You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2006/11/15 21:40:37 UTC

svn commit: r475409 [1/2] - in /spamassassin/branches/jm_re2c_hacks: ./ build/ build/buildbot/ build/mkupdates/ debian/ lib/Mail/ lib/Mail/SpamAssassin/ lib/Mail/SpamAssassin/Conf/ lib/Mail/SpamAssassin/Locker/ lib/Mail/SpamAssassin/Message/ lib/Mail/S...

Author: jm
Date: Wed Nov 15 12:40:35 2006
New Revision: 475409

URL: http://svn.apache.org/viewvc?view=rev&rev=475409
Log:
merged up to 475396 using 'svn merge -r467693:475396 https://svn.apache.org/repos/asf/spamassassin/trunk'

Added:
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Check.pm
      - copied, changed from r475396, spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Check.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/MemoryDump.pm
      - copied unchanged from r475396, spamassassin/trunk/lib/Mail/SpamAssassin/Util/MemoryDump.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/TieOneStringHash.pm
      - copied unchanged from r475396, spamassassin/trunk/lib/Mail/SpamAssassin/Util/TieOneStringHash.pm
    spamassassin/branches/jm_re2c_hacks/t/spamd_unix_and_tcp.t
      - copied unchanged from r475396, spamassassin/trunk/t/spamd_unix_and_tcp.t
Modified:
    spamassassin/branches/jm_re2c_hacks/INSTALL
    spamassassin/branches/jm_re2c_hacks/MANIFEST
    spamassassin/branches/jm_re2c_hacks/Makefile.PL
    spamassassin/branches/jm_re2c_hacks/build/README
    spamassassin/branches/jm_re2c_hacks/build/buildbot/master.cfg
    spamassassin/branches/jm_re2c_hacks/build/mkrules
    spamassassin/branches/jm_re2c_hacks/build/mkupdates/listpromotable
    spamassassin/branches/jm_re2c_hacks/build/mkupdates/run_part2
    spamassassin/branches/jm_re2c_hacks/debian/control
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Bayes.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf/Parser.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/HTML.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Locker/UnixNFSSafe.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message/Node.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/SpamdForkScaling.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util.pm
    spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Util/DependencyInfo.pm
    spamassassin/branches/jm_re2c_hacks/masses/hit-frequencies
    spamassassin/branches/jm_re2c_hacks/masses/mass-check
    spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/gen_info_xml
    spamassassin/branches/jm_re2c_hacks/masses/rule-qa/automc/ruleqa.cgi
    spamassassin/branches/jm_re2c_hacks/rules/20_dnsbl_tests.cf
    spamassassin/branches/jm_re2c_hacks/rules/20_head_tests.cf
    spamassassin/branches/jm_re2c_hacks/rules/30_text_de.cf
    spamassassin/branches/jm_re2c_hacks/rules/50_scores.cf
    spamassassin/branches/jm_re2c_hacks/rules/active.list
    spamassassin/branches/jm_re2c_hacks/rules/v320.pre
    spamassassin/branches/jm_re2c_hacks/sa-update.raw
    spamassassin/branches/jm_re2c_hacks/spamassassin.spec
    spamassassin/branches/jm_re2c_hacks/spamd/spamd.raw
    spamassassin/branches/jm_re2c_hacks/t/SATest.pm
    spamassassin/branches/jm_re2c_hacks/t/get_headers.t
    spamassassin/branches/jm_re2c_hacks/t/lang_pl_tests.t
    spamassassin/branches/jm_re2c_hacks/t/mkrules.t

Modified: spamassassin/branches/jm_re2c_hacks/INSTALL
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/INSTALL?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/INSTALL (original)
+++ spamassassin/branches/jm_re2c_hacks/INSTALL Wed Nov 15 12:40:35 2006
@@ -207,6 +207,17 @@
     Debian: apt-get install libhtml-parser-perl
     Gentoo: emerge dev-perl/HTML-Parser
 
+  - Net::DNS (from CPAN)
+
+    Used for all DNS-based tests (SBL, XBL, SpamCop, DSBL, etc.),
+    perform MX checks, used when manually reporting spam to SpamCop,
+    and used by sa-update to gather version information.
+
+    You need to make sure the Net::DNS version is sufficiently up-to-date:
+
+      - version 0.34 or higher on Unix systems
+      - version 0.46 or higher on Windows systems
+
 
 Optional Modules
 ----------------
@@ -235,20 +246,6 @@
     There seems to be a bug in libdb 4.1.25, which is
     distributed by default on some versions of Linux.  See
     http://wiki.apache.org/spamassassin/DbFileSleepBug for details.
-
-
-  - Net::DNS (from CPAN)
-
-    Used for all DNS-based tests (SBL, XBL, SpamCop, DSBL, etc.),
-    perform MX checks, used when manually reporting spam to SpamCop,
-    and used by sa-update to gather version information.  Recommended.
-
-    If this is installed and you are using network tests of any variety
-    (which is the default), then you need to make sure the Net::DNS
-    version is sufficiently up-to-date:
-
-      - version 0.34 or higher on Unix systems
-      - version 0.46 or higher on Windows systems
 
 
   - Net::SMTP (from CPAN)

Modified: spamassassin/branches/jm_re2c_hacks/MANIFEST
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/MANIFEST?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/MANIFEST (original)
+++ spamassassin/branches/jm_re2c_hacks/MANIFEST Wed Nov 15 12:40:35 2006
@@ -74,6 +74,7 @@
 lib/Mail/SpamAssassin/Plugin/AutoLearnThreshold.pm
 lib/Mail/SpamAssassin/Plugin/Bayes.pm
 lib/Mail/SpamAssassin/Plugin/BodyEval.pm
+lib/Mail/SpamAssassin/Plugin/Check.pm
 lib/Mail/SpamAssassin/Plugin/DCC.pm
 lib/Mail/SpamAssassin/Plugin/DKIM.pm
 lib/Mail/SpamAssassin/Plugin/DNSEval.pm
@@ -109,6 +110,7 @@
 lib/Mail/SpamAssassin/Util/DependencyInfo.pm
 lib/Mail/SpamAssassin/Util/Progress.pm
 lib/Mail/SpamAssassin/Util/RegistrarBoundaries.pm
+lib/Mail/SpamAssassin/Util/TieOneStringHash.pm
 lib/spamassassin-run.pod
 masses/CORPUS_POLICY
 masses/CORPUS_SUBMIT
@@ -544,3 +546,4 @@
 t/spamd_kill_restart.t
 t/spamd_kill_restart_rr.t
 t/re_base_extraction.t
+t/spamd_unix_and_tcp.t

Modified: spamassassin/branches/jm_re2c_hacks/Makefile.PL
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/Makefile.PL?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/Makefile.PL (original)
+++ spamassassin/branches/jm_re2c_hacks/Makefile.PL Wed Nov 15 12:40:35 2006
@@ -210,6 +210,7 @@
         'Pod::Usage'    => 1.10,          # all versions prior to this do seem to be buggy
         'HTML::Parser'  => 3.43,          # the HTML code is based on this parser, older versions have utf-8 bugs
         'Text::Wrap'    => 98.112902,     # this version is shipped with 5.005_03, the oldest version known to work
+        'Net::DNS'      => (RUNNING_ON_WINDOWS ? 0.46 : 0.34), # bugs in older revs
         'Sys::Hostname' => 0,
         'Time::Local'   => 0,
         'Errno'         => 0,
@@ -274,6 +275,12 @@
     'NO_META' => 1,
 );
 
+# rules/72_active.cf is built from "rulesrc", but *must* exist before
+# WriteMakefile() is called due to shortcomings in MakeMaker.
+my @FILES_THAT_MUST_EXIST = qw(
+        rules/72_active.cf
+    );
+
 # That META.yml stuff was introduced with Perl 6.06_03, see
 # <http://archive.develooper.com/makemaker@perl.org/msg00922.html>
 # <http://archive.develooper.com/makemaker@perl.org/msg00984.html>
@@ -379,6 +386,10 @@
   exit 1;
 }
 
+foreach my $file (@FILES_THAT_MUST_EXIST) {
+  open (TOUCH, ">>$file") or die "cannot touch '$file'";
+  close TOUCH;
+}
 
 #######################################################################
 
@@ -1126,7 +1137,6 @@
 	$(PREPROCESS) $(FIXBYTES) $(FIXVARS) $(FIXBANG) -m$(PERM_RWX) -i$? -o$@
 
 build_rules: 
-	-rm rules/70_inactive.cf
 	[ ! -d rulesrc ] || $(PERL) build/mkrules --src rulesrc --out rules --manifest MANIFEST --manifestskip MANIFEST.SKIP
 
 SPAMC_MAKEFILE  = spamc/Makefile

Modified: spamassassin/branches/jm_re2c_hacks/build/README
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/build/README?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/build/README (original)
+++ spamassassin/branches/jm_re2c_hacks/build/README Wed Nov 15 12:40:35 2006
@@ -281,6 +281,14 @@
         svn up
         svn commit -m "added new release to website"
 
+- Release a new rules update matching the released code:
+
+    ssh spamassassin.zones.apache.org
+    sudo -u updatesd \
+        /home/updatesd/svn/spamassassin/build/mkupdates/run_nightly
+    sudo -u updatesd \
+        /home/updatesd/svn/spamassassin/build/mkupdates/run_part2
+
 - update the tag used to point to "current release":
 
     repo=https://svn.apache.org/repos/asf/spamassassin

Modified: spamassassin/branches/jm_re2c_hacks/build/buildbot/master.cfg
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/build/buildbot/master.cfg?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/build/buildbot/master.cfg (original)
+++ spamassassin/branches/jm_re2c_hacks/build/buildbot/master.cfg Wed Nov 15 12:40:35 2006
@@ -74,12 +74,12 @@
         ("sol10-perl561", read_pwd("zone-sol10")),
 
 #generally never up these days
-        ("quinlan-freebsd-perl585", read_pwd("quinlan-freebsd-perl585")),
-        ("parker-suse-9.2", read_pwd("parker-suse-9.2")),
-        ("parker-openbsd-3.7", read_pwd("parker-openbsd-3.7")),
-        ("sidney-fedora3", read_pwd("sidney-fedora3")),
-        ("sidney-cygwin", read_pwd("sidney-cygwin")),
-        ("sidney-win32", read_pwd("sidney-win32")),
+        # ("quinlan-freebsd-perl585", read_pwd("quinlan-freebsd-perl585")),
+        # ("parker-suse-9.2", read_pwd("parker-suse-9.2")),
+        # ("parker-openbsd-3.7", read_pwd("parker-openbsd-3.7")),
+        # ("sidney-fedora3", read_pwd("sidney-fedora3")),
+        # ("sidney-cygwin", read_pwd("sidney-cygwin")),
+        # ("sidney-win32", read_pwd("sidney-win32")),
         ]
 
 # this is the standard set of build steps, with a "make distcheck" and a
@@ -183,20 +183,20 @@
 
 # now the buildbots that aren't always up...
 
-b1 = { "name": "t-parker-suse-9.2", "slavename": "parker-suse-9.2", "builddir": "t-parker-suse-9.2", "factory": bf_generic, }
-c['builders'].append(b1)
-
-b1 = { "name": "t-parker-openbsd-3.7", "slavename": "parker-openbsd-3.7", "builddir": "t-parker-openbsd-3.7", "factory": bf_generic, }
-c['builders'].append(b1)
-
-b1 = { "name": "t-quinlan-fbsd", "slavename": "quinlan-freebsd-perl585", "builddir": "t-quinlan-freebsd-perl585", "factory": bf_generic, }
-c['builders'].append(b1)
-
-b1 = { "name": "t-sidney-fedora3", "slavename": "sidney-fedora3", "builddir": "t-sidney-fedora3", "factory": bf_generic, }
-c['builders'].append(b1)
+# b1 = { "name": "t-parker-suse-9.2", "slavename": "parker-suse-9.2", "builddir": "t-parker-suse-9.2", "factory": bf_generic, }
+# c['builders'].append(b1)
+# 
+# b1 = { "name": "t-parker-openbsd-3.7", "slavename": "parker-openbsd-3.7", "builddir": "t-parker-openbsd-3.7", "factory": bf_generic, }
+# c['builders'].append(b1)
 
