/[Apache-SVN]/spamassassin/trunk/build/mkrules
ViewVC logotype

Diff of /spamassassin/trunk/build/mkrules

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- spamassassin/trunk/build/mkrules	2005/10/12 02:43:02	314755
+++ spamassassin/trunk/build/mkrules	2005/10/12 02:52:19	314756
@@ -30,21 +30,25 @@ use File::Find;
 use File::Copy;
 
 use Getopt::Long;
-use vars qw($opt_src $opt_out);
-GetOptions("src=s", "out=s");
+use vars qw(@opt_srcs $opt_out);
+GetOptions("src=s" => \@opt_srcs, "out=s");
 
-die "no src" unless ($opt_src);
+die "no src" unless (@opt_srcs >= 1);
 die "no out" unless ($opt_out);
-die "unreadable src" unless (-d $opt_src);
 die "unreadable out" unless (-d $opt_out);
 
 # source files that need compilation, and their targets
 my $needs_compile = { };
+my $current_src;
 
-File::Find::find ({
+foreach my $src (@opt_srcs) {
+  die "unreadable src" unless (-d $src);
+  $current_src = $src;
+  File::Find::find ({
           wanted => \&wanted,
           no_chdir => 1
-        }, $opt_src);
+        }, $src);
+}
 
 # context for the rules compiler
 my $seen_rules = { };
