]> source.dussan.org Git - rspamd.git/commitdiff
* Make perl config parser working
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 21 Apr 2010 15:53:08 +0000 (19:53 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 21 Apr 2010 15:53:08 +0000 (19:53 +0400)
perl/lib/Mail/Rspamd/Config.pm

index da81a79c1e38f81b7d9c2b575c42acea7f66959b..13acc66a07cc326b1cae9b0aeb080e5b2b6d8259 100644 (file)
@@ -49,10 +49,13 @@ sub new {
        $class = ref($class) || $class;
 
        my $self = {
-               workers => {},
+               workers => [],
                modules => {},
                classifiers     => {},
                factors => {},
+               options => {},
+               variables => {},
+               logging => {},
                parser_state => {
                        state => PARSER_STATE_START,
                        valid => 1,
@@ -130,22 +133,29 @@ sub _handle_start_element {
                        }
                        elsif ($lce eq 'worker') {
                                $self->{parser_state}->{state} = PARSER_STATE_WORKER;
+                               $self->{parser_state}->{worker} = { options => {} };
                        }
                        elsif ($lce eq 'metric') {
                                $self->parser_state->state = PARSER_STATE_METRIC;
-                               $self->_get_attr(@attrs, 'name', 'name', 1);
+                               $self->_get_attr('name', 'name', 1, @attrs);
+                               $self->{parser_state}->{metric} = {};
                        }
                        elsif ($lce eq 'module') {
-                               $self->parser_state->state = PARSER_STATE_MODULE;
-                               $self->_get_attr(@attrs, 'name', 'name', 1);
+                               $self->{parser_state}->{state} = PARSER_STATE_MODULE;
+                               $self->_get_attr('name', 'name', 1, @attrs);
+                               $self->{parser_state}->{module} = {};
                        }
                        elsif ($lce eq 'classifier') {
-                               $self->parser_state->state = PARSER_STATE_METRIC;
-                               $self->_get_attr(@attrs, 'type', 'type', 1);
+                               $self->{parser_state}->{state} = PARSER_STATE_CLASSIFIER;
+                               $self->_get_attr('type', 'type', 1, @attrs);
+                               $self->{parser_state}->{classifier} = { statfiles => []};
                        }
                        elsif ($lce eq 'factors') {
                                $self->{parser_state}->{state} = PARSER_STATE_FACTORS;
                        }
+                       elsif ($lce eq 'variable') {
+                               $self->_get_attr('name', 'name', 1, @attrs);
+                       }
                        else {
                                # Other element
                                $self->{parser_state}->{element} = $lce;
@@ -154,7 +164,7 @@ sub _handle_start_element {
                elsif ($self->{parser_state}->{state} == PARSER_STATE_MODULE) {
                        my $lce = lc $element;
                        if ($lce eq 'option') {
-                               $self->_get_attr(@attrs, 'name', 'option', 1);
+                               $self->_get_attr('name', 'option', 1, @attrs);
                        }
                        else {
                                $self->{parser_state}->{valid} = 0;
@@ -164,7 +174,7 @@ sub _handle_start_element {
                elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) {
                        my $lce = lc $element;
                        if ($lce eq 'factor') {
-                               $self->_get_attr(@attrs, 'name', 'name', 1);
+                               $self->_get_attr('name', 'name', 1, @attrs);
                        }
                }
                elsif ($self->{parser_state}->{state} == PARSER_STATE_CLASSIFIER) {
@@ -173,6 +183,12 @@ sub _handle_start_element {
                                $self->{parser_state}->{state} = PARSER_STATE_STATFILE;
                        }
                }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_WORKER) {
+                       my $lce = lc $element;
+                       if ($lce eq 'param') {
+                               $self->_get_attr('name', 'name', 1, @attrs);
+                       }
+               }
                elsif ($self->{parser_state}->{state} == PARSER_STATE_END) {
                        # Tags after end element
                        $self->{parser_state}->{valid} = 0;
@@ -217,6 +233,13 @@ sub _handle_end_element {
                                $self->{parser_state}->{classifier} = undef;
                        }
                }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_METRIC) {
+                       if ($lce eq 'metric') {
+                               $self->{metrics}->{ $self->{parser_state}->{name} } = $self->{parser_state}->{metric};
+                               $self->{parser_state}->{state} = PARSER_STATE_MAIN;
+                               $self->{parser_state}->{metric} = undef;
+                       }
+               }
                elsif ($self->{parser_state}->{state} == PARSER_STATE_STATFILE) {
                        if ($lce eq 'statfile') {
                                push(@{$self->{parser_state}->{classifier}->{statfiles}}, $self->{parser_state}->{statfile});
@@ -231,6 +254,16 @@ sub _handle_end_element {
                                $self->{parser_state}->{module} = undef;
                        }
                }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_LOGGING) {
+                       if ($lce eq 'logging') {
+                               $self->{parser_state}->{state} = PARSER_STATE_MAIN;
+                       }
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) {
+                       if ($lce eq 'factors') {
+                               $self->{parser_state}->{state} = PARSER_STATE_MAIN;
+                       }
+               }
        }
 }
 
@@ -244,16 +277,54 @@ Handle data of xml tag
 =cut
 sub _handle_text {
        my ($self, $parser, $string) = @_;
+       
+       my $data;
+
+       if (defined ($string) && $string =~ /^\s*(\S*(?:\s+\S+)*)\s*$/) {
+               $data = $1;
+       }
+       else {
+               return undef;
+       }
+       if (!$data) {
+               return undef;
+       }
 
        if ($self->{parser_state}->{valid}) {
                if ($self->{parser_state}->{state} == PARSER_STATE_MAIN) {
-                       if (defined ($string)) {
-                               chomp $string;
-                               if ($string) {
-                                       $self->{ $self->{parser_state}->{element} } = $string;
-                               }
+                       if ($self->{parser_state}->{element} eq 'variable') {
+                               $self->{variables}->{ $self->{parser_state}->{name} } = $data;
+                       }
+                       else {
+                               $self->{options}->{ $self->{parser_state}->{element} } = $data;
+                       }
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_LOGGING) {
+                       $self->{logging}->{ $self->{parser_state}->{element} } = $data;
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_WORKER) {
+                       if ($self->{parser_state}->{element} eq 'param') {
+                               $self->{parser_state}->{worker}->{options}->{$self->{parser_state}->{name}} = $data;
+                       }
+                       else {
+                               $self->{parser_state}->{worker}->{ $self->{parser_state}->{element} } = $data;
                        }
                }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_CLASSIFIER) {
+                       $self->{parser_state}->{classifier}->{ $self->{parser_state}->{element} } = $data;
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_STATFILE) {
+                       $self->{parser_state}->{statfile}->{ $self->{parser_state}->{element} } = $data;
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_MODULE) {
+                       $self->{parser_state}->{module}->{ $self->{parser_state}->{option} } = $data;
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_FACTORS) {
+                       $self->{factors}->{ $self->{parser_state}->{name} } = $data;
+               }
+               elsif ($self->{parser_state}->{state} == PARSER_STATE_METRIC) {
+                       $self->{parser_state}->{metric}->{ $self->{parser_state}->{element} } = $data;
+               }
        }
 }
 
@@ -268,21 +339,28 @@ Extract specified attr and put it to parser_state
 sub _get_attr {
        my ($self, $name, $hash_name, $required, @attrs) = @_;
        my $found = 0;
+       my $param = 1;
 
        foreach (@attrs) {
-               if (lc $_ eq $name) {
-                       $self->parser_state->{$hash_name} = lc shift;
-                       $found = 1;
+               if ($found) {
+                       $self->{parser_state}->{$hash_name} = $_;
                        last;
                }
                else {
-                       # Shift value
-                       shift;
+                       if ($param) {
+                               if (lc $_ eq $name) {
+                                       $found = 1;
+                               }
+                               $param = 0;
+                       }
+                       else {
+                               $param = 1;
+                       }
                }
        }
 
        if (!$found && $required) {
-               $self->{error} = "Attribute '$name' is required for tag $self->{element}";
-               $self->parser_state->{'valid'} = 0;
+               $self->{error} = "Attribute '$name' is required for tag '$self->{parser_state}->{element}'";
+               $self->{parser_state}->{'valid'} = 0;
        }
 }