-b1 = { "name": "t-sidney-cygwin", "slavename": "sidney-cygwin", "builddir": "t-sidney-cygwin", "factory": bf_generic, }
-c['builders'].append(b1)
+# b1 = { "name": "t-quinlan-fbsd", "slavename": "quinlan-freebsd-perl585", "builddir": "t-quinlan-freebsd-perl585", "factory": bf_generic, }
+# c['builders'].append(b1)
+# 
+# b1 = { "name": "t-sidney-fedora3", "slavename": "sidney-fedora3", "builddir": "t-sidney-fedora3", "factory": bf_generic, }
+# c['builders'].append(b1)
+# 
+# b1 = { "name": "t-sidney-cygwin", "slavename": "sidney-cygwin", "builddir": "t-sidney-cygwin", "factory": bf_generic, }
+# c['builders'].append(b1)
 
 # 3.0 branch
 steps = [
@@ -210,10 +210,10 @@
         ];
 bf_30branch = factory.BuildFactory(steps)
 
-b1 = { "name": "b3.0-parker-suse-9.2", "slavename": "parker-suse-9.2", "builddir": "b3.0-parker-suse-9.2", "factory": bf_30branch, }
-c['builders'].append(b1)
+# b1 = { "name": "b3.0-parker-suse-9.2", "slavename": "parker-suse-9.2", "builddir": "b3.0-parker-suse-9.2", "factory": bf_30branch, }
+# c['builders'].append(b1)
 
-b1 = { "name": "b3.0-parker-freebsd-5.3", "slavename": "parker-freebsd-5.3", "builddir": "b3.0-parker-freebsd-5.3", "factory": bf_30branch, }
+# b1 = { "name": "b3.0-parker-freebsd-5.3", "slavename": "parker-freebsd-5.3", "builddir": "b3.0-parker-freebsd-5.3", "factory": bf_30branch, }
 ### c['builders'].append(b1)
 
 # These are the steps, from Sidney, for building under win32
@@ -253,9 +253,9 @@
         s(step.Test, command=["nmake", "distcheck"]),
         s(step.Test, command="nmake disttest < nul:"),
         ];
-bf_win32 = factory.BuildFactory(steps)
-b1 = { "name": "t-sidney-win32", "slavename": "sidney-win32", "builddir": "t-sidney-win32", "factory": bf_win32, }
-c['builders'].append(b1)
+# bf_win32 = factory.BuildFactory(steps)
+# b1 = { "name": "t-sidney-win32", "slavename": "sidney-win32", "builddir": "t-sidney-win32", "factory": bf_win32, }
+# c['builders'].append(b1)
 
 ###########################################################################
 

Modified: spamassassin/branches/jm_re2c_hacks/build/mkrules
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/build/mkrules?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/build/mkrules (original)
+++ spamassassin/branches/jm_re2c_hacks/build/mkrules Wed Nov 15 12:40:35 2006
@@ -46,14 +46,13 @@
 use vars qw(
     @opt_srcs $opt_out $opt_sandboxout $opt_manifest
     $opt_manifestskip $opt_listpromotable $opt_active
-    $opt_activeout $opt_inactiveout $default_file_header
+    $opt_activeout $default_file_header
     $opt_rulemetadata
 );
 GetOptions("src=s" => \@opt_srcs,
     "out=s",
     "sandboxout=s",
     "activeout=s",
-    "inactiveout=s",
     "active=s",
     "manifest=s",
     "manifestskip=s",
@@ -91,10 +90,10 @@
 
 $opt_sandboxout  ||= "70_sandbox.cf";
 $opt_activeout   ||= "72_active.cf";
-$opt_inactiveout ||= "70_inactive.cf";
 
 # source files that need compilation, and their targets
 my $needs_compile = { };
+my $found_output = { };
 my $current_src;
 my $newest_src_mtime = 0;
 my $newest_out_mtime = 0;
@@ -108,24 +107,38 @@
   }
   $current_src = $src;
   File::Find::find ({
-          wanted => \&wanted,
+          wanted => \&src_wanted,
           no_chdir => 1
         }, $src);
 }
 
 # get mtimes of output files; we can be sure that all
 # output is under the "opt_out" dir, so recurse there
-#File::Find::find ({
-#        wanted => \&out_wanted,
-#        no_chdir => 1
-#      }, $opt_out);
-
-#if ($newest_src_mtime && $newest_out_mtime
-#    && $newest_src_mtime < $newest_out_mtime)
-#{
-#  print "mkrules: no rules updated\n";
-#  exit 0;
-#}
+File::Find::find ({
+        wanted => \&out_wanted,
+        no_chdir => 1
+      }, $opt_out);
+
+# we must rebuild if a compiled .pm is missing, too
+my $found_all_pm_files = 1;
+foreach my $f (keys %{$needs_compile}) {
+  next unless ($f =~ /\.pm$/i);
+  if (!exists $found_output->{basename $f}) {
+    $found_all_pm_files = 0;
+  }
+}
+
+# check mtimes, and also require that the two required output files
+# really do exist
+if ($newest_src_mtime && $newest_out_mtime
+    && $newest_src_mtime < $newest_out_mtime
+    && -f $opt_out.'/'.$opt_sandboxout
+    && -f $opt_out.'/'.$opt_activeout
+    && $found_all_pm_files)
+{
+  print "mkrules: no rules updated\n";
+  exit 0;
+}
 
 my $rules = { };
 
@@ -216,9 +229,17 @@
   return $errors;       # 0 means good
 }
 
