File Coverage

lib/Text/FixEOL.pm
Criterion Covered Total %
statement 149 149 100.0
branch 64 64 100.0
condition 14 15 93.3
subroutine 17 17 100.0
pod 13 13 100.0
total 257 258 99.6


line stmt bran cond sub pod time code
1             package Text::FixEOL;
2              
3 1     1   52231 use strict;
  1         4  
  1         5692  
4              
5             $Text::FixEOL::VERSION = '1.06';
6              
7             ##########################################################################################
8              
9             sub DEBUG () { 0; }
10              
11             ##########################################################################################
12              
13             my %_Platform_Defaults = (
14             lf => {
15             'fixlast' => 'no',
16             'eof' => 'asis',
17             'eol' => "\012",
18             },
19             cr => {
20             'fixlast' => 'no',
21             'eof' => 'asis',
22             'eol' => "\015",
23             },
24             crlf => {
25             'fixlast' => 'no',
26             'eof' => 'asis',
27             'eol' => "\015\012",
28             },
29             asis => {
30             'fixlast' => 'no',
31             'eof' => 'asis',
32             'eol' => "asis",
33             },
34             network => {
35             'fixlast' => 'yes',
36             'eof' => 'remove',
37             'eol' => "\015\012",
38             },
39             mac => {
40             'fixlast' => 'yes',
41             'eof' => 'remove',
42             'eol' => "\015",
43             },
44             macos => {
45             'fixlast' => 'yes',
46             'eof' => 'remove',
47             'eol' => "\015",
48             },
49             windows => {
50             'fixlast' => 'yes',
51             'eof' => 'asis',
52             'eol' => "\015\012",
53             },
54             mswin32 => {
55             'fixlast' => 'yes',
56             'eof' => 'asis',
57             'eol' => "\015\012",
58             },
59             os2 => {
60             'fixlast' => 'yes',
61             'eof' => 'asis',
62             'eol' => "\015\012",
63             },
64             vms => {
65             'fixlast' => 'yes',
66             'eof' => 'remove',
67             'eol' => "\015\012",
68             },
69             netware => {
70             'fixlast' => 'yes',
71             'eof' => 'asis',
72             'eol' => "\015\012",
73             },
74             dos => {
75             'fixlast' => 'yes',
76             'eof' => 'asis',
77             'eol' => "\015\012",
78             },
79             cygwin => {
80             'fixlast' => 'yes',
81             'eof' => 'asis',
82             'eol' => "\015\012",
83             },
84             unix => {
85             'fixlast' => 'yes',
86             'eof' => 'remove',
87             'eol' => "\012",
88             },
89             'unknown' => {
90             'fixlast' => 'yes',
91             'eof' => 'remove',
92             'eol' => "\n",
93             },
94             );
95              
96             ##########################################################################################
97              
98             sub new {
99 322     322 1 16599 my $proto = shift;
100 322         404 my $proto_ref = ref($proto);
101 322         327 my $package = __PACKAGE__;
102 322         312 my $class;
103 322 100       501 if ($proto_ref) { $class = $proto_ref; }
  296 100       386  
104 25         36 elsif ($proto) { $class = $proto; }
105 1         1 else { $class = $package; }
106 322         599 my $self = bless {},$class;
107              
108 322         582 $self->eol_handling('platform');
109 322         529 $self->eof_handling('platform');
110 322         490 $self->fix_last_handling('platform');
111              
112 322         416 my %raw_properties = ();
113 322 100       671 if (1 < @_) { %raw_properties = @_; }
  4 100       13  
114             elsif (1 == @_) {
115 301         279 my $parm = shift;
116 301         349 my $parm_type = ref($parm);
117 301 100       417 if ($parm_type eq 'HASH') {
118 300         1135 %raw_properties = %$parm;
119             } else {
120 1         4 require Carp;
121 1         85 Carp::croak("${package}::new() - Unexpected parameter type passed to constructor: $parm_type");
122             }
123             } else {
124 17         42 return $self;
125             }
126              
127 304         623 my %properties = map { lc($_) => $raw_properties{$_} } keys %raw_properties;
  900         2165  
128              
129 304 100       806 if ($properties{'eol'}) {
130 302         562 $self->eol_handling($properties{'eol'});
131 302         451 delete $properties{'eol'};
132             }
133 304 100       505 if ($properties{'eof'}) {
134 298         498 $self->eof_handling($properties{'eof'});
135 298         448 delete $properties{'eof'};
136             }
137 304 100       545 if ($properties{'fixlast'}) {
138 298         516 $self->fix_last_handling($properties{'fixlast'});
139 298         388 delete $properties{'fixlast'};
140             }
141 304         415 my @extra_properties = keys %properties;
142 304 100       572 if (0 < @extra_properties) {
143 2         16 require Carp;
144 2         292 Carp::croak("${package}::new() - Unexpected attributes passed: " . join(', ',sort @extra_properties) . "\n");
145             }
146              
147 302         1091 return $self;
148             }
149              
150             ##########################################################################################
151              
152             sub eol_to_unix {
153 59     59 1 344 my $self = shift;
154              
155 59         225 my $to_unix = $self->new({
156             'EOL' => 'unix',
157             'EOF' => 'unix',
158             'FixLast' => 'unix',
159             })->fix_eol(@_);
160 59         259 return $to_unix;
161             }
162              
163             ##########################################################################################
164              
165             sub eol_to_dos {
166 59     59 1 529 my $self = shift;
167              
168 59         222 my $to_dos = $self->new({
169             'EOL' => 'dos',
170             'EOF' => 'dos',
171             'FixLast' => 'dos',
172             })->fix_eol(@_);
173 59         262 return $to_dos;
174             }
175              
176             ##########################################################################################
177              
178             sub eol_to_mac {
179 59     59 1 511 my $self = shift;
180              
181 59         240 my $to_mac = $self->new({
182             'EOL' => 'mac',
183             'EOF' => 'mac',
184             'FixLast' => 'mac',
185             })->fix_eol(@_);
186 59         248 return $to_mac;
187             }
188              
189             ##########################################################################################
190              
191             sub eol_to_network {
192 59     59 1 520 my $self = shift;
193              
194 59         220 my $to_network= $self->new({
195             'EOL' => 'network',
196             'EOF' => 'network',
197             'FixLast' => 'yes',
198             })->fix_eol(@_);
199 59         239 return $to_network;
200             }
201              
202             ##########################################################################################
203              
204             sub eol_to_crlf {
205 59     59 1 547 my $self = shift;
206              
207 59         211 my $to_crlf = $self->new({
208             'EOL' => 'crlf',
209             'EOF' => 'remove',
210             'FixLast' => 'yes',
211             })->fix_eol(@_);
212 59         233 return $to_crlf;
213             }
214              
215             ##########################################################################################
216              
217             sub fix_eol {
218 424     424 1 1289 my $self = shift;
219              
220 424 100       730 unless (1 == @_) {
221 2         11 require Carp;
222 2         3 my $package = __PACKAGE__;
223 2         182 Carp::croak("${package}::fix_eol() - Incorrect number of parameters passed. One string (only) is required.");
224             }
225              
226 422         452 my ($string) = @_;
227 422         686 my $eol_mode = $self->eol_mode;
228 422 100       731 if ($eol_mode ne 'asis') {
229 363         678 $string = $self->_eol_to_base_lf($string);
230             }
231 422         821 my $fix_last = $self->fix_last_mode;
232 422 100       748 if ($fix_last eq 'yes') {
233 421         463 my $old_eof = '';
234 421 100       812 if ($string =~ s/(\032+)$//s) { # \032 is Ctrl-Z
235 6         10 $old_eof = "\032";
236             }
237 421 100 100     1360 if (($string ne '') and ($eol_mode ne 'asis')) {
238 358 100       1159 if ($string !~ m/\012$/s) {
239 4         7 $string .= "\012";
240             }
241              
242             } else {
243 63 100       118 if ($eol_mode ne 'asis') {
244 4         5 $string = "\012";
245             }
246             }
247 421         698 $string .= $old_eof;
248             }
249              
250 422         735 my $eof_handling = $self->eof_mode;
251 422 100 100     833 if ($eof_handling eq 'remove') {
    100          
252 357         446 $string =~ s/\032+$//s;
253              
254             } elsif (($eof_handling eq 'add') and ($string !~ m/\032$/s)) {
255 2         3 $string .= "\032";
256             }
257              
258 422 100       662 if ($eol_mode ne 'asis') {
259 363         361 my $eol_replacement = $eol_mode;
260 363         1091 $string =~ s/\012/$eol_replacement/gs;
261             }
262 422         855 return $string;
263             }
264              
265             ##########################################################################################
266              
267             sub eol_mode {
268 426     426 1 404 my $self = shift;
269 426         714 my $eol_handling = $self->eol_handling;
270              
271 426 100       761 if ($eol_handling =~ m/^literal:(.+)$/s) {
272 59         147 return $1;
273              
274             } else {
275 367         632 my $default_eol = $self->_platform_defaults($eol_handling, 'EOL');
276 367         605 return $default_eol;
277             }
278             }
279              
280             ##########################################################################################
281              
282             sub eof_mode {
283 422     422 1 472 my $self = shift;
284              
285 422         588 my $eof_handling = $self->eof_handling;
286 422         764 my $default_eof = $self->_platform_defaults($eof_handling, 'EOF');
287 422         688 return $default_eof;
288             }
289              
290             ##########################################################################################
291              
292             sub fix_last_mode {
293 422     422 1 455 my $self = shift;
294              
295 422         723 my $fix_last = $self->fix_last_handling;
296 422         762 my $fix_last_mode = $self->_platform_defaults($fix_last, 'FixLast');
297 422         662 return $fix_last_mode;
298             }
299              
300             ##########################################################################################
301              
302             sub _platform_defaults {
303 1212     1212   1261 my $self = shift;
304 1212         1180 my $package = __PACKAGE__;
305              
306 1212         1475 my ($platform_name, $property) = @_;
307              
308 1212         1331 $platform_name = lc ($platform_name);
309 1212         1131 $property = lc ($property);
310              
311 1212 100 100     4308 return $platform_name if (($property eq 'fixlast') and ($platform_name =~ m/^(yes|no)$/));
312 1085 100 100     3173 return $platform_name if (($property eq 'eof') and ($platform_name =~ m/^(asis|remove|add)$/));
313              
314 1017 100       1672 if ($platform_name eq 'platform') {
315 236         383 $platform_name = lc ($^O);
316             }
317              
318 1017         1292 my $platform_defaults = $_Platform_Defaults{$platform_name};
319 1017 100       1521 unless (defined ($platform_defaults)) {
320 236         298 $platform_defaults = $_Platform_Defaults{'unknown'};
321             }
322 1017         1290 my $property_value = $platform_defaults->{$property};
323 1017 100       1549 unless (defined ($property_value)) {
324 1         13 require Carp;
325 1         148 Carp::croak("${package}::_platform_defaults() - Unknown property of $property");
326             }
327 1016         1782 return $property_value;
328             }
329              
330             ##########################################################################################
331              
332             sub _eol_to_base_lf {
333 363     363   345 my $self = shift;
334              
335 363         403 my ($string) = @_;
336              
337             # Undef converts to ''
338 363 100       555 return '' unless (defined $string);
339              
340             # If there are not any DOS EOLs (\015 characters), return the original string
341 362 100       772 return $string unless ($string =~ m/\015/s);
342              
343             # If there is nothing except DOS EOL, convert them to \012 directly
344 330 100       659 if ($string !~ m/\012/s) {
345 24         66 $string =~ s/\015/\012/gs;
346 24         51 return $string;
347             }
348              
349             # If the EOLs are all 'singletons', do in-place cleanup of the DOS EOLs
350 306 100 66     772 if (($string !~ m/\015\012/s) and ($string !~ m/\012\015/s)) {
351 36         85 $string =~ s/\015/\012/gs;
352 36         80 return $string;
353             }
354              
355 270         1304 my @eols = $string =~ m/([\012\015]+)/sg;
356 270         373 my %replacement_map = ();
357 270         348 foreach my $eol_mode (@eols) {
358 762 100       1586 next if (defined $replacement_map{$eol_mode});
359 378         370 my $replace_with = $eol_mode;
360 378         990 $replace_with =~ s/(\015\012|\012\015)/\012/gs;
361 378         638 $replace_with =~ s/\015/\012/gs;
362 378         872 $replacement_map{$eol_mode} = $replace_with;
363             }
364 270         870 $string =~ s/([\012\015]+)/$replacement_map{$1}/gse;
  762         2131  
365              
366 270         972 return $string;
367             }
368              
369             ##########################################################################################
370              
371 1064     1064 1 2141 sub eol_handling { return shift->_property('eol_handling', @_); }
372 1055     1055 1 1926 sub eof_handling { return shift->_property('eof_handling', @_); }
373 1056     1056 1 1966 sub fix_last_handling { return shift->_property('fix_last_handling', @_); }
374              
375             ##########################################################################################
376             # _property('property_name' => $property_value)
377             #
378             # get/set base accessor for property values
379              
380             sub _property {
381 3176     3176   3182 my $self = shift;
382              
383 3176         2954 my $property = shift;
384              
385 3176         2911 my $package = __PACKAGE__;
386 3176 100       5843 if (0 == @_) {
    100          
387 1290         1980 my $output = $self->{$package}->{$property};
388 1290         2574 return $output;
389              
390             } elsif (1 == @_) {
391 1885         1837 my $input = shift;
392 1885         3379 $self->{$package}->{$property} = $input;
393 1885         2972 return;
394             } else {
395 1         5 die ("Bad calling parameters to ${package}::${property}()\n");
396             }
397             }
398              
399             ##########################################################################################
400              
401             1;