File Coverage

blib/lib/Mail/Alias/Reader/Parser.pm
Criterion Covered Total %
statement 50 50 100.0
branch 42 42 100.0
condition 9 9 100.0
subroutine 7 7 100.0
pod 0 1 0.0
total 108 109 99.0


line stmt bran cond sub pod time code
1             # Copyright (c) 2012, cPanel, Inc.
2             # All rights reserved.
3             # http://cpanel.net/
4             #
5             # This is free software; you can redistribute it and/or modify it under the same
6             # terms as Perl itself. See the LICENSE file for further details.
7              
8             package Mail::Alias::Reader::Parser;
9              
10 4     4   26 use strict;
  4         11  
  4         155  
11 4     4   21 use warnings;
  4         4  
  4         95  
12              
13 4     4   2637 use Mail::Alias::Reader::Token ();
  4         14  
  4         103  
14              
15 4     4   25 use Carp;
  4         11  
  4         2873  
16              
17             sub _parse_forward_statement {
18 7     7   83 my ($tokens) = @_;
19 7         18 my @destinations;
20              
21 7         32 my $last_token = Mail::Alias::Reader::Token->new('T_BEGIN');
22              
23 7         22 foreach my $token ( @{$tokens} ) {
  7         26  
24 30 100       108 next if $token->isa(qw/T_BEGIN T_COMMENT T_WHITESPACE/);
25              
26 19 100       65 if ( $token->is_value ) {
    100          
27 9 100       26 confess('Unexpected value') if $last_token->is_value;
28              
29 8         18 push @destinations, $token;
30             }
31             elsif ( $token->isa('T_COMMA') ) {
32 6 100 100     18 confess('Unexpected comma') unless $last_token->is_value || $last_token->isa('T_COMMA');
33             }
34             else {
35 4 100       13 confess("Unexpected $token->{'type'}") unless $token->isa('T_END');
36             }
37              
38 16         63 $last_token = $token;
39             }
40              
41 4 100       72 confess('Statement contains no destinations') unless @destinations;
42              
43 3         26 return \@destinations;
44             }
45              
46             sub _parse_aliases_statement {
47 22     22   38 my ($tokens) = @_;
48 22         27 my ( $name, @destinations );
49              
50 22         79 my $last_token = Mail::Alias::Reader::Token->new('T_BEGIN');
51              
52 22         32 foreach my $token ( @{$tokens} ) {
  22         83  
53 152 100       374 next if $token->isa(qw/T_BEGIN T_COMMENT T_WHITESPACE/);
54              
55 102 100       256 if ( $last_token->isa('T_BEGIN') ) {
    100          
    100          
    100          
    100          
56 22 100       82 confess("Expected address as name of alias, found $token->{'type'}") unless $token->is_address;
57             }
58             elsif ( $token->isa('T_COLON') ) {
59 20 100       54 confess('Unexpected colon') unless $last_token->is_address;
60 18 100       85 confess('Too many colons') if $name;
61              
62 16         31 $name = $last_token->{'value'};
63             }
64             elsif ( $token->isa('T_COMMA') ) {
65 20 100 100     54 confess('Unexpected comma') unless $last_token->is_value || $last_token->isa('T_COMMA');
66             }
67             elsif ( $token->isa('T_END') ) {
68 13 100 100     39 confess('Unexpected end of aliases statement') unless $last_token->is_value || $last_token->isa('T_COMMA');
69              
70 11         20 last;
71             }
72             elsif ( $token->is_value ) {
73 26         41 push @destinations, $token;
74             }
75             else {
76 1         12 confess("Unexpected $token->{'type'}");
77             }
78              
79 80         237 $last_token = $token;
80             }
81              
82 11 100       69 confess('Alias statement has no name') unless defined $name;
83              
84 9         90 return ( $name, \@destinations );
85             }
86              
87             sub parse {
88 28     28 0 953 my ( $class, $statement, $mode ) = @_;
89 28         253 my $tokens = Mail::Alias::Reader::Token->tokenize($statement);
90              
91 28 100       122 return _parse_forward_statement($tokens) if $mode eq 'forward';
92 22 100       86 return _parse_aliases_statement($tokens) if $mode eq 'aliases';
93              
94 1         18 confess("Invalid parsing mode $mode specified");
95             }
96              
97             1;
98              
99             __END__