@@ -58,14 +62,22 @@ write_output_files();
 exit;
 
 sub wanted {
-  return unless (-f $File::Find::name && /\d.*\.(?:cf|pm)$/i);
+  my $path = $File::Find::name;
+  # only files
+  return if (!-f $path);
+  
+  # limit what will be copied from sandboxes
+  return if ($path =~ /sandbox/ && /\d.*\.(?:cf|pm)$/i);
+
+  # a bit of sanity please - no svn metadata ;)
+  return if ($path =~ /\.svn/);
 
-  my $dir = $File::Find::name;
-  $dir =~ s/^${opt_src}[\/\\\:]//s;
+  my $dir = $path;
+  $dir =~ s/^${current_src}[\/\\\:]//s;
   $dir =~ s/([^\/\\\:]+)$//;
   my $filename = $1;
 
-  my $f = "$opt_src/$dir$filename";
+  my $f = "$current_src/$dir$filename";
   my $t = "$opt_out/$filename";
   $needs_compile->{$f} = {
           f => $f,
@@ -95,8 +107,7 @@ sub compile_sorted {
     my $needs_rebuild = 1;
 
     if ($entry->{dir} =~ /sandbox/) {
-      # sandbox rules
-      rule_file_compile(1, $f, $t, $entry->{filename});
+      rule_file_compile_sandbox($f, $t, $entry->{filename});
     }
     elsif ($entry->{dir} =~ /extra/) {
       # 'extra' rulesets; not built by default (TODO)
@@ -105,7 +116,7 @@ sub compile_sorted {
     else {
       # rules in "core" and "lang" are always copied
       if ($needs_rebuild) {
-        rule_file_compile(0, $f, $t, $entry->{filename});
+        rule_file_compile_core($f, $t, $entry->{filename});
       }
     }
   }
@@ -135,8 +146,8 @@ sub compile_sorted {
 # TODO: linting during compilation, and ignore lint-failures? may have to
 # reimplement a small subset of lint behaviour to do this.
 
-sub rule_file_compile {
-  my ($is_sandbox, $f, $t, $filename) = @_;
+sub rule_file_compile_sandbox {
+  my ($f, $t, $filename) = @_;
 
   open (IN, "<$f") or die "cannot read $f";
 
@@ -162,6 +173,9 @@ sub rule_file_compile {
   my $ALWAYS_PUBLISH = '!always_publish!';
   $rules->{$ALWAYS_PUBLISH} = { text => '', publish => 1 };
 
+  # an "ifplugin" or "if" scope
+  my $current_conditional;
+
   while (<IN>) {
     my $orig = $_;
 
@@ -184,7 +198,7 @@ sub rule_file_compile {
 
     if (/^
         (header|rawbody|body|full|uri|meta|mimeheader|describe|
-         tflags|reuse|score)
+        tflags|reuse|score)
         \s+(\S+)\s+(.*)$
       /x)
     {
@@ -194,12 +208,11 @@ sub rule_file_compile {
       my $val = $3;
 
       my $origname = $name;
-      if ($is_sandbox) {
-        $name = rule_name_avoid_collisions($name, $f);
-      }
+      $name = rule_name_avoid_collisions($name, $f);
 
       if (!$rules->{$name}) { $rules->{$name} = rule_entry_create(); }
       $rules->{$name}->{origname} = $origname;
+      $rules->{$name}->{cond} = $current_conditional;
       $rules->{$name}->{text} .= $orig;
 
       $lastrule = $name;
@@ -216,9 +229,7 @@ sub rule_file_compile {
       my $val = $3;
 
       my $origname = $name;
-      if ($is_sandbox) {
-        $name = rule_name_avoid_collisions($name, $f);
-      }
+      $name = rule_name_avoid_collisions($name, $f);
 
       if (!$rules->{$name}) { $rules->{$name} = rule_entry_create(); }
       $rules->{$name}->{origname} = $origname;
@@ -230,11 +241,18 @@ sub rule_file_compile {
       }
       $rules->{$name}->{$command} = $val;
     }
+    elsif (/^
+        (if|ifplugin)
+        \s+(.*?)$
+      /x)
+    {
+      $current_conditional = $orig;
+    }
+    elsif (/^endif\b/x)
+    {
+      undef $current_conditional;
+    }
     else {
-      # this is a non-comment, non-rule, non-build-directive line.
-      # create a file with the same name as the input file, and
-      # publish to that.
-
       # warn "unknown line in rules file '$f', saving to default: $orig";
       $rules->{$ALWAYS_PUBLISH}->{text} .= $orig;
     }
@@ -254,7 +272,7 @@ sub rule_file_compile {
     $pubfile = $opt_out.'/'.$filename;
     $output_files->{$pubfile} = 1;
 
-    if ($is_sandbox && !$rules->{$name}->{publish}) {
+    if (!$rules->{$name}->{publish}) {
       # don't output non-published rules
       next;     
     }
@@ -272,7 +290,13 @@ sub rule_file_compile {
       $output_file_text->{$pubfile} .= $cmts;
     }
 
-    $output_file_text->{$pubfile} .= $text;
+    my $cond = $rules->{$name}->{cond};
+    if ($cond) {
+      $output_file_text->{$pubfile} .= $cond.$text."endif\n";
+    }
+    else {
+      $output_file_text->{$pubfile} .= $text;
+    }
   }
 
   print "$f: ".(scalar @$rule_order)." rules copied\n";
@@ -284,6 +308,64 @@ sub rule_file_compile {
   }
 }
 
+sub rule_file_compile_core {
+  my ($f, $t, $filename) = @_;
+
+  my $pubfile = $opt_out.'/'.$filename;
+  $output_files->{$pubfile} = 1;
+
+  open (IN, "<$f") or die "cannot read $f";
+  while (<IN>) {
+    my $orig = $_;
+
+    s/^#reuse/reuse/;   # TODO - dirty hack.  we need to fix this to just be
+    # a keyword which the engine ignores, this is absurd! 
+
+    s/#.*$//g; s/^\s+//; s/\s+$//;
+
+    # always publish non-sandbox lines verbatim.  just note what
+    # rules we've seen, and carry on
+    $output_file_text->{$pubfile} .= $orig;
+
+    # save "lang" declarations
+    my $lang = '';
+    if (s/^lang\s+(\S+)\s+//) {
+      $lang = $1;
+    }
+
+    if (/^
+        (header|rawbody|body|full|uri|meta|mimeheader|describe|
+        tflags|reuse|score)
+        \s+(\S+)\s+(.*)$
+      /x)
+    {
+      # rule definitions
+      my $type = $1;
+      my $name = $2;
+      my $val = $3;
+
+      # just save the name, and ignore the rest; we're already publishing it
+      $seen_rules->{$name} = 1;
+    }
+    elsif (/^
+        (pubfile|publish)
+        \s+(\S+)\s*(.*?)$
+      /x)
+    {
+      # preprocessor directives
+      my $command = $1;
+      my $name = $2;
+      my $val = $3;
+
+      warn "$f: cannot use 'publish' in non-sandbox files\n";
+    }
+  }
+  close IN;
+
+  # now append all the found text to the output file buffers
+  print "$f: all lines copied\n";
+}
+
 sub write_output_files {
   foreach my $pubfile (sort keys %$output_files) {
     if (-f $pubfile) {

 

infrastructure at apache.org
ViewVC Help
Powered by ViewVC 1.1.26