File Coverage

blib/lib/RDF/Notation3/Template/TReader.pm
Criterion Covered Total %
statement 74 89 83.1
branch 26 34 76.4
condition 2 3 66.6
subroutine 7 8 87.5
pod 0 2 0.0
total 109 136 80.1


line stmt bran cond sub pod time code
1 2     2   9 use strict;
  2         3  
  2         106  
2             #use warnings;
3              
4             package RDF::Notation3::Template::TReader;
5              
6             require 5.005_62;
7 2     2   19 use Carp;
  2         3  
  2         2432  
8              
9             ############################################################
10              
11              
12             sub get {
13 934     934 0 1091 my ($self) = @_;
14              
15 934 50       2029 unless ($self->{tokens}->[0]) {
16 0         0 $self->_more_tokens;
17             }
18              
19 934         1002 return shift @{$self->{tokens}};
  934         2359  
20             }
21              
22             sub try {
23 2303     2303 0 3842 my ($self) = @_;
24              
25 2303 100       5189 unless ($self->{tokens}->[0]) {
26 184         345 $self->_more_tokens;
27             }
28              
29 2303         6608 return $self->{tokens}->[0];
30             }
31              
32             sub _more_tokens {
33 184     184   264 my ($self) = @_;
34 184         454 $self->{currentline} = $self->_new_line;
35 184         301 my $line = \$self->{currentline};
36              
37 184 100       386 unless ($$line) {
38 10         11 push @{$self->{tokens}}, ' EOF ';
  10         24  
39 10         20 return;
40             }
41 174         187 while (1) {
42 1144 100       2653 last unless $$line;
43 970         911 my $token;
44 970 100       4574 if ( $$line =~ /^\"/ ) {
    100          
    50          
    50          
45 17         45 my $tok = $self->_get_string;
46 17         20 push @{$self->{tokens}}, $tok;
  17         75  
47             }
48             elsif ( $$line =~ /^\s+/ ) {
49 504         961 $$line = $';
50             }
51             # " is sticked to the previous character, such as ("
52             elsif ( $$line =~ /^([^\s\"]+)\"/ ) {
53 0         0 $$line = '"' . $';
54 0         0 push @{$self->{tokens}}, $1;
  0         0  
55             }
56             elsif ( $$line =~ /^(\S+)/ ) {
57 449         905 $$line = $';
58 449         9004 push @{$self->{tokens}}, $1;
  449         1246  
59             }
60             }
61 174         391 push @{$self->{tokens}}, ' EOL ';
  174         490  
62             }
63              
64             # returns a quoted string to be eval'ed
65             sub _get_string {
66 19     19   26 my $self = shift;
67 19         35 my $lineref = \$self->{currentline};
68              
69             # Handle escaped newlines
70 19         45 my $have_escaped_newlines = ($$lineref =~ /\\\n$/);
71              
72             # Check if it's a python string
73 19 100       51 if ( $$lineref =~ /^\"{3}/ ) {
74 3         14 return $self->_get_triple_quoted_string;
75             }
76              
77 16         77 my @parts = split /\"/, $$lineref;
78              
79             # First part should be empty
80 16         25 shift @parts;
81              
82 16         27 my $return = "";
83 16         23 my $part;
84 16         50 while ( $part = shift @parts ) {
85 16         25 $return .= $part;
86 16 100       49 last unless $return =~ /\\$/;
87 2         8 $return .= '"';
88             }
89              
90             # if chewed up everything and not ending in a quote
91 16 100 66     52 if ( @parts == 0 && $$lineref !~ /[^\\]\"$/) {
92              
93             # Escaped newlines should be ignored.
94 2 50       6 if ( $have_escaped_newlines ) {
95             # if there are more lines
96 2         8 my $line = $self->_new_line(1);
97 2 50       8 if ( $line ) {
98             # tack them on and try again.
99 2         6 $$lineref .= $line;
100 2         11 return $self->_get_string( $lineref );
101             }
102             }
103 0         0 $self->_do_error(111, $$lineref);
104             }
105 14         38 $$lineref = join '"', @parts;
106              
107 14         50 return "\"$return\"";
108             }
109              
110             sub _get_triple_quoted_string {
111 3     3   5 my $self = shift;
112 3         5 my $lineref = \$self->{currentline};
113 3 50       19 if ( $$lineref =~ /^\"{6}/ ) {
    100          
114 0         0 $$lineref = $';
115 0         0 return "\"\"";
116             }
117             elsif ( $$lineref =~ /^\"{3}(.*?[^\\])\"{3}/ ) {
118 1         3 $$lineref = $';
119 1         3 my $tok = $1;
120              
121             # quote unquoted double quotes
122 1         4 while ($tok =~ s/(^|[^\\])\"/$1\\\"/ ){}
123 1         5 return "\"$tok\"";
124             }
125 2         4 my $return = $$lineref;
126 2         7 my $line = "";
127 2         8 while ( $line = $self->_new_line(1) ) {
128 6 100       27 if ( $line =~ /^((.*?[^\\])?\"{3})/ ) {
129 2         6 $return .= $1;
130 2         5 $$lineref = $';
131              
132             # remove the surrounding quotes
133 2         7 $return =~ s/^\"{3}//;
134 2         9 $return =~ s/\"{3}$//;
135              
136             # Handle escaped newlines
137 2         6 $return =~ s/\\\n//g;
138              
139             # quote unquoted double quotes
140 2         30 while ($return =~ s/(^|[^\\])\"/$1\\\"/ ){}
141 2         11 return "\"$return\"";
142             }
143             else {
144 4         14 $return .= $line;
145             }
146             }
147             # Ran out of lines!
148 0           $self->_do_error(113, $return);
149             }
150              
151             sub _do_error {
152 0     0     my ($self, $n, $tk) = @_;
153              
154 0           my %msg = (
155             111 => 'string1 ("...") is not terminated',
156             113 => 'string2 ("""...""")is not terminated',
157             114 => 'string1 ("...") can\'t include newlines',
158             );
159              
160 0           my $msg = "[Error $n]";
161 0 0         $msg .= " line $self->{ln}, token" if $n > 100;
162 0           $msg .= " \"$tk\"\n";
163 0           $msg .= "$msg{$n}!\n";
164 0           croak $msg;
165             }
166              
167             1;
168              
169             __END__