Parent Directory | Revision Log | 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 |