File Coverage

blib/lib/App/PTP/Util.pm
Criterion Covered Total %
statement 47 61 77.0
branch 4 12 33.3
condition 1 4 25.0
subroutine 14 20 70.0
pod 0 2 0.0
total 66 99 66.6


line stmt bran cond sub pod time code
1             # This module provides various helper function used throughout the program.
2              
3             package App::PTP::Util;
4              
5 20     20   362 use 5.022;
  20         80  
6 20     20   108 use strict;
  20         33  
  20         459  
7 20     20   100 use warnings;
  20         41  
  20         16364  
8              
9             # More or less the same as List::Util::uniqstr (or List::Util::uniq). Provided
10             # here because the List::Util function is not available in 5.22 by default.
11             sub uniqstr {
12 4     4 0 11 my ($content, $markers) = @_;
13 4         17 for my $i (0 .. $#$content - 1) {
14 18 100       48 if ($content->[$i] eq $content->[$i+1]) {
15 9         16 undef $content->[$i];
16 9         16 undef $markers->[$i];
17             }
18             }
19 4         15 @$content = grep { defined } @$content;
  22         44  
20 4         8 @$markers = grep { defined } @$markers;
  22         47  
21             }
22              
23             # Globally delete duplicate lines even if they are not contiguous. Keep the
24             # first occurence of each string.
25             sub globaluniqstr {
26 2     2 0 9 my ($content, $markers) = @_;
27 2         3 my %seen;
28 2         7 for my $i (0 .. $#$content) {
29 9 100       27 if ($seen{$content->[$i]}++) {
30 4         7 undef $content->[$i];
31 4         6 undef $markers->[$i];
32             }
33             }
34 2         8 @$content = grep { defined } @$content;
  9         21  
35 2         6 @$markers = grep { defined } @$markers;
  9         22  
36             }
37              
38             {
39             # A simple way to make a scalar be read-only.
40             package App::PTP::Util::ReadOnlyVar;
41             sub TIESCALAR {
42 100     100   180 my ($class, $value) = @_;
43 100         263 return bless \$value, $class;
44             }
45             sub FETCH {
46 109     109   2426 my ($self) = @_;
47 109         627 return $$self;
48             }
49             # Does nothing. We could warn_or_die, but it does not play well with the fact
50             # that we are inside the safe.
51       0     sub STORE {}
52             # Secret hidden methods for our usage only. These methods can't be used
53             # through the tie-ed variable, but only through the object returned by the
54             # call to tie.
55             sub set {
56 1214     1214   2219 my ($self, $value) = @_;
57 1214         2417 $$self = $value;
58             }
59             sub get {
60 0     0   0 my ($self, $value) = @_;
61 0         0 return $$self;
62             }
63             sub inc {
64 146     146   349 my ($self) = @_;
65 146         632 ++$$self;
66             }
67             }
68              
69             {
70             # A simple way to make a scalar be an alias of another one (but does not allow
71             # to store undef in the variable as this is used to mark non-existant lines
72             # in some function and this package is tied to the marker variable).
73             package App::PTP::Util::AliasVar;
74             sub TIESCALAR {
75 20     20   52 my ($class) = @_;
76 20         41 my $var;
77 20         55 return bless \$var, $class;
78             }
79             sub FETCH {
80 18     18   31 my ($self) = @_;
81 18         56 return $$$self;
82             }
83             sub STORE {
84 5     5   10 my ($self, $value) = @_;
85             # This empty string is also the value that is set in do_perl when the marker
86             # is undef (this is not the same as the default 0 that is put when the array
87             # is built).
88 5   50     19 $$$self = $value // '';
89             }
90             # Secret hidden methods for our usage only. These methods can't be used
91             # through the tie-ed variable, but only through the object returned by the
92             # call to tie.
93             sub set {
94 568     568   992 my ($self, $ref) = @_;
95 568         1071 $$self = $ref;
96             }
97             }
98              
99             {
100             # A fake array that returns the marker at a given offset from the current
101             # line (and refuses to store undef in the array).
102             package App::PTP::Util::MarkersArray;
103             our $NEGATIVE_INDICES = 1;
104             sub TIEARRAY {
105 20     20   81 my ($class, $markers, $n) = @_;
106 20         55 my $this = [$markers, $n];
107 20         89 return bless $this, $class;
108             }
109             sub FETCH {
110 0     0     my ($self, $offset) = @_;
111 0           my $index = ($$self->[1] - 1 + $offset);
112 0 0         return 0 if $index < 0;
113 0 0         return 0 if $index >= $self->FETCHSIZE();
114 0           return $self->[0][$index];
115             }
116             sub FETCHSIZE {
117 0     0     my ($self) = @_;
118 0           return scalar(@App::PTP::Commands::markers);
119             }
120             sub STORE {
121 0     0     my ($self, $offset, $value) = @_;
122 0           my $index = ($$self->[1] - 1 + $offset);
123 0 0         return $value if $index < 0;
124 0 0         return $value if $index >= $self->FETCHSIZE();
125 0   0       $self->[0][$index] = $value // ''; # make it more difficult to store undef
126             }
127       0     sub STORESIZE {}
128             }
129              
130             1;