File Coverage

/root/.cpan/build/Inline-0.54_02-wb8_n3/blib/lib/Inline/denter.pm
Criterion Covered Total %
statement 95 149 63.7
branch 18 56 32.1
condition 4 16 25.0
subroutine 12 16 75.0
pod 0 2 0.0
total 129 239 53.9


line stmt bran cond sub pod time code
1             package Inline::denter;
2              
3 1     1   5 use strict;
  1         1  
  1         26  
4 1     1   4 use Carp;
  1         1  
  1         63  
5 1     1   4 use AutoLoader 'AUTOLOAD';
  1         2  
  1         4  
6              
7             sub new {
8 1     1 0 115 my $class = shift;
9 1         11 bless {width => 4,
10             comma => " : ",
11             level => 0,
12             tabwidth => 8,
13             }, $class;
14             }
15              
16             # Prevent a taint exception being thrown by AutoLoader.pm.
17             # Serves no other purpose.
18       0     sub DESTROY {
19             }
20              
21             sub undent {
22 1     1 0 5 local $/ = "\n";
23 1         3 my ($o, $text) = @_;
24 1         7 my ($comma) = $o->{comma};
25 1         4 my $package = caller;
26 1 50       40 $package = caller(1) if $package eq 'Inline::denter';
27 1         1 %{$o->{xref}} = ();
  1         5  
28 1         3 @{$o->{objects}} = ();
  1         4  
29 1         2 @{$o->{context}} = ();
  1         7  
30 1         2 my $glob = '';
31 1         4 chomp $text;
32 1         14 @{$o->{lines}} = split $/, $text;
  1         11  
33 1         5 $o->{level} = 0;
34 1   50     9 $o->{line} ||= 1;
35 1         5 $o->_setup_line;
36 1         3 while (not $o->{done}) {
37 5 50 33     112 if ($o->{level} == 0 and
38             $o->{content} =~ /^(\w+)\s*$comma\s*(.*)$/) {
39 5         14 $o->{content} = $2;
40 1     1   187 no strict 'refs';
  1         2  
  1         1175  
41 5         6 push @{$o->{objects}}, "$1";
  5         56  
42             }
43 5         9 push @{$o->{objects}}, $o->_undent_data;
  5         15  
44             }
45 1         3 return @{$o->{objects}};
  1         62  
46             }
47              
48             sub _undent_data {
49 14     14   17 my $o = shift;
50 14         18 my ($obj, $class) = ('', '');
51 14         15 my @refs;
52             my %refs;
53 14         41 while ($o->{content} =~ s/^\\(?:\((\w+)\))?((\%|\@|\$|\\).*)/$2/) {
54 0         0 push @refs, $1;
55 0         0 $refs{$1} = scalar @refs;
56             }
57 14 100       58 if ($o->{content} =~ /^([\%\@\$])
    50          
58             (\w(?:\w|::)*)?
59             \s*$/x
60             ) {
61 4         6 my $foo;
62 4 0       14 $obj = ($1 eq '%') ? {} : ($1 eq '@') ? [] : \$foo;
    50          
63 4   50     20 $class = $2 || '';
64 4 50       9 if ($1 eq '%') {
    0          
65 4         10 %$obj = $o->_undent_hash;
66             }
67             elsif ($1 eq '@') {
68 0         0 @$obj = $o->_undent_array;
69             }
70             else {
71 0         0 $$obj = $o->_undent_scalar;
72             }
73 4 50       12 bless $obj, $class if length $class;
74             }
75             elsif ($o->{content} =~ /^\?\s*$/) {
76 0         0 $obj = $o->_undent_undef;
77             }
78             else {
79 10         19 $obj = $o->_undent_value;
80             }
81 14         40 while (@refs) {
82 0         0 my $ref = pop @refs;
83 0         0 my $copy = $obj;
84 0         0 $obj = \ $copy;
85 0 0       0 $o->{xref}{$ref} = $obj if $ref;
86             }
87 14         69 return $obj;
88             }
89              
90             sub _undent_value {
91 10     10   11 my $o = shift;
92 10         11 my $value = '';
93 10 50       30 if ($o->{content} =~ /^\<\<(\w+)(\-?)\s*$/) {
    50          
94 0         0 my ($marker, $chomp) = ($1, $2);
95 0         0 my $line = $o->{line};
96 0         0 $o->_next_line;
97 0   0     0 while (not $o->{done} and
98             $o->{lines}[0] ne $marker) {
99 0         0 $value .= $o->{lines}[0] . "\n";
100 0         0 $o->_next_line;
101             }
102 0 0       0 croak M03_no_value_end_marker($marker, $line) if $o->{done};
103 0 0       0 chomp $value if $chomp;
104             }
105             elsif ($o->{content} =~ /^\"/) {
106 0 0       0 croak $o->M04_mismatched_quotes unless $o->{content} =~ /^\".*\"\s*$/;
107 0         0 ($value = $o->{content}) =~ s/^\"|\"\s*$//g;
108             }
109             else {
110 10         14 $value = $o->{content};
111             }
112 10         21 $o->_next_line;
113 10         17 $o->_setup_line;
114 10         24 return $value;
115             }
116              
117             sub _undent_hash {
118 4     4   4 my @values;
119 4         5 my $o = shift;
120 4         6 my $level = $o->{level} + 1;
121 4         8 $o->_next_line;
122 4         14 $o->_setup_line;
123 4         12 while ($o->{level} == $level) {
124 9         132 my ($key, $value) = split $o->{comma}, $o->{content};
125 9 50 33     46 croak $o->M05_invalid_key_value unless (defined $key and defined $value);
126 9         29 $o->{content} = $value;
127 9         23 push @values, $o->_get_key($key), $o->_undent_data;;
128             }
129 4 50       12 croak $o->M06_invalid_indent_level if $o->{level} > $level;
130 4         24 return @values;
131             }
132              
133             sub _get_key {
134 9     9   15 my ($o, $key) = @_;
135 9 50       43 return $key unless $key =~ /^\<\<(\w+)(\-?)/;
136 0         0 my ($marker, $chomp) = ($1, $2);
137 0         0 $key = '';
138 0         0 my $line = $o->{line};
139 0         0 $o->_next_line;
140 0   0     0 while (not $o->{done} and
141             $o->{lines}[0] ne $marker) {
142 0         0 $key .= $o->{lines}[0] . "\n";
143 0         0 $o->_next_line;
144             }
145 0 0       0 croak M02_no_key_end_marker($marker, $line) if $o->{done};
146 0 0       0 chomp $key if $chomp;
147 0         0 $o->_next_line;
148 0         0 $o->_setup_line;
149 0         0 return $key;
150             }
151              
152             sub _undent_array {
153 0     0   0 my @values;
154 0         0 my $o = shift;
155 0         0 my $level = $o->{level} + 1;
156 0         0 $o->_next_line;
157 0         0 $o->_setup_line;
158 0         0 while ($o->{level} == $level) {
159 0         0 push @values, $o->_undent_data;
160             }
161 0 0       0 croak $o->M06_invalid_indent_level if $o->{level} > $level;
162 0         0 return @values;
163             }
164              
165             sub _undent_scalar {
166 0     0   0 my $values;
167 0         0 my $o = shift;
168 0         0 my $level = $o->{level} + 1;
169 0         0 $o->_next_line;
170 0         0 $o->_setup_line;
171 0 0       0 croak $o->M06_invalid_indent_level if $o->{level} != $level;
172 0 0       0 croak $o->M07_invalid_scalar_value if $o->{content} =~ /^[\%\@\$\\]/;
173 0 0       0 return $o->_undent_undef if $o->{content} =~ /^\?/;
174 0         0 return $o->_undent_value;
175             }
176              
177             sub _undent_undef {
178 0     0   0 my $o = shift;
179 0         0 $o->_next_line;
180 0         0 $o->_setup_line;
181 0         0 return undef;
182             }
183              
184             sub _next_line {
185 14     14   14 my $o = shift;
186 14 50       13 $o->{done}++, $o->{level} = -1, return unless @{$o->{lines}};
  14         35  
187 14         17 local $_ = shift @{$o->{lines}};
  14         28  
188 14         23 $o->{line}++;
189             }
190              
191             sub _setup_line {
192 15     15   21 my $o = shift;
193 15 100       13 $o->{done}++, $o->{level} = -1, return unless @{$o->{lines}};
  15         38  
194 14         19 my ($width, $tabwidth) = @{$o}{qw(width tabwidth)};
  14         25  
195 14         17 while (1) {
196 14         23 local $_ = $o->{lines}[0];
197             # expand tabs in leading whitespace;
198 14 50       59 $o->next_line, next if /^(\s*$|\#)/; # skip comments and blank lines
199 14         40 while (s{^( *)(\t+)}
200 0         0 {' ' x (length($1) + length($2) * $tabwidth -
201             length($1) % $tabwidth)}e){}
202 14 50       131 croak $o->M01_invalid_indent_width unless /^(( {$width})*)(\S.*)$/;
203 14         43 $o->{level} = length($1) / $width;
204 14         26 $o->{content} = $3;
205 14         35 last;
206             }
207             }
208              
209             1;
210             __END__