-sub wanted {
+sub src_wanted {
   my $path = $File::Find::name;
-  # only files
+
+  # record stat times of directories, too, to catch file additions/removals
+  # in the source tree
+  my @st = stat $path;
+  if ($st[9] && $st[9] > $newest_src_mtime) {
+    $newest_src_mtime = $st[9];
+  }
+
+  # only files from now on, though
   return if (!-f $path);
   
   # limit what will be copied from sandboxes
@@ -237,11 +258,6 @@
   my $t;
   $t = "$opt_out/$filename";
 
-  my @st = stat $path;
-  if ($st[9] && $st[9] > $newest_src_mtime) {
-    $newest_src_mtime = $st[9];
-  }
-
   $needs_compile->{$f} = {
           f => $f,
           t => $t,
@@ -253,15 +269,25 @@
 sub out_wanted {
   my $path = $File::Find::name;
   return unless (-f $path);
-  return unless ($path =~ /\.cf$/i);
+  return if ($path =~ /\.svn/);
+  return unless ($path =~ /\.(?:cf|pm)$/i);
 
   my @st = stat $path;
   if ($st[9] && $st[9] > $newest_out_mtime) {
     $newest_out_mtime = $st[9];
   }
+
+  my $dir = $path;
+  $dir =~ s/^${current_src}[\/\\\:]//s;
+  $dir =~ s/([^\/\\\:]+)$//;
+  my $filename = $1;
+
+  if ($path =~ /\.pm$/i) {
+    $found_output->{$filename} = 1;
+  }
 }
 
-# compile all the source files found by the wanted() sub, in sorted
+# compile all the source files found by the src_wanted() sub, in sorted
 # order so that the order of precedence makes sense.
 sub read_all_rules {
   my ($sources) = @_;
@@ -269,11 +295,11 @@
   # deal with the perl modules first, so that later linting w/ loadplugin will
   # work appropriately.
   foreach my $f (sort {
-    my ($ae) = $a =~ /\.(cf|pm)$/;
-    my ($be) = $b =~ /\.(cf|pm)$/;
-    return $be cmp $ae || $a cmp $b;
-    } keys %$sources) {
-
+                  my ($ae) = $a =~ /\.(cf|pm)$/;
+                  my ($be) = $b =~ /\.(cf|pm)$/;
+                  return $be cmp $ae || $a cmp $b;
+                } keys %$sources)
+  {
     my $entry = $needs_compile->{$f};
     my $t = $entry->{t};
 
@@ -526,7 +552,7 @@
 
       my $forceactive = 1;
       
-      # always send 'test' lines to the sandbox or inactive files
+      # always send 'test' lines to the sandbox files
       if (/^test\s*/) {
         $forceactive = 0;
 
@@ -581,9 +607,8 @@
 
   foreach my $file (<$opt_out/*.cf>) {
     next unless ($file =~ /\d\d_\S+\.cf$/);
-    next if ($file =~ /\/\Q$opt_activeout\E/);
-    next if ($file =~ /\/\Q$opt_sandboxout\E/);
-    next if ($file =~ /\/\Q$opt_inactiveout\E/);
+    next if (pubfile_is_activeout($file));
+    next if (pubfile_is_sandboxout($file));
     read_output_file($file);
   }
 }
@@ -652,7 +677,7 @@
     my $srcfile = $rules->{$name}->{srcfile};
     my $pubfile = pubfile_for_rule($rules, $name);
     my $is_active = 0;
-    if ($pubfile =~ /${opt_activeout}$/) {
+    if (pubfile_is_activeout($pubfile)) {
       $is_active++;
     }
 
@@ -705,13 +730,8 @@
 
   my $pubfile;
   if ($rules->{$name}->{publish}) {
-    $pubfile = $rules->{$name}->{pubfile};
-    if ($pubfile) {
-      $pubfile = $opt_out.'/'.$pubfile;
-    } else {
-      # "publish NAMEOFRULE" => send it to active
-      $pubfile = $opt_out.'/'.$opt_activeout;
-    }
+    # "publish NAMEOFRULE" => send it to active
+    $pubfile = $opt_out.'/'.$opt_activeout;
   }
 
   # default: "70_sandbox.cf" or "72_active.cf"
@@ -727,7 +747,8 @@
       $pubfile = $opt_out.'/'.$opt_sandboxout;
     }
     else {
-      $pubfile = $opt_out.'/'.$opt_inactiveout;
+      warn "oops? inactive rule, non-sandbox, shouldn't be possible anymore";
+      $pubfile = $opt_out.'/'.$opt_sandboxout;
     }
   }
   return $pubfile;
@@ -759,7 +780,7 @@
   foreach my $file (keys %$output_files) {
     $output_file_text->{$file} = $output_files->{$file}->{header};
 
-    if ($always && $file =~ /\Q$opt_activeout\E$/) {
+    if ($always && pubfile_is_activeout($file)) {
       $output_file_text->{$file} .= $always;
     }
   }
@@ -793,7 +814,7 @@
   # always be likewise promoted into the active set, overriding the prev step.
   foreach my $rule (@rulenames) {
     my $pubfile = $rules->{$rule}->{output_file};
-    next unless ($pubfile && $pubfile =~ /\Q$opt_activeout\E/);
+    next unless ($pubfile && pubfile_is_activeout($pubfile));
     fix_up_rule_dependencies($rule);
   }
 
@@ -825,13 +846,6 @@
 
   # finally, finish off all output files
   foreach my $file (keys %$output_files) {
-    # do we have any end-of-file comments?  if so, add it
-    # off: results in comments being duplicated many times
-    # my $cmts = $rules->{$COMMENTS}->{text};
-    # if ($cmts) {
-      # $output_file_text->{$pubfile} .= $cmts;
-    # }
-
     # and get them lint-checked!
     $files_to_lint->{$file} = 1;
   }
@@ -875,7 +889,6 @@
 sub fix_up_rule_dependencies {
   my $rule = shift;
 
-  # next if ($rule =~ /^__/);
   my $pubfile = $rules->{$rule}->{output_file};
   my $text    = $rules->{$rule}->{output_text};
   return unless $text;
@@ -895,11 +908,21 @@
       # don't do this if the subrule would be moved *out* of the
       # active file!
       my $pubfile2 = $rules->{$rule2}->{output_file};
-      next if ($pubfile2 && $pubfile2 =~ /\Q$opt_activeout\E/);
+      next if (pubfile_is_activeout($pubfile2));
 
       $rules->{$rule2}->{output_file} = $pubfile;
     }
   }
+}
+
+sub pubfile_is_activeout {
+  return 1 if ($_[0] && $_[0] =~ /\b\Q$opt_activeout\E$/);
+  return 0;
+}
+
+sub pubfile_is_sandboxout {
+  return 1 if ($_[0] && $_[0] =~ /\b\Q$opt_sandboxout\E$/);
+  return 0;
 }
 
 sub write_output_files {

Modified: spamassassin/branches/jm_re2c_hacks/build/mkupdates/listpromotable
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/build/mkupdates/listpromotable?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/build/mkupdates/listpromotable (original)
+++ spamassassin/branches/jm_re2c_hacks/build/mkupdates/listpromotable Wed Nov 15 12:40:35 2006
@@ -109,6 +109,7 @@
     local_tests_only => 1,
     dont_copy_prefs => 1,
     config_tree_recurse => 1,
+    keep_config_parsing_metadata => 1,
     # debug => 1,
 });
 

Modified: spamassassin/branches/jm_re2c_hacks/build/mkupdates/run_part2
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/build/mkupdates/run_part2?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/build/mkupdates/run_part2 (original)
+++ spamassassin/branches/jm_re2c_hacks/build/mkupdates/run_part2 Wed Nov 15 12:40:35 2006
@@ -81,16 +81,22 @@
 
 make install                             || exit $?
 
+presdir=$tmpdir/etc/mail/spamassassin
 rulesdir=$tmpdir/share/spamassassin
 
 (
   cd $rulesdir 
 
+  # include ".pre" files for the default distro plugins, like
+  # Mail::SpamAssassin::Plugin::BodyEval, Mail::SpamAssassin::Plugin::Bayes
+  # etc. (bug 5171)
+  cp -p $presdir/*.pre .
+
   # Use this to include plugin .pm files:
-  # tar cvf - *.cf *.pm                    || exit $?
+  # tar cvf - *.cf *.pm *.pre            || exit $?
 
   # or this, to ban code from the updates:
-  tar cvf - *.cf                         || exit $?
+  tar cvf - *.cf *.pre                   || exit $?
 
 ) | gzip -9 > $tmpdir/update.tgz         || exit $?
 

Modified: spamassassin/branches/jm_re2c_hacks/debian/control
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/debian/control?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/debian/control (original)
+++ spamassassin/branches/jm_re2c_hacks/debian/control Wed Nov 15 12:40:35 2006
@@ -7,8 +7,8 @@
 
 Package: spamassassin
 Architecture: any
-Depends: ${perl:Depends}, ${shlibs:Depends}, libdigest-sha1-perl, libhtml-parser-perl (>= 3.24), libstorable-perl | perl (>= 5.8.0)
-Recommends: libnet-dns-perl, libmail-spf-query-perl
+Depends: ${perl:Depends}, ${shlibs:Depends}, libdigest-sha1-perl, libhtml-parser-perl (>= 3.24), libnet-dns-perl | perl (>= 5.8.0)
+Recommends: libmail-spf-query-perl
 Suggests: razor (>= 2.40), pyzor, libtime-hires-perl
 Provides: spamassassin, spamc
 Description:  Spam detector and markup engine

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin.pm Wed Nov 15 12:40:35 2006
@@ -297,6 +297,10 @@
 
 =cut
 
+# undocumented ctor settings: 
+#
+# - keep_config_parsing_metadata: used by build/listpromotable, default 0
+
 sub new {
   my $class = shift;
   $class = ref($class) || $class;
@@ -431,7 +435,6 @@
 
 sub check {
   my ($self, $mail_obj) = @_;
-  local ($_);
 
   $self->init(1);
   my $msg = Mail::SpamAssassin::PerMsgStatus->new($self, $mail_obj);
@@ -1228,6 +1231,8 @@
   $mail->finish();
   $self->finish_learner();
 
+  $self->{conf}->free_uncompiled_rule_source();
+
   # load SQL modules now as well
   my $dsn = $self->{conf}->{user_scores_dsn};
   if ($dsn ne '') {
@@ -1333,7 +1338,9 @@
 sub finish {
   my ($self) = @_;
 
-  Mail::SpamAssassin::PerMsgStatus::finish_tests($self->{conf});
+  $self->call_plugins("finish_tests", { conf => $self->{conf},
+                                        main => $self });
+
   $self->{conf}->finish(); delete $self->{conf};
   $self->{plugins}->finish(); delete $self->{plugins};
 
@@ -1398,7 +1405,7 @@
     }
 
     if ($sysrules) {
-      $self->{config_text} .= $self->read_cf ($sysrules, 'default rules dir');
+      $self->{config_text} .= $self->read_cf($sysrules, 'default rules dir');
     }
 
     if (!$self->{languages_filename}) {
@@ -1406,7 +1413,7 @@
     }
 
     if ($siterules) {
-      $self->{config_text} .= $self->read_cf ($siterules, 'site rules dir');
+      $self->{config_text} .= $self->read_cf($siterules, 'site rules dir');
     }
 
     if ( $use_user_pref != 0 ) {
@@ -1426,7 +1433,7 @@
         }
       }
 
-      $self->{config_text} .= $self->read_cf ($fname, 'user prefs file');
+      $self->{config_text} .= $self->read_cf($fname, 'user prefs file');
     }
   }
 

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Bayes.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Bayes.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Bayes.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Bayes.pm Wed Nov 15 12:40:35 2006
@@ -232,7 +232,6 @@
     'conf'		=> $main->{conf},
     ## 'log_raw_counts'	=> 0, # see compute_prob_for_token()
     'use_ignores'       => 1,
-    'tz'		=> Mail::SpamAssassin::Util::local_tz(),
   };
   bless ($self, $class);
 

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf.pm Wed Nov 15 12:40:35 2006
@@ -74,6 +74,7 @@
 use Mail::SpamAssassin::Constants qw(:sa);
 use Mail::SpamAssassin::Conf::Parser;
 use Mail::SpamAssassin::Logger;
+use Mail::SpamAssassin::Util::TieOneStringHash;
 use File::Spec;
 
 use strict;
@@ -1511,6 +1512,13 @@
 or 'X-Message-Id', then uses its own one in the 'Message-Id' header.  The value
 returned for this symbol is the text from all 3 headers, separated by newlines.
 
+=item C<X-Spam-Relays-Untrusted>, C<X-Spam-Relays-Trusted>,
+C<X-Spam-Relays-Internal> and C<X-Spam-Relays-External> represent a portable,
+pre-parsed representation of the message's network path, as recorded in the
+Received headers, divided into 'trusted' vs 'untrusted' and 'internal' vs
+'external' sets.  See C<http://wiki.apache.org/spamassassin/TrustedRelays> for
+more details.
+
 =back
 
 C<op> is either C<=~> (contains regular expression) or C<!~> (does not contain
@@ -2457,10 +2465,14 @@
  _DATE_            rfc-2822 date of scan
  _STARS(*)_        one "*" (use any character) for each full score point
                    (note: limited to 50 'stars')
- _RELAYSTRUSTED_   relays used and deemed to be trusted
- _RELAYSUNTRUSTED_ relays used that can not be trusted
- _RELAYSINTERNAL_  relays used and deemed to be internal
- _RELAYSEXTERNAL_  relays used and deemed to be external
+ _RELAYSTRUSTED_   relays used and deemed to be trusted (see the 
+                   'X-Spam-Relays-Trusted' pseudo-header)
+ _RELAYSUNTRUSTED_ relays used that can not be trusted (see the 
+                   'X-Spam-Relays-Untrusted' pseudo-header)
+ _RELAYSINTERNAL_  relays used and deemed to be internal (see the 
+                   'X-Spam-Relays-Internal' pseudo-header)
+ _RELAYSEXTERNAL_  relays used and deemed to be external (see the 
+                   'X-Spam-Relays-External' pseudo-header)
  _AUTOLEARN_       autolearn status ("ham", "no", "spam", "disabled",
                    "failed", "unavailable")
  _TESTS(,)_        tests hit separated by "," (or other separator)
@@ -2583,7 +2595,6 @@
   $self->{plugins_loaded} = { };
 
   $self->{tests} = { };
-  $self->{descriptions} = { };
   $self->{test_types} = { };
   $self->{scoreset} = [ {}, {}, {}, {} ];
   $self->{scoreset_current} = 0;
@@ -2591,6 +2602,11 @@
   $self->{tflags} = { };
   $self->{source_file} = { };
 
+  # keep descriptions in a slow but space-efficient single-string
+  # data structure
+  tie %{$self->{descriptions}}, 'Mail::SpamAssassin::Util::TieOneStringHash'
+    or warn "tie failed";
+
   # after parsing, tests are refiled into these hashes for each test type.
   # this allows e.g. a full-text test to be rewritten as a body test in
   # the user's user_prefs file.
@@ -2882,6 +2898,13 @@
 
 ###########################################################################
 
+sub get_description_for_rule {
+  my ($self, $rule) = @_;
+  return $self->{descriptions}->{$rule};
+}
+
+###########################################################################
+
 sub maybe_header_only {
   my($self,$rulename) = @_;
   my $type = $self->{test_types}->{$rulename};
@@ -3024,8 +3047,23 @@
 
 ###########################################################################
 
+sub free_uncompiled_rule_source {
+  my ($self) = @_;
+
+  if (!$self->{main}->{keep_config_parsing_metadata} &&
+        !$self->{allow_user_rules})
+  {
+    delete $self->{if_stack};
+    delete $self->{source_file};
+    delete $self->{meta_dependencies};
+  }
+}
+
+###########################################################################
+
 sub finish {
   my ($self) = @_;
+  untie %{$self->{descriptions}};
   %{$self} = ();
 }
 

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf/Parser.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf/Parser.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf/Parser.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Conf/Parser.pm Wed Nov 15 12:40:35 2006
@@ -191,8 +191,12 @@
     # next, its priority (used to ensure frequently-used params
     # are parsed first)
     my $cmdname = $cmd->{command} || $cmd->{setting};
-    foreach my $name ($cmdname, @{$cmd->{aliases}}) {
-      $self->{command_luts}->{$set}->{$name} = $cmd;
+    $self->{command_luts}->{$set}->{$cmdname} = $cmd;
+
+    if ($cmd->{aliases} && scalar @{$cmd->{aliases}} > 0) {
+      foreach my $name (@{$cmd->{aliases}}) {
+        $self->{command_luts}->{$set}->{$name} = $cmd;
+      }
     }
   }
 }
@@ -433,6 +437,8 @@
     $self->lint_warn($msg, undef, $is_error);
   }
 
+  delete $self->{if_stack};
+
   $self->lint_check();
   $self->set_default_scores();
 
@@ -530,7 +536,7 @@
       # T_ rules (in a testing probationary period) get low, low scores
       my $set_score = ($k =~/^T_/) ? 0.01 : 1.0;
 
-      $set_score = -$set_score if ( $conf->{tflags}->{$k} =~ /\bnice\b/ );
+      $set_score = -$set_score if ( ($conf->{tflags}->{$k}||'') =~ /\bnice\b/ );
       for my $index (0..3) {
         $conf->{scoreset}->[$index]->{$k} = $set_score;
       }
@@ -750,8 +756,10 @@
   # named this way just in case we ever want a "finish_parsing_start"
   $conf->{main}->call_plugins("finish_parsing_end", { conf => $conf });
 
-  delete $conf->{tests};                # free it up
-  delete $conf->{priority};             # free it up
+  # free up stuff we no longer need
+  delete $conf->{tests};
+  delete $conf->{priority};
+  delete $conf->{test_types};
 }
 
 sub trace_meta_dependencies {
@@ -766,12 +774,7 @@
     my $deps = [ ];
     my $alreadydone = { };
     $self->_meta_deps_recurse($conf, $name, $name, $deps, $alreadydone);
-    $conf->{meta_dependencies}->{$name} = $deps;
-
-    # this is too noisy
-    # if (scalar @$deps > 0) {
-    # dbg("rules: meta dependencies: $name => ".join(' ', @$deps));
-    # }
+    $conf->{meta_dependencies}->{$name} = join (' ', @{$deps});
   }
 }
 
@@ -823,7 +826,7 @@
     next unless (defined $deps);
 
     my $basepri = $pri->{$rule};
-    foreach my $dep (@$deps) {
+    foreach my $dep (split ' ', $deps) {
       my $deppri = $pri->{$dep};
       if ($deppri > $basepri) {
         dbg("rules: $rule (pri $basepri) requires $dep (pri $deppri): fixed");
@@ -923,7 +926,6 @@
 
   $conf->{tests}->{$name} = $text;
   $conf->{test_types}->{$name} = $type;
-  $conf->{tflags}->{$name} ||= '';
   if ($type == $Mail::SpamAssassin::Conf::TYPE_META_TESTS) {
     $conf->{priority}->{$name} ||= 500;
   }
@@ -933,8 +935,9 @@
   $conf->{priority}->{$name} ||= 0;
   $conf->{source_file}->{$name} = $self->{currentfile};
 
-  # this no longer seems to be needed!
-  # $conf->{if_stack}->{$name} = $self->get_if_stack_as_string();
+  if ($self->{main}->{keep_config_parsing_metadata}) {
+    $conf->{if_stack}->{$name} = $self->get_if_stack_as_string();
+  }
 
   if ($self->{scoresonly}) {
     $conf->{user_rules_to_compile}->{$type} = 1;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/HTML.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/HTML.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/HTML.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/HTML.pm Wed Nov 15 12:40:35 2006
@@ -52,14 +52,6 @@
   #   blink ilayer multicol noembed nolayer spacer wbr
 ;
 
-# attributes
-my %attributes = map {; $_ => 1 }
-  # HTML 4.01 deprecated, loose DTD, frameset DTD
-  qw( abbr accept-charset accept accesskey action align alink alt archive axis background bgcolor border cellpadding cellspacing char charoff charset checked cite class classid clear code codebase codetype color cols colspan compact content coords data datetime declare defer dir disabled enctype face for frame frameborder headers height href hreflang hspace http-equiv id ismap label lang language link longdesc marginheight marginwidth maxlength media method multiple name nohref noresize noshade nowrap object onblur onchange onclick ondblclick onfocus onkeydown onkeypress onkeyup onload onmousedown onmousemove onmouseout onmouseover onmouseup onreset onselect onsubmit onunload profile prompt readonly rel rev rows rowspan rules scheme scope scrolling selected shape size span src standby start style summary tabindex target text title type usemap valign value valuetype version vlink vspace width ),
-  # attributes: additional attributes we accept
-  qw( family wrap / ),
-;
-
 # elements that change text style
 my %elements_text_style = map {; $_ => 1 }
   qw( body font table tr th td big small basefont marquee span ),
@@ -145,7 +137,6 @@
 
   # final results scalars
   $self->put_results(image_area => $self->{image_area});
-  $self->put_results(max_shouting => $self->{max_shouting});
   $self->put_results(length => $self->{length});
   $self->put_results(min_size => $self->{min_size});
   $self->put_results(max_size => $self->{max_size});
@@ -179,13 +170,6 @@
     $self->put_results(obfuscation_ratio =>
 		       $self->{obfuscation} / $self->{tags});
   }
-  if (exists $self->{attr_bad} && exists $self->{attr_all}) {
-    $self->put_results(attr_bad => $self->{attr_bad} / $self->{attr_all});
-  }
-  if (exists $self->{attr_unique_bad} && exists $self->{attr_unique_all}) {
-    $self->put_results(attr_unique_bad =>
-		       $self->{attr_unique_bad} / $self->{attr_unique_all});
-  }
 }
 
 sub put_results {
@@ -230,7 +214,6 @@
   my ($self, $text) = @_;
 
   $self->{image_area} = 0;
-  $self->{max_shouting} = 0;
   $self->{title_index} = -1;
   $self->{max_size} = 3;	# start at default size
   $self->{min_size} = 3;	# start at default size
@@ -290,17 +273,6 @@
 
   return if $maybe_namespace;
 
-  # check attributes
-  for my $name (keys %$attr) {
-    if (!exists $attributes{$name}) {
-      $self->{attr_bad}++;
-      $self->{attr_unique_bad}++ if !exists $self->{"attr_seen_$name"};
-    }
-    $self->{attr_all}++;
-    $self->{attr_unique_all}++ if !exists $self->{"attr_seen_$name"};
-    $self->{"attr_seen_$name"} = 1;
-  }
-
   # ignore non-elements
   if (exists $elements{$tag} || exists $tricks{$tag}) {
     text_style(@_) if exists $elements_text_style{$tag};
@@ -560,7 +532,6 @@
 
   # invisibility
   if (substr($fg,-6) eq substr($bg,-6)) {
-    $self->put_results(font_invisible => 1);
     return 1;
   }
   # near-invisibility
@@ -609,44 +580,11 @@
 sub html_tests {
   my ($self, $tag, $attr, $num) = @_;
 
-  # HTML shouting
-  if ($tag =~ /^(?:b|i|u|strong|em|big|center|h[1-6])$/) {
-    my $level = 0;
-    for my $shout (qw( b i u strong em big center h1 h2 h3 h4 h5 h6 )) {
-      next unless exists $self->{inside}{$shout};
-      $level += $self->{inside}{$shout};
-    }
-    $self->{max_shouting} = $level if $level > $self->{max_shouting};
-  }      
-  if ($tag =~ /^(?:a|body|div|input|form|td|layer|area|img)$/i) {
-    for my $key (keys %$attr) {
-      if ($key =~ /\bon(?:contextmenu|load|resize|submit|unload)\b/i &&
-	  $attr->{$key})
-      {
-	$self->put_results(html_event_unsafe => 1);
-      }
-    }
-  }
-  if ($tag eq "font" && exists $attr->{size}) {
-    my $size = $attr->{size};
-    $self->put_results(tiny_font => 1) if (($size =~ /^\s*(\d+)/ && $1 <= 1) ||
-					   ($size =~ /\-(\d+)/ && $1 >= 3));
-    $self->put_results(big_font => 1) if (($size =~ /^\s*(\d+)/ && $1 > 3) ||
-					  ($size =~ /\+(\d+)/ && $1 >= 1));
-  }
   if ($tag eq "font" && exists $attr->{face}) {
-    if ($attr->{face} =~ /[A-Z]{3}/ && $attr->{face} !~ /M[ST][A-Z]|ITC/) {
-      $self->put_results(font_face_caps => 1);
-    }
     if ($attr->{face} !~ /^[a-z][a-z -]*[a-z](?:,\s*[a-z][a-z -]*[a-z])*$/i) {
       $self->put_results(font_face_bad => 1);
     }
   }
-  if (exists $attr->{style}) {
-    if ($attr->{style} =~ /font(?:-size)?:\s*(\d+(?:\.\d*)?|\.\d+)(p[tx])/i) {
-      $self->examine_text_style($1, $2);
-    }
-  }
   if ($tag eq "img" && exists $self->{inside}{a} && $self->{inside}{a} > 0) {
     $self->{uri}->{$self->{anchor_last}}->{anchor_text}->[-1] .= "<img>\n";
     $self->{anchor}->[-1] .= "<img>\n";
@@ -702,15 +640,6 @@
   }
 }
 
-sub examine_text_style {
-  my ($self, $size, $type) = @_;
-  $type = lc $type;
-  $self->put_results(tiny_font => 1) if ($type eq "pt" && $size < 4);
-  $self->put_results(tiny_font => 1) if ($type eq "px" && $size < 4);
-  $self->put_results(big_font => 1) if ($type eq "pt" && $size > 14);
-  $self->put_results(big_font => 1) if ($type eq "px" && $size > 18);
-}
-
 sub display_text {
   my $self = shift;
   my $text = shift;
@@ -755,16 +684,9 @@
   if (exists $self->{inside}{script} && $self->{inside}{script} > 0)
   {
     push @{ $self->{script} }, $text;
-    if ($text =~ /\bon(?:blur|contextmenu|focus|load|resize|submit|unload)\b/i)
-    {
-      $self->put_results(html_event_unsafe => 1);
-    }
     return;
   }
   if (exists $self->{inside}{style} && $self->{inside}{style} > 0) {
-    if ($text =~ /font(?:-size)?:\s*(\d+(?:\.\d*)?|\.\d+)(p[tx])/i) {
-      $self->examine_text_style($1, $2);
-    }
     return;
   }
 
@@ -781,8 +703,6 @@
   my $invisible_for_bayes = 0;
   if ($text =~ /[^ \t\n\r\f\x0b\xa0]/) {
     $invisible_for_bayes = $self->html_font_invisible($text);
-    $self->put_results(text_after_body => 1) if $self->{closed_body};
-    $self->put_results(text_after_html => 1) if $self->{closed_html};
   }
 
   if (exists $self->{text}->[-1]) {
@@ -817,21 +737,6 @@
   my ($self, $text) = @_;
 
   push @{ $self->{comment} }, $text;
-
-  if (exists $self->{inside}{script} && $self->{inside}{script} > 0)
-  {
-    if ($text =~ /\bon(?:blur|contextmenu|focus|load|resize|submit|unload)\b/i)
-    {
-      $self->put_results(html_event_unsafe => 1);
-    }
-    return;
-  }
-  if (exists $self->{inside}{style} && $self->{inside}{style} > 0) {
-    if ($text =~ /font(?:-size)?:\s*(\d+(?:\.\d*)?|\.\d+)(p[tx])/i) {
-      $self->examine_text_style($1, $2);
-    }
-    return;
-  }
 }
 
 sub html_declaration {
@@ -839,7 +744,6 @@
 
   if ($text =~ /^<!doctype/i) {
     my $tag = "!doctype";
-
     $self->{elements}++;
     $self->{tags}++;
     $self->{inside}{$tag} = 0;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Locker/UnixNFSSafe.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Locker/UnixNFSSafe.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Locker/UnixNFSSafe.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Locker/UnixNFSSafe.pm Wed Nov 15 12:40:35 2006
@@ -101,7 +101,8 @@
     my $now = ($#stat < 11 ? undef : $stat[10]);
     @stat = lstat($lock_file);
     my $lock_age = ($#stat < 11 ? undef : $stat[10]);
-    if (defined($lock_age) && ($now - $lock_age) > LOCK_MAX_AGE) {
+    if (defined($lock_age) && defined($now) && ($now - $lock_age) > LOCK_MAX_AGE)
+    {
       # we got a stale lock, break it
       dbg("locker: safe_lock: breaking stale $lock_file: age=" .
 	  (defined $lock_age ? $lock_age : "undef") . " now=$now");

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message.pm Wed Nov 15 12:40:35 2006
@@ -210,8 +210,7 @@
     else {
       # Ok, there's a header here, let's go ahead and add it in.
       if ($header) {
-        # Yes, the /s is needed to match \n too.
-        my ($key, $value) = split (/:\s*(?=.)/s, $header, 2);
+        my ($key, $value) = split (/:/s, $header, 2);
 
         # If it's not a valid header (aka: not in the form "foo: bar"), skip it.
         if (defined $value) {
@@ -613,7 +612,13 @@
 	# Ok, we've subparsed, so go ahead and remove the raw and decoded
 	# data because we won't need them anymore (the tree under this part
 	# will have that data)
+	if (ref $toparse->[0]->{'raw'} eq 'GLOB') {
+	  # Make sure we close it if it's a temp file -- Bug 5166
+	  close ($toparse->[0]->{'raw'});
+	}
+
 	delete $toparse->[0]->{'raw'};
+	  
 	delete $toparse->[0]->{'decoded'};
       }
     }

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message/Node.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message/Node.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message/Node.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Message/Node.pm Wed Nov 15 12:40:35 2006
@@ -56,7 +56,8 @@
   my $self = {
     headers		=> {},
     raw_headers		=> {},
-    header_order	=> []
+    header_order	=> [],
+    type                => ""
   };
 
   # deal with any parameters
@@ -173,6 +174,7 @@
     my $dec_value = $raw_value;
     $dec_value =~ s/\n[ \t]+/ /gs;
     $dec_value =~ s/\s*$//s;
+    $dec_value =~ s/^\s*//s;
     push @{ $self->{'headers'}->{$key} },     $self->_decode_header($dec_value);
 
     push @{ $self->{'raw_headers'}->{$key} }, $raw_value;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm Wed Nov 15 12:40:35 2006
@@ -152,95 +152,9 @@
     $self->{conf}->set_score_set ($set|2);
   }
 
-  {
-    # bug 4353:
-    # Do this before the RBL tests are kicked off.  The metadata parsing
-    # will figure out the (un)trusted relays and such, which are used in the
-    # rbl calls.
-    $self->extract_message_metadata();
-
-    # Here, we launch all the DNS RBL queries and let them run while we
-    # inspect the message
-    $self->run_rbl_eval_tests ($self->{conf}->{rbl_evals});
-    my $needs_dnsbl_harvest_p = 1; # harvest needs to be run
-
-    my $decoded = $self->get_decoded_stripped_body_text_array();
-    my $bodytext = $self->get_decoded_body_text_array();
-    my $fulltext = $self->{msg}->get_pristine();
-
-    my @uris = $self->get_uri_list();
-
-    foreach my $priority (sort { $a <=> $b } keys %{$self->{conf}->{priorities}}) {
-      # no need to run if there are no priorities at this level.  This can
-      # happen in Conf.pm when we switch a rules from one priority to another
-      next unless ($self->{conf}->{priorities}->{$priority} > 0);
-
-      # if shortcircuiting is hit, we skip all other priorities...
-      last if $self->have_shortcircuited();
-
-      dbg("check: running tests for priority: $priority");
-
-      # only harvest the dnsbl queries once priority HARVEST_DNSBL_PRIORITY
-      # has been reached and then only run once
-      if ($priority >= HARVEST_DNSBL_PRIORITY && $needs_dnsbl_harvest_p
-            && !$self->have_shortcircuited())
-      {
-	# harvest the DNS results
-	$self->harvest_dnsbl_queries();
-	$needs_dnsbl_harvest_p = 0;
-
-	# finish the DNS results
-	$self->rbl_finish();
-	$self->{main}->call_plugins ("check_post_dnsbl", { permsgstatus => $self });
-       $self->{resolver}->finish_socket() if $self->{resolver};
-      }
-
-      # do head tests
-      $self->do_head_tests($priority);
-      $self->do_head_eval_tests($priority);
-
-      $self->do_body_tests($priority, $decoded);
-      $self->do_body_uri_tests($priority, @uris);
-      $self->do_body_eval_tests($priority, $decoded);
-  
-      $self->do_rawbody_tests($priority, $bodytext);
-      $self->do_rawbody_eval_tests($priority, $bodytext);
-  
-      $self->do_full_tests($priority, \$fulltext);
-      $self->do_full_eval_tests($priority, \$fulltext);
-
-      $self->do_meta_tests($priority);
-
-      # we may need to call this more often than once through the loop, but
-      # it needs to be done at least once, either at the beginning or the end.
-      $self->{main}->call_plugins ("check_tick", { permsgstatus => $self });
-    }
-
-    # sanity check, it is possible that no rules >= HARVEST_DNSBL_PRIORITY ran so the harvest
-    # may not have run yet.  Check, and if so, go ahead and harvest here.
-    if ($needs_dnsbl_harvest_p) {
-      if (!$self->have_shortcircuited()) {
-        # harvest the DNS results
-        $self->harvest_dnsbl_queries();
-      }
-
-      # finish the DNS results
-      # TODO: this should be consolidated with the identical code above
-      $self->rbl_finish();
-      $self->{main}->call_plugins ("check_post_dnsbl", { permsgstatus => $self });
-      $self->{resolver}->finish_socket() if $self->{resolver};
-    }
-
-    # finished running rules
-    delete $self->{current_rule_name};
-    undef $decoded;
-    undef $bodytext;
-    undef $fulltext;
-
-    # auto-learning
-    $self->learn();
-    $self->{main}->call_plugins ("check_post_learn", { permsgstatus => $self });
-  }
+  # The primary check functionality occurs via a plugin call.  For more information please
+  # see: Mail::SpamAssassin::Plugin::Check
+  $self->{main}->call_plugins ("check_main", { permsgstatus => $self });
 
   # delete temporary storage and memory allocation used during checking
   $self->delete_fulltext_tmpfile();
@@ -1584,7 +1498,11 @@
   }
   # a conventional header
   else {
-    $result = join('', $self->{msg}->get_header($request, $getraw));
+    if ($getraw) {
+      $result = join('', $self->{msg}->raw_header($request));
+    } else {
+      $result = join('', $self->{msg}->get_header($request));
+    }
 
     # metadata
     if (!$result) {
@@ -1659,418 +1577,6 @@
 
 ###########################################################################
 
-sub start_rules_plugin_code {
-  my ($self, $ruletype, $pri) = @_;
-
-  my $evalstr = '
-
-      # start_rules_plugin_code '.$ruletype.'
-      my $scoresptr = $self->{conf}->{scores};
-
-  ';
-
-  if ($self->{main}->have_plugin("start_rules")) {
-    $evalstr .= '
-
-      $self->{main}->call_plugins ("start_rules", { permsgstatus => $self, ruletype
-=> \''.$ruletype.'\', priority => $pri });
-
-    ';
-  }
-
-  return $evalstr;
-}
-
-sub hit_rule_plugin_code {
-  my ($self, $rulename, $ruletype, $loop_break_directive) = @_;
-
-  # note: keep this in 'single quotes' to avoid the $ & performance hit,
-  # unless specifically requested by the caller.   Also split the
-  # two chars, just to be paranoid and ensure that a buggy perl interp
-  # doesn't impose that hit anyway (just in case)
-  my $match = '($' . '&' . '|| "negative match")';
-
-  my $debug_code = '';
-  if (exists($self->{should_log_rule_hits})) {
-    $debug_code = '
-        dbg("rules: ran '.$ruletype.' rule '.$rulename.' ======> got hit: \"" . '.
-            $match.' . "\"");
-    ';
-  }
-
-  my $save_hits_code = '';
-  if ($self->{save_pattern_hits}) {
-    $save_hits_code = '
-        $self->{pattern_hits}->{q{'.$rulename.'}} = '.$match.';
-    ';
-  }
-
-  # if we're not running "tflags multiple", break out of the matching
-  # loop this way
-  my $multiple_code = '';
-  if ($self->{conf}->{tflags}->{$rulename} !~ /\bmultiple\b/) {
-    $multiple_code = $loop_break_directive.';';
-  }
-
-  return $debug_code.$save_hits_code.$multiple_code;
-}
-
-sub ran_rule_plugin_code {
-  my ($self, $rulename, $ruletype) = @_;
-
-  return '' unless $self->{main}->have_plugin("ran_rule");
-
-  return '
-    $self->{main}->call_plugins ("ran_rule", { permsgstatus => $self, rulename => \''.$rulename.'\', ruletype => \''.$ruletype.'\' });
-  ';
-}
-
-sub hash_line_for_rule {
-  my ($self, $rulename) = @_;
-  return "\n".'#line 1 "'.
-        $self->{conf}->{source_file}->{$rulename}.
-        ', rule '.$rulename.',"';
-}
-
-###########################################################################
-
-sub do_head_tests {
-  my ($self, $priority) = @_;
-
-  return if $self->have_shortcircuited();
-
-  # note: we do this only once for all head pattern tests.  Only
-  # eval tests need to use stuff in here.
-  $self->{test_log_msgs} = ();        # clear test state
-
-  dbg("rules: running header regexp tests; score so far=".$self->{score});
-
-  my $doing_user_rules = 
-    $self->{conf}->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_HEAD_TESTS};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  # speedup code provided by Matt Sergeant
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::_head_tests_'.$clean_priority}
-      && !$doing_user_rules) {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::_head_tests_'.$clean_priority}($self);
-    use strict "refs";
-    return;
-  }
-
-  my $evalstr = $self->start_rules_plugin_code("header", $priority);
-  my $use_rule_subs = $self->{main}->{use_rule_subs};
-
-  my $evalstr2 = '';
-
-  # hash to hold the rules, "header\tdefault value" => rulename
-  my %ordered = ();
-  my %testcode = ();
-
-  while (my($rulename, $rule) = each %{$self->{conf}{head_tests}->{$priority}}) {
-    my $def = '';
-    my ($hdrname, $testtype, $pat) =
-        $rule =~ /^\s*(\S+)\s*(\=|\!)\~\s*(\S.*?\S)\s*$/;
-
-    if (!defined $pat) {
-      warn "rules: invalid rule: $rulename\n";
-      $self->{rule_errors}++;
-      next;
-    }
-
-    if ($pat =~ s/\s+\[if-unset:\s+(.+)\]\s*$//) { $def = $1; }
-
-    $hdrname =~ s/#/[HASH]/g;                # avoid probs with eval below
-    $def =~ s/#/[HASH]/g;
-
-    push(@{$ordered{"$hdrname\t$def"}}, $rulename);
-
-    if ($doing_user_rules) {
-      next if (!$self->is_user_rule_sub ($rulename.'_head_test'));
-    }
-
-    if ($use_rule_subs) {
-      $evalstr2 .= '
-	sub '.$rulename.'_head_test {
-	  my($self,$text) = @_;
-	  '.$self->hash_line_for_rule($rulename).'
-	  while ($text '.$testtype.'~ '.$pat.'g) {
-	    $self->got_hit(q#'.$rulename.'#, "", ruletype => "header");
-	    '. $self->hit_rule_plugin_code($rulename, "header", "last") . '
-	  }
-	}
-      ';
-      push (@TEMPORARY_METHODS, $rulename.'_head_test');
-    }
-    else {
-      # store for use below
-      $testcode{$rulename} = $testtype.'~ '.$pat.'g';
-    }
-  }
-
-  # setup the function to run the rules
-  while(my($k,$v) = each %ordered) {
-    my($hdrname, $def) = split(/\t/, $k, 2);
-    $evalstr .= ' $hval = $self->get(q#'.$hdrname.'#, q#'.$def.'#);';
-    foreach my $rulename (@{$v}) {
-      if ($use_rule_subs) {
-	$evalstr .= '
-	  if ($scoresptr->{q#'.$rulename.'#}) {
-	     '.$rulename.'_head_test($self, $hval);
-	     '.$self->ran_rule_plugin_code($rulename, "header").'
-	  }
-	';
-      }
-      else {
-        my $testcode = $testcode{$rulename};
-
-	$evalstr .= '
-	  if ($scoresptr->{q#'.$rulename.'#}) {
-	    pos $hval = 0;
-	    '.$self->hash_line_for_rule($rulename).'
-	    while ($hval '.$testcode.') {
-	      $self->got_hit(q#'.$rulename.'#, "", ruletype => "header");
-	      '.$self->hit_rule_plugin_code($rulename, "header", "last").'
-	    }
-	    '.$self->ran_rule_plugin_code($rulename, "header").'
-	  }
-	';
-      }
-    }
-  }
-
-  # clear out a previous version of this fn, if already defined
-  if (defined &{'_head_tests_'.$clean_priority}) {
-    undef &{'_head_tests_'.$clean_priority};
-  }
-
-  return unless ($evalstr);
-
-  $evalstr = <<"EOT";
-{
-    package Mail::SpamAssassin::PerMsgStatus;
-
-    $evalstr2
-
-    sub _head_tests_$clean_priority {
-        my (\$self) = \@_;
-        my \$hval;
-
-        $evalstr;
-    }
-
-    1;
-}
-EOT
-
-  eval $evalstr;
-
-  if ($@) {
-    warn "rules: failed to run header tests, skipping some: $@\n";
-    $self->{rule_errors}++;
-  }
-  else {
-    my $method = '_head_tests_'.$clean_priority;
-    push @TEMPORARY_METHODS, $method;
-    no strict "refs";
-    &{$method}($self);
-    use strict "refs";
-  }
-}
-
-sub do_body_tests {
-  my ($self, $priority, $textary) = @_;
-    
-  return if $self->have_shortcircuited();
-
-  dbg("rules: running body-text per-line regexp tests; score so far=".$self->{score});
-
-  my $conf = $self->{conf};
-  my $doing_user_rules = 
-    $conf->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_BODY_TESTS};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  $self->{test_log_msgs} = ();        # clear test state
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::_body_tests_'.$clean_priority}
-       && !$doing_user_rules) {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::_body_tests_'.$clean_priority}($self, @$textary);
-    use strict "refs";
-    return;
-  }
-
-  # caller can set this member of the Mail::SpamAssassin object to
-  # override this; useful for profiling rule runtimes, although I think
-  # the HitFreqsRuleTiming.pm plugin is probably better nowadays anyway
-  my $use_rule_subs = $self->{main}->{use_rule_subs};
-
-  # build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("body", $priority);
-  my $evalstr2 = '';
-  my $loopid = 0;
-
-  $evalstr .= '
-
-        $self->{main}->call_plugins("run_body_hack", {
-                permsgstatus => $self, ruletype => "body",
-                priority => '.$priority.', lines => \@_
-              });
-
-  ';
-
-  while (my($rulename, $pat) = each %{$conf->{body_tests}->{$priority}})
-  {
-    my $sub;
-    my $sub_one_line;
-
-    my $need_one_line;
-    if ($conf->{generate_body_one_line_sub}->{$rulename}) {
-      $need_one_line = 1;
-    }
-
-    if ($conf->{tflags}->{$rulename} =~ /\bmultiple\b/)
-    {
-      # support multiple matches
-      $loopid++;
-      $sub = '
-      body_'.$loopid.': foreach my $l (@_) {
-	pos $l = 0;
-	'.$self->hash_line_for_rule($rulename).'
-	while ($l =~ '.$pat.'g) { 
-	  $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body"); 
-	  '. $self->hit_rule_plugin_code($rulename, "body",
-				    "last body_".$loopid) . '
-	}
-      }
-      ';
-
-      if ($need_one_line) {
-	$sub_one_line = '
-	pos $_[1] = 0;
-	'.$self->hash_line_for_rule($rulename).'
-	while ($_[1] =~ '.$pat.'g) { 
-          my $self = $_[0];
-	  $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body"); 
-	  '. $self->hit_rule_plugin_code($rulename, "body", "return 1") . '
-	}
-	';
-      }
-    }
-    else {
-      # omitting the "pos" call, "body_loopid" label, use of while()
-      # instead of if() etc., shaves off 8 perl OPs.
-      $sub = '
-      foreach my $l (@_) {
-	'.$self->hash_line_for_rule($rulename).'
-	if ($l =~ '.$pat.') { 
-	  $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body"); 
-	  '. $self->hit_rule_plugin_code($rulename, "body", "last") .'
-	}
-      }
-      ';
-
-      if ($need_one_line) {
-	$sub_one_line = '
-	'.$self->hash_line_for_rule($rulename).'
-	if ($_[1] =~ '.$pat.') { 
-          my $self = $_[0];
-	  $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body"); 
-	  '. $self->hit_rule_plugin_code($rulename, "body", "return 1") . '
-	}
-	';
-      }
-    }
-
-    if (!$conf->{skip_body_rules}->{$rulename}) {
-      if ($use_rule_subs) {
-        $evalstr .= '
-          if ($scoresptr->{q{'.$rulename.'}}) {
-            '.$rulename.'_body_test($self,@_); 
-            '.$self->ran_rule_plugin_code($rulename, "body").'
-          }
-        ';
-      }
-      else {
-        $evalstr .= '
-          if ($scoresptr->{q{'.$rulename.'}}) {
-            '.$sub.'
-            '.$self->ran_rule_plugin_code($rulename, "body").'
-          }
-        ';
-      }
-    }
-
-    if ($doing_user_rules) {
-      next if (!$self->is_user_rule_sub ($rulename.'_body_test'));
-    }
-
-    if ($use_rule_subs) {
-      $evalstr2 .= '
-	sub '.$rulename.'_body_test { my $self = shift; '.$sub.' }
-      ';
-      push (@TEMPORARY_METHODS, $rulename.'_body_test');
-    }
-
-    if ($need_one_line) {
-      $evalstr2 .= '
-	  sub '.$rulename.'_one_line_body_test { '.$sub_one_line.' }
-      ';
-    }
-    push (@TEMPORARY_METHODS, $rulename.'_one_line_body_test');
-  }
-
-  # clear out a previous version of this fn, if already defined
-  if (defined &{'_body_tests_'.$clean_priority}) {
-    undef &{'_body_tests_'.$clean_priority};
-  }
-
-  return unless ($evalstr);
-
-  # generate the loop that goes through each line...
-  $evalstr = <<"EOT";
-{
-  package Mail::SpamAssassin::PerMsgStatus;
-
-  $evalstr2
-
-  sub _body_tests_$clean_priority {
-    my \$self = shift;
-    $evalstr;
-  }
-
-  1;
-}
-EOT
-
-  # warn("body eval code for pri $priority:\n".$evalstr."\nend of body eval code");
-
-  # and run it.
-  eval $evalstr;
-  if ($@) {
-    warn("rules: failed to compile body tests, skipping:\n" . "\t($@)\n");
-    $self->{rule_errors}++;
-  }
-  else {
-    my $method = '_body_tests_'.$clean_priority;
-    push @TEMPORARY_METHODS, $method;
-    no strict "refs";
-    &{$method}($self,@$textary);
-    use strict "refs";
-  }
-}
-
-sub is_user_rule_sub {
-  my ($self, $subname) = @_;
-  return 0 if (eval 'defined &Mail::SpamAssassin::PerMsgStatus::'.$subname);
-  1;
-}
-
 # Taken from URI and URI::Find
 my $reserved   = q(;/?:@&=+$,[]\#|);
 my $mark       = q(-_.!~*'());                                    #'; emacs
@@ -2387,549 +1893,8 @@
   return @{$self->{parsed_uri_list}};
 }
 
-sub do_body_uri_tests {
-  my ($self, $priority, @uris) = @_;
-
-  return if $self->have_shortcircuited();
-  
-  dbg("uri: running uri tests; score so far=".$self->{score});
-
-  my $doing_user_rules = 
-    $self->{conf}->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_URI_TESTS};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  $self->{test_log_msgs} = ();        # clear test state
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::_body_uri_tests_'.$clean_priority}
-      && !$doing_user_rules) {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::_body_uri_tests_'.$clean_priority}($self, @uris);
-    use strict "refs";
-    return;
-  }
-
-  my $use_rule_subs = $self->{main}->{use_rule_subs};
-
-  # otherwise build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("uri", $priority);
-  my $evalstr2 = '';
-  my $loopid = 0;
-
-  while (my($rulename, $pat) = each %{$self->{conf}{uri_tests}->{$priority}}) {
-    my $sub;
-    if ($self->{conf}->{tflags}->{$rulename} =~ /\bmultiple\b/)
-    {
-      $loopid++;
-      $sub = '
-      uri_'.$loopid.': foreach my $l (@_) {
-	pos $l = 0;
-	'.$self->hash_line_for_rule($rulename).'
-	while ($l =~ '.$pat.'g) { 
-	   $self->got_hit(q{'.$rulename.'}, "URI: ", ruletype => "uri");
-	   '. $self->hit_rule_plugin_code($rulename, "uri",
-				    "last uri_".$loopid) . '
-	}
-      }
-      ';
-    } else {
-      $sub = '
-      foreach my $l (@_) {
-	'.$self->hash_line_for_rule($rulename).'
-	if ($l =~ '.$pat.') { 
-	   $self->got_hit(q{'.$rulename.'}, "URI: ", ruletype => "uri");
-	   '. $self->hit_rule_plugin_code($rulename, "uri", "last") .'
-	}
-      }
-      ';
-    }
-
-    if ($use_rule_subs) {
-      $evalstr .= '
-	if ($scoresptr->{q{'.$rulename.'}}) {
-	  '.$rulename.'_uri_test($self, @_);
-	  '.$self->ran_rule_plugin_code($rulename, "uri").'
-	}
-      ';
-    }
-    else {
-      $evalstr .= '
-	if ($scoresptr->{q{'.$rulename.'}}) {
-	  '.$sub.'
-	  '.$self->ran_rule_plugin_code($rulename, "uri").'
-	}
-      ';
-    }
-
-    if ($doing_user_rules) {
-      next if (!$self->is_user_rule_sub ($rulename.'_uri_test'));
-    }
-
-    if ($use_rule_subs) {
-      $evalstr2 .= '
-        sub '.$rulename.'_uri_test { my $self = shift; '.$sub.' }
-      ';
-      push (@TEMPORARY_METHODS, $rulename.'_uri_test');
-    }
-  }
-
-  # clear out a previous version of this fn, if already defined
-  if (defined &{'_body_uri_tests_'.$clean_priority}) {
-    undef &{'_body_uri_tests_'.$clean_priority};
-  }
-
-  return unless ($evalstr);
-
-  # generate the loop that goes through each line...
-  $evalstr = <<"EOT";
-{
-  package Mail::SpamAssassin::PerMsgStatus;
-
-  $evalstr2
-
-  sub _body_uri_tests_$clean_priority {
-    my \$self = shift;
-    $evalstr;
-  }
-
-  1;
-}
-EOT
-
-  # and run it.
-  eval $evalstr;
-  if ($@) {
-    warn("rules: failed to compile URI tests, skipping:\n" . "\t($@)\n");
-    $self->{rule_errors}++;
-  }
-  else {
-    my $method = '_body_uri_tests_'.$clean_priority;
-    push @TEMPORARY_METHODS, $method;
-    no strict "refs";
-    &{$method}($self, @uris);
-    use strict "refs";
-  }
-}
-
-sub do_rawbody_tests {
-  my ($self, $priority, $textary) = @_;
-
-  return if $self->have_shortcircuited();
-
-  dbg("rules: running raw-body-text per-line regexp tests; score so far=".$self->{score});
-
-  my $doing_user_rules = 
-    $self->{conf}->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_RAWBODY_TESTS};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  $self->{test_log_msgs} = ();        # clear test state
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::_rawbody_tests_'.$clean_priority}
-      && !$doing_user_rules) {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::_rawbody_tests_'.$clean_priority}($self, @$textary);
-    use strict "refs";
-    return;
-  }
-
-  my $use_rule_subs = $self->{main}->{use_rule_subs};
-
-  # build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("rawbody", $priority);
-  my $evalstr2 = '';
-  my $loopid = 0;
-
-  while (my($rulename, $pat) = each %{$self->{conf}{rawbody_tests}->{$priority}}) {
-    my $sub;
-    if ($self->{conf}->{tflags}->{$rulename} =~ /\bmultiple\b/)
-    {
-      # support multiple matches
-      $loopid++;
-      $sub = '
-      rawbody_'.$loopid.': foreach my $l (@_) {
-	pos $l = 0;
-	'.$self->hash_line_for_rule($rulename).'
-	while ($l =~ '.$pat.'g) { 
-	   $self->got_hit(q{'.$rulename.'}, "RAW: ", ruletype => "rawbody");
-	   '. $self->hit_rule_plugin_code($rulename, "rawbody",
-				    "last rawbody_".$loopid) . '
-	}
-      }
-      ';
-    }
-    else {
-      $sub = '
-      foreach my $l (@_) {
-	'.$self->hash_line_for_rule($rulename).'
-	if ($l =~ '.$pat.') { 
-	   $self->got_hit(q{'.$rulename.'}, "RAW: ", ruletype => "rawbody");
-	   '. $self->hit_rule_plugin_code($rulename, "rawbody", "last") . '
-	}
-      }
-      ';
-    }
-
-    if ($use_rule_subs) {
-      $evalstr .= '
-	if ($scoresptr->{q{'.$rulename.'}}) {
-	   '.$rulename.'_rawbody_test($self, @_);
-	   '.$self->ran_rule_plugin_code($rulename, "rawbody").'
-	}
-      ';
-    }
-    else {
-      $evalstr .= '
-	if ($scoresptr->{q{'.$rulename.'}}) {
-	  '.$sub.'
-	  '.$self->ran_rule_plugin_code($rulename, "rawbody").'
-	}
-      ';
-    }
-
-    if ($doing_user_rules) {
-      next if (!$self->is_user_rule_sub ($rulename.'_rawbody_test'));
-    }
-
-    if ($use_rule_subs) {
-      $evalstr2 .= '
-	sub '.$rulename.'_rawbody_test { my $self = shift; '.$sub.' }
-      ';
-      push (@TEMPORARY_METHODS, $rulename.'_rawbody_test');
-    }
-  }
-
-  # clear out a previous version of this fn, if already defined
-  if (defined &{'_rawbody_tests_'.$clean_priority}) {
-    undef &{'_rawbody_tests_'.$clean_priority};
-  }
-
-  return unless ($evalstr);
-
-  # generate the loop that goes through each line...
-  $evalstr = <<"EOT";
-{
-  package Mail::SpamAssassin::PerMsgStatus;
-
-  $evalstr2
-
-  sub _rawbody_tests_$clean_priority {
-    my \$self = shift;
-    $evalstr;
-  }
-
-  1;
-}
-EOT
-
-  # and run it.
-  eval $evalstr;
-  if ($@) {
-    warn("rules: failed to compile body tests, skipping:\n" . "\t($@)\n");
-    $self->{rule_errors}++;
-  }
-  else {
-    my $method = '_rawbody_tests_'.$clean_priority;
-    push @TEMPORARY_METHODS, $method;
-    no strict "refs";
-    &{$method}($self, @$textary);
-    use strict "refs";
-  }
-}
-
-sub do_full_tests {
-  my ($self, $priority, $fullmsgref) = @_;
-    
-  return if $self->have_shortcircuited();
-  
-  dbg("rules: running full-text regexp tests; score so far=".$self->{score});
-
-  my $doing_user_rules = 
-    $self->{conf}->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_FULL_TESTS};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  $self->{test_log_msgs} = ();        # clear test state
-
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::_full_tests_'.$clean_priority}
-      && !$doing_user_rules) {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::_full_tests_'.$clean_priority}($self, $fullmsgref);
-    use strict "refs";
-    return;
-  }
-
-  # build up the eval string...
-  my $evalstr = $self->start_rules_plugin_code("full", $priority);
-
-  while (my($rulename, $pat) = each %{$self->{conf}{full_tests}->{$priority}}) {
-    $evalstr .= '
-      if ($scoresptr->{q{'.$rulename.'}}) {
-        pos $$fullmsgref = 0;
-        '.$self->hash_line_for_rule($rulename).'
-        while ($$fullmsgref =~ '.$pat.'g) {
-          $self->got_hit(q{'.$rulename.'}, "FULL: ", ruletype => "full");
-          '. $self->hit_rule_plugin_code($rulename, "full", "last") . '
-        }
-        '.$self->ran_rule_plugin_code($rulename, "full").'
-      }
-    ';
-  }
-
-  if (defined &{'_full_tests_'.$clean_priority}) {
-    undef &{'_full_tests_'.$clean_priority};
-  }
-
-  return unless ($evalstr);
-
-  # and compile it.
-  $evalstr = <<"EOT";
-  {
-    package Mail::SpamAssassin::PerMsgStatus;
-
-    sub _full_tests_$clean_priority {
-        my (\$self, \$fullmsgref) = \@_;
-        study \$\$fullmsgref;
-        $evalstr
-    }
-
-    1;
-  }
-EOT
-  eval $evalstr;
-
-  if ($@) {
-    warn "rules: failed to compile full tests, skipping:\n" . "\t($@)\n";
-    $self->{rule_errors}++;
-  } else {
-    my $method = '_full_tests_'.$clean_priority;
-    push @TEMPORARY_METHODS, $method;
-    no strict "refs";
-    &{$method}($self, $fullmsgref);
-    use strict "refs";
-  }
-}
-
 ###########################################################################
 
-sub do_head_eval_tests {
-  my ($self, $priority) = @_;
-  return unless (defined($self->{conf}->{head_evals}->{$priority}));
-  $self->run_eval_tests ($Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS,
-                         $self->{conf}->{head_evals}->{$priority}, '', $priority);
-}
-
-sub do_body_eval_tests {
-  my ($self, $priority, $bodystring) = @_;
-  return unless (defined($self->{conf}->{body_evals}->{$priority}));
-  $self->run_eval_tests ($Mail::SpamAssassin::Conf::TYPE_BODY_EVALS,
-                         $self->{conf}->{body_evals}->{$priority}, 'BODY: ',
-                         $priority, $bodystring);
-}
-
-sub do_rawbody_eval_tests {
-  my ($self, $priority, $bodystring) = @_;
-  return unless (defined($self->{conf}->{rawbody_evals}->{$priority}));
-  $self->run_eval_tests ($Mail::SpamAssassin::Conf::TYPE_RAWBODY_EVALS,
-                         $self->{conf}->{rawbody_evals}->{$priority}, 'RAW: ',
-                         $priority, $bodystring);
-}
-
-sub do_full_eval_tests {
-  my ($self, $priority, $fullmsgref) = @_;
-  return unless (defined($self->{conf}->{full_evals}->{$priority}));
-  $self->run_eval_tests ($Mail::SpamAssassin::Conf::TYPE_FULL_EVALS,
-                         $self->{conf}->{full_evals}->{$priority}, '',
-                         $priority, $fullmsgref);
-}
-
-###########################################################################
-
-sub do_meta_tests {
-  my ($self, $priority) = @_;
-    
-  return if $self->have_shortcircuited();
-
-  dbg("rules: running meta tests; score so far=" . $self->{score} );
-  my $conf = $self->{conf};
-
-  my $doing_user_rules = 
-    $conf->{user_rules_to_compile}->{$Mail::SpamAssassin::Conf::TYPE_META_TESTS};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  # speedup code provided by Matt Sergeant
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::_meta_tests_'.$clean_priority}
-       && !$doing_user_rules) {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::_meta_tests_'.$clean_priority}($self);
-    use strict "refs";
-    return;
-  }
-
-  my (%rule_deps, %setup_rules, %meta, $rulename);
-  my $evalstr = q{
-
-    my $h = $self->{tests_already_hit};
-
-  };
-
-  # Get the list of meta tests
-  my @metas = keys %{ $conf->{meta_tests}->{$priority} };
-
-  # Go through each rule and figure out what we need to do
-  foreach $rulename (@metas) {
-    my $rule   = $conf->{meta_tests}->{$priority}->{$rulename};
-    my $token;
-
-    # Lex the rule into tokens using a rather simple RE method ...
-    my $lexer = ARITH_EXPRESSION_LEXER;
-    my @tokens = ($rule =~ m/$lexer/g);
-
-    # Set the rule blank to start
-    $meta{$rulename} = "";
-
-    # List dependencies that are meta tests in the same priority band
-    $rule_deps{$rulename} = [ ];
-
-    # Go through each token in the meta rule
-    foreach $token (@tokens) {
-
-      # Numbers can't be rule names
-      if ($token =~ /^(?:\W+|\d+)$/) {
-        $meta{$rulename} .= "$token ";
-      }
-      else {
-        $meta{$rulename} .= "\$h->{'$token'} ";
-        $setup_rules{$token}=1;
-
-        if (!exists $conf->{scores}->{$token}) {
-          info("rules: meta test $rulename has undefined dependency '$token'");
-        }
-        elsif ($conf->{scores}->{$token} == 0) {
-          my $dowarn = 1;
-
-          # there are some cases where this is expected; don't warn
-          # in those cases.
-          if ((($self->{conf}->get_score_set()) & 1) == 0 &&
-              $conf->{tflags}->{$token} && 
-              $conf->{tflags}->{$token} =~ /\bnet\b/)
-          {
-            $dowarn = 0;    # bug 5040: net rules in a non-net scoreset
-          }
-
-          $dowarn and info("rules: meta test $rulename has dependency '$token' with a zero score");
-        }
-
-        # If the token is another meta rule, add it as a dependency
-        push (@{ $rule_deps{$rulename} }, $token)
-          if (exists $conf->{meta_tests}->{$priority}->{$token});
-      }
-    }
-  }
-
-  # avoid "undefined" warnings by providing a default value for needed rules
-  $evalstr .= join("\n", (map { "\$h->{'$_'} ||= 0;" } keys %setup_rules), "");
-
-  # Sort by length of dependencies list.  It's more likely we'll get
-  # the dependencies worked out this way.
-  @metas = sort { @{ $rule_deps{$a} } <=> @{ $rule_deps{$b} } } @metas;
-
-  my $count;
-  my $tflags = $conf->{tflags};
-
-  # Now go ahead and setup the eval string
-  do {
-    $count = $#metas;
-    my %metas = map { $_ => 1 } @metas; # keep a small cache for fast lookups
-
-    # Go through each meta rule we haven't done yet
-    for (my $i = 0 ; $i <= $#metas ; $i++) {
-
-      # If we depend on meta rules that haven't run yet, skip it
-      next if (grep( $metas{$_}, @{ $rule_deps{ $metas[$i] } }));
-
-      # If we depend on network tests, call ensure_rules_are_complete()
-      # to block until they are
-      my $alldeps = join ' ', grep {
-              $tflags->{$_} =~ /\bnet\b/
-            } @{ $conf->{meta_dependencies}->{ $metas[$i] } };
-
-      if ($alldeps ne '') {
-        $evalstr .= '  $self->ensure_rules_are_complete(q{'.$metas[$i].'}, qw{'.$alldeps.'});';
-      }
-
-      # Add this meta rule to the eval line
-      $evalstr .= '
-        $r = '.$meta{$metas[$i]}.';
-        if ($r) { $self->got_hit(q#'.$metas[$i].'#, "", ruletype => "meta", value => $r); }
-      ';
-
-      splice @metas, $i--, 1;    # remove this rule from our list
-    }
-  } while ($#metas != $count && $#metas > -1); # run until we can't go anymore
-
-  # If there are any rules left, we can't solve the dependencies so complain
-  my %metas = map { $_ => 1 } @metas; # keep a small cache for fast lookups
-  foreach $rulename (@metas) {
-    $self->{rule_errors}++; # flag to --lint that there was an error ...
-    my $msg =
-	"rules: excluding meta test $rulename, unsolved meta dependencies: " .
-	    join(", ", grep($metas{$_}, @{ $rule_deps{$rulename} }));
-    if ($self->{main}->{lint_rules}) {
-      warn $msg."\n";
-    }
-    else {
-      info($msg);
-    }
-  }
-
-  if (defined &{'_meta_tests_'.$clean_priority}) {
-    undef &{'_meta_tests_'.$clean_priority};
-  }
-
-  return unless ($evalstr);
-
-  # setup the environment for meta tests
-  $evalstr = <<"EOT";
-{
-    package Mail::SpamAssassin::PerMsgStatus;
-
-    sub _meta_tests_$clean_priority {
-        # note: cannot set \$^W here on perl 5.6.1 at least, it
-        # crashes meta tests.
-
-        my (\$self) = \@_;
-	my \$r;
-
-        $evalstr;
-    }
-
-    1;
-}
-EOT
-
-  eval $evalstr;
-
-  if ($@) {
-    warn "rules: failed to run meta tests, skipping some: $@\n";
-    $self->{rule_errors}++;
-  }
-  else {
-    my $method = '_meta_tests_'.$clean_priority;
-    push @TEMPORARY_METHODS, $method;
-    no strict "refs";
-    &{$method}($self);
-    use strict "refs";
-  }
-}    # do_meta_tests()
-
 sub ensure_rules_are_complete {
   my $self = shift;
   my $metarule = shift;
@@ -2955,162 +1920,8 @@
 
 ###########################################################################
 
-sub run_eval_tests {
-  my ($self, $testtype, $evalhash, $prepend2desc, $priority, @extraevalargs) = @_;
-
-  return if $self->have_shortcircuited();
-
-  my $conf = $self->{conf};
-  my $doing_user_rules = $conf->{user_rules_to_compile}->{$testtype};
-
-  # clean up priority value so it can be used in a subroutine name
-  my $clean_priority;
-  ($clean_priority = $priority) =~ s/-/neg/;
-
-  my $scoreset = $conf->get_score_set();
-
-  my $methodname = '_eval_tests'.
-                        '_type'.$testtype .
-                        '_pri'.$clean_priority .
-                        '_set'.$scoreset;
-
-  # Some of the rules are scoreset specific, so we need additional 
-  # subroutines to handle those
-  if (defined &{'Mail::SpamAssassin::PerMsgStatus::'.$methodname}
-        && !$doing_user_rules)
-  {
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::'.$methodname}($self,@extraevalargs);
-    use strict "refs";
-    return;
-  }
-
-  # look these up once in advance to save repeated lookups in loop below
-  my $tflagsref = $conf->{tflags};
-  my $eval_pluginsref = $conf->{eval_plugins};
-  my $have_start_rules = $self->{main}->have_plugin("start_rules");
-  my $have_ran_rule = $self->{main}->have_plugin("ran_rule");
-
-  # the buffer for the evaluated code
-  my $evalstr = q{ };
-$evalstr .= q{ my $function; };
-
-  # conditionally include the dbg in the eval str
-  my $dbgstr = q{ };
-  if (would_log('dbg')) {
-    $dbgstr = q{ 
-      dbg("rules: ran eval rule $rulename ======> got hit ($result)");
-    };
-  }
-
-  while (my ($rulename, $test) = each %{$evalhash})
-  {
-    if ($tflagsref->{$rulename}) {
-      # If the rule is a net rule, and we are in a non-net scoreset, skip it.
-      if ($tflagsref->{$rulename} =~ /\bnet\b/) {
-        next if (($scoreset & 1) == 0);
-      }
-      # If the rule is a bayes rule, and we are in a non-bayes scoreset, skip it.
-      if ($tflagsref->{$rulename} =~ /\bbayes\b/) {
-        next if (($scoreset & 2) == 0);
-      }
-    }
-
-    my ($function, @args) = @{$test};
-    if (!$function) {
-      warn "rules: error: no function defined for $rulename";
-      next;
-    }
-
-    $evalstr .= '
-      $rulename = q#'.$rulename.'#;
-      $self->{test_log_msgs} = ();
-    ';
-
-    # only need to set current_rule_name for plugin evals
-    if ($eval_pluginsref->{$function}) {
-      # let plugins get the name of the rule that is currently being run,
-      # and ensure their eval functions exist
-      $evalstr .= '
-        $self->{current_rule_name} = $rulename;
-        $self->register_plugin_eval_glue(q#'.$function.'#);
-      ';
-    }
-
-    # this stuff is quite slow, and totally superfluous if
-    # no plugin is loaded for those hooks
-    if ($have_start_rules) {
-      $evalstr .= '
-        $self->{main}->call_plugins("start_rules", {
-                permsgstatus => $self, ruletype => "eval", priority => $priority
-              });
-      ';
-    }
-
-    my $argstr = '';
-    if (scalar @args > 0) {
-      $argstr = ',' . join (', ', map { "q#".$_."#" } @args);
-    }
-
-    $evalstr .= '
-      eval {
-        $result = $self->' . $function . ' (@extraevalargs '. $argstr .' );
-      };
-      if ($@) { $self->handle_eval_rule_errors($rulename); }
-    ';
-
-    if ($have_ran_rule) {
-      $evalstr .= '
-        $self->{main}->call_plugins("ran_rule", {
-            permsgstatus => $self, ruletype => "eval", rulename => $rulename
-          });
-      ';
-    }
-
-    $evalstr .= '
-      if ($result) {
-        $self->got_hit($rulename, $prepend2desc, ruletype => "eval", value => $result);
-        '.$dbgstr.'
-      }
-    ';
-  }
-
-  # nothing done in the loop, that means no rules
-  return unless ($evalstr);
-
-  $evalstr = <<"EOT";
-{
-  package Mail::SpamAssassin::PerMsgStatus;
-
-    sub ${methodname} {
-      my (\$self, \@extraevalargs) = \@_;
-
-      my \$prepend2desc = q#$prepend2desc#;
-      my \$rulename;
-      my \$result;
-
-      $evalstr
-    }
-
-  1;
-}
-EOT
-
-  eval $evalstr;
-
-  if ($@) {
-    warn "rules: failed to compile eval tests, skipping some: $@\n";
-    $self->{rule_errors}++;
-  }
-  else {
-    push (@TEMPORARY_METHODS, $methodname);
-    no strict "refs";
-    &{'Mail::SpamAssassin::PerMsgStatus::'.$methodname}($self,@extraevalargs);
-    use strict "refs";
-  }
-}
-
 # use a separate sub here, for brevity
+# called out of generated eval
 sub handle_eval_rule_errors {
   my ($self, $rulename) = @_;
   warn "rules: failed to run $rulename test, skipping:\n\t($@)\n";
@@ -3158,47 +1969,6 @@
 
 ###########################################################################
 
-sub run_rbl_eval_tests {
-  my ($self, $evalhash) = @_;
-
-  if ($self->{main}->{local_tests_only}) {
-    dbg("rules: local tests only, ignoring RBL eval");
-    return 0;
-  }
-  
-  while (my ($rulename, $test) = each %{$evalhash}) {
-    my $score = $self->{conf}->{scores}->{$rulename};
-    next unless $score;
-
-    $self->{test_log_msgs} = ();        # clear test state
-
-    my ($function, @args) = @{$test};
-
-    my $result;
-    eval {
-       $result = $self->$function($rulename, @args);
-    };
-
-    if ($@) {
-      warn "rules: failed to run $rulename RBL test, skipping:\n" . "\t($@)\n";
-      $self->{rule_errors}++;
-      next;
-    }
-  }
-}
-
-###########################################################################
-
-sub have_shortcircuited
-{
-  my ($self) = @_;
-  return 1 if $self->{main}->call_plugins ("have_shortcircuited", {
-        permsgstatus => $self
-      });
-}
-
-###########################################################################
-
 # note: only eval tests should store state in $self->{test_log_msgs};
 # pattern tests do not.
 #
@@ -3324,8 +2094,6 @@
 sub got_hit {
   my ($self, $rule, $area, %params) = @_;
 
-  return if $self->have_shortcircuited();
-
   # ensure that rule values always result in an *increase* of
   # $self->{tests_already_hit}->{$rule}:
   my $value = $params{value}; if (!$value || $value <= 0) { $value = 1; }
@@ -3345,7 +2113,7 @@
             $params{score} || $self->{conf}->{scores}->{$rule},
             $area,
             $params{ruletype},
-            ($self->{conf}->{descriptions}->{$rule} || $rule));
+            $self->{conf}->get_description_for_rule($rule) || $rule);
   return 1;
 }
 

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm?view=diff&rev=475409&r1=475408&r2=475409
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm Wed Nov 15 12:40:35 2006
@@ -329,23 +329,9 @@
 
 =back
 
-=item $plugin->extract_metadata ( { options ... } )
-
-Signals that a message is being mined for metadata.  Some plugins may wish
-to add their own metadata as well.
-
-=over 4
-
-=item msg
-
-The C<Mail::SpamAssassin::Message> object for this message.
+=item $plugin->check_main ( { options ... } )
 
-=back
-
-=item $plugin->parsed_metadata ( { options ... } )
-
-Signals that a message's metadata has been parsed, and can now be
-accessed by the plugin.
+Signals that a message should be checked.
 
 =over 4
 
@@ -396,6 +382,66 @@
 
 =back
 
+=item $plugin->check_end ( { options ... } )
+
+Signals that a message check operation has just finished, and the
+results are about to be returned to the caller.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
+The current score, names of rules that hit, etc. can be retrieved
+using the public APIs on this object.
+
+=back
+
+=item $plugin->finish_tests ( { options ... } )
+
+Called via SpamAssassin::finish and should clear up any tests that a plugin
+has added to the namespace.
+
+In certain circumstances, plugins may find it useful to compile
+perl functions from the ruleset, on the fly.  It is important to
+remove these once the C<Mail::SpamAssassin> object is deleted,
+however, and this API allows this.
+
+Each plugin is responsible for its own generated perl functions.
+
+=over 4
+
+=item conf
+
+The C<Mail::SpamAssassin::Conf> object on which the configuration
+data should be stored.
+
+=item $plugin->extract_metadata ( { options ... } )
+
+Signals that a message is being mined for metadata.  Some plugins may wish
+to add their own metadata as well.
+
+=over 4
+
+=item msg
+
+The C<Mail::SpamAssassin::Message> object for this message.
+
+=back
+
+=item $plugin->parsed_metadata ( { options ... } )
+
+Signals that a message's metadata has been parsed, and can now be
+accessed by the plugin.
+
+=over 4
+
+=item permsgstatus
+
+The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
+
+=back
+
 =item $plugin->start_rules ( { options ... } )
 
 Called before testing a set of rules of a given type and priority.
@@ -458,21 +504,6 @@
 =item rulename
 
 The name of the rule that was tested.
-
-=back
-
-=item $plugin->check_end ( { options ... } )
-
-Signals that a message check operation has just finished, and the
-results are about to be returned to the caller.
-
-=over 4
-
-=item permsgstatus
-
-The C<Mail::SpamAssassin::PerMsgStatus> context object for this scan.
-The current score, names of rules that hit, etc. can be retrieved
-using the public APIs on this object.
 
 =back