File Coverage

blib/lib/Parse/Highlife/Token/Delimited.pm
Criterion Covered Total %
statement 9 46 19.5
branch 0 10 0.0
condition n/a
subroutine 3 6 50.0
pod 0 2 0.0
total 12 64 18.7


line stmt bran cond sub pod time code
1             package Parse::Highlife::Token::Delimited;
2              
3 1     1   4 use base qw(Parse::Highlife::Token);
  1         2  
  1         61  
4 1     1   5 use Parse::Highlife::Utils qw(params extend_match);
  1         1  
  1         41  
5 1     1   4 use Data::Dump qw(dump);
  1         1  
  1         477  
6              
7             sub new
8             {
9 0     0 0   my( $class, @args ) = @_;
10 0           my $self = bless Parse::Highlife::Token->new( @args ), $class;
11 0           return $self -> _init( @args );
12             }
13              
14             sub _init
15             {
16 0     0     my( $self, $start, $end, $escape )
17             = params( \@_,
18             -start => '',
19             -end => '',
20             -escape => "\\",
21             );
22 0           $self->{'start'} = $start;
23 0           $self->{'end'} = $end;
24 0           $self->{'escape'} = $escape;
25 0           return $self;
26             }
27              
28             sub match
29             {
30 0     0 0   my( $self, $string, $offset ) = @_;
31 0 0         if( substr( $string, $offset, length $self->{'start'} ) eq $self->{'start'} ) {
32             # string starts with start sequence
33             # -> parse until end sequence is found
34 0           my $ended = 0;
35 0           my $c = $offset + length $self->{'start'}; # jump over start sequence
36 0           while( $c < length $string ) {
37 0           my $tail = substr $string, $c;
38 0 0         if( substr( $tail, 0, length $self->{'end'} ) eq $self->{'end'} ) {
39             # check if found end sequence is escaped
40 0           my $head = substr $string, 0, $c;
41            
42             # count appearences of end-sequence from current offset backwards
43 0           my $escapes = 0;
44 0           my $c2 = $c;
45 0           while( $c2 > 0 ) {
46 0           my $before = substr $string, 0, $c2;
47 0 0         if( substr( $before, - length $self->{'escape'} ) eq $self->{'escape'} ) {
48 0           $escapes ++;
49 0           $c2 -= length $self->{'escape'};
50 0           next;
51             }
52 0           last;
53             }
54              
55             # if number of escapes is even, they do not escape the current end-sequence
56 0 0         if( $escapes % 2 == 0 ) {
57 0           $c += length $self->{'end'}; # jump over end sequence
58 0           $ended = 1;
59 0           last;
60             }
61             }
62 0           $c++;
63             }
64 0 0         if( $ended ) {
65             #my $old = substr( $string, $offset, $c - $offset );
66 0           my $matched_substring = substr( $string, $offset, $c - $offset );
67             #print "($old) -> ($matched_substring)\n";
68 0           my $real_content = $matched_substring;
69 0           $real_content = substr( $real_content, length $self->{'start'} );
70 0           $real_content = substr( $real_content, 0, - length $self->{'end'} );
71             return
72 0           extend_match(
73             $string,
74             {
75             'token-classname' => ref $self,
76             'matched-substring' => $matched_substring,
77             'real-content' => $real_content,
78             'first-offset' => $offset,
79             }
80             );
81             }
82             }
83 0           return 0;
84             }
85              
86             1;