File Coverage

blib/lib/Data/MaskPrint.pm
Criterion Covered Total %
statement 157 173 90.7
branch 81 96 84.3
condition 43 60 71.6
subroutine 6 6 100.0
pod 2 2 100.0
total 289 337 85.7


line stmt bran cond sub pod time code
1             #!/usr/local/bin/perl -wc
2              
3             package Data::MaskPrint;
4 1     1   797 use vars qw($myself @ISA $VERSION);
  1         2  
  1         97  
5             $VERSION = "1.0";
6 1     1   5 use Exporter();
  1         2  
  1         29  
7             @ISA = qw(Exporter);
8              
9              
10 1     1   5 use strict;
  1         12  
  1         38  
11 1     1   6 use Carp;
  1         2  
  1         3381  
12              
13             sub new ()
14             {
15 1     1 1 59 my $class = shift;
16 1         4 my $self=[];
17 1         5 bless $self, $class;
18             }
19              
20             sub num_mask_print($$$)
21             {
22 118     118 1 3852 my $this = shift;
23 118         136 my $data = shift;
24 118         149 my $mask = shift;
25              
26              
27             #defines follow
28 118         412 my $PAREN = 0;
29 118         112 my $PLUS = 0;
30 118         117 my $MINUS = 0;
31 118         171 my $DOLLAR = 0;
32 118         106 my $DECIMAL= 0;
33 118         171 my $NEGATIVE = 0;
34 118         175 my $SUPRESS_LEAD_SPACE = 0;
35            
36              
37 118         114 my @fmt_pic;
38              
39 118 100       521 $DOLLAR = 1 if ($mask =~ /\$/);
40 118 100 66     619 $MINUS = 1 if (($mask =~ /-/) || ($mask =~ /\+/));
41 118 50       227 $PLUS = 1 if ($mask =~ /\+/);
42              
43 118 100       284 if ($mask =~ /
44             {
45 5         18 $mask =~ s/
46 5         7 $SUPRESS_LEAD_SPACE = 1;
47             }
48              
49 118 50       447 if ($mask =~ /\..*\./)
    100          
50             {
51 0         0 croak "Only one decimal point is permitted in the mask (Picture)";
52             }
53             elsif ($mask =~ /\./)
54             {
55 84         105 $DECIMAL = 1;
56             }
57              
58 118 50       315 if ($mask =~ /\).*\)/)
    100          
59             {
60 0         0 croak "Only one ) is permitted in the mask (Picture)";
61             }
62             elsif ($mask =~ /\)/)
63             {
64 28         33 $PAREN = 1;
65             }
66              
67 118 50 66     701 if ((($mask =~ /\(/) && !$PAREN) || ($PAREN && !($mask =~ /\(/)))
      66        
      33        
68             {
69 0         0 croak "Parenthesis does not match in the mask (Picture)";
70             }
71              
72 118 50 33     357 if (($PAREN) && ($MINUS || $PLUS))
      66        
73             {
74 0         0 croak "Mask (Picture) formatted incorrectly cannot have both parenthesis and -/+ sign";
75             }
76              
77              
78 118 100       299 if ($data >= 0)
79             {
80 78 100       127 if ($PAREN)
81             {
82 14         28 $mask =~ s/\)//g;
83 14         26 $mask = '#' . $mask;
84 14         48 $mask =~ s/\(/\#/g;
85 14         17 $SUPRESS_LEAD_SPACE = 1;
86             }
87 78         153 $mask =~ s/-/\#/g;
88             }
89             else
90             {
91 40         46 $NEGATIVE = 1;
92 40 50       152 if ($PLUS)
93             {
94 0         0 $mask =~ s/\+/-/g;
95             }
96 40         356 $data =~ s/-//;
97             }
98              
99 118 100       312 if (!$DECIMAL)
100             {
101 34         83 $data =~ s/\..*$//;
102             }
103              
104             #preparing mask array
105 118         438 for(my $i = 0; $i < length($mask); $i++)
106             {
107 1092         3062 $fmt_pic[$i] = substr($mask, $i, 1);
108             }
109              
110             #checking if the data will fit into the space provided by the mask
111 118         719 my @arr = split(/\./, $data);
112 118         351 my @arr2 = split(/\./, $mask);
113 118         318 $arr2[0] =~ s/,//g;
114 118         169 my $count = length($arr2[0]);
115 118 100 100     544 $count-- if ($PAREN || $MINUS || $PLUS);
      66        
116 118 100       205 $count-- if ($DOLLAR);
117 118 100       228 return '*' x length($mask) if (length($arr[0]) > $count);
118              
119              
120             #processing right side of the mask
121 114         140 my $DECIMAL_POS_MASK = length($mask);
122 114         198 my $DECIMAL_POS_DATA = length($data);
123 114 100       198 if ($DECIMAL)
124             {
125 81         114 $DECIMAL_POS_MASK = index($mask, '.');
126 81 100       326 if ($data =~ /\./)
127             {
128 74         159 $DECIMAL_POS_DATA = index($data, '.');
129             }
130             else
131             {
132 7         10 $DECIMAL_POS_DATA = length($data);
133             }
134 81         220 for(my $i = $DECIMAL_POS_MASK, my $j = $DECIMAL_POS_DATA;
135             $i < scalar(@fmt_pic);
136             $i++)
137             {
138 257         343 my $num = undef;
139 257 100       992 if ($j < length($data))
140             {
141 222         640 $num = substr($data, $j, 1);
142 222         258 $j++;
143             }
144            
145 257   66     1138 while(($fmt_pic[$i] eq ')') || ($fmt_pic[$i] eq ','))
146             {
147 14         150 $i++;
148             }
149 257 100       535 last if !defined($fmt_pic[$i]);
150              
151 243         425 foreach ($fmt_pic[$i])
152             {
153             /\*/ && do
154 243 50       701 {
155 0 0       0 if (defined($num))
156             {
157 0         0 $fmt_pic[$i] = $num;
158             }
159             else
160             {
161 0         0 $fmt_pic[$i] = '*';
162             }
163             };
164             /\$|#|-|\&/ && do
165 243 100       1479 {
166 162 100       344 if (defined($num))
167             {
168 148         746 $fmt_pic[$i] = $num;
169             }
170             else
171             {
172 14         184 $fmt_pic[$i] = 0;
173             }
174             };
175             }
176             }
177             }
178              
179             #Processing left side of mask here(side to re left of .)
180             #Right side should already be processed if there is no right side
181             #just process the rest of mask
182 114         234 my $i;
183 114         290 for($i = $DECIMAL_POS_MASK - 1, my $j = $DECIMAL_POS_DATA - 1;
184             $j >= 0 ;
185             $j--, $i--)
186             {
187 300         768 my $num = substr($data, $j, 1);
188            
189 300   66     1274 while(($fmt_pic[$i] eq ')') || ($fmt_pic[$i] eq ','))
190             {
191 37         147 $i--;
192             }
193 300 50       692 last if ($i < 0);
194              
195 300 100 66     1319 if (($fmt_pic[$i] eq '$') ||
196             ($fmt_pic[$i] eq '('))
197             {
198 145         475 for(my $k = $i - 1; $k >= 0; $k--)
199             {
200 175 100       337 next if ($fmt_pic[$k] eq ',');
201 145         176 $fmt_pic[$k] = $fmt_pic[$i];
202 145         188 last;
203             }
204             }
205 300         2847 $fmt_pic[$i] = $num;
206             }
207              
208             #Processing leftover string afetr all numbers have been processed
209 114         204 my $HAD_DOLLAR = 0;
210 114         271 my $HAD_SIGN = 0;
211 114         109 my $HAD_PAREN = 0;
212 114         118 my $HAD_STAR = 0;
213              
214 114         298 for( ; $i >= 0; $i--)
215             {
216 638         974 foreach ($fmt_pic[$i])
217             {
218 638 100 100     2331 if (($NEGATIVE) && !($HAD_SIGN) && !($PAREN) && !($MINUS))
      100        
      100        
219             {
220 3         4 $fmt_pic[$i] = '-';
221 3         4 $HAD_SIGN = 1;
222 3         13 next;
223             }
224             /\*/ && do
225 635 100       1286 {
226             #Let it be
227             };
228             /\,/ && do
229 635 100       1823 {
230 72 50       127 if ($i > 0)
    0          
231             {
232 72         177 $fmt_pic[$i] = $fmt_pic[$i - 1];
233 72         69 $i++;
234 72         271 next;
235             }
236             elsif ($fmt_pic[$i + 1] =~ /[0-9]/)
237             {
238 0         0 $fmt_pic[$i] = ' ';
239             }
240             else
241             {
242 0         0 $fmt_pic[$i] = $fmt_pic[$i + 1];
243 0         0 $i++;
244 0         0 next;
245             }
246             };
247             /\&/ && do
248 563 100       1035 {
249 31         52 $fmt_pic[$i] = 0;
250             };
251             /\$/ && do
252 563 100       1429 {
253 118 100       227 if ($HAD_DOLLAR)
254             {
255 61 100       92 if ($i > 0)
256             {
257 54         72 my $symbol = '#';
258 54         116 for(my $k = $i - 1; $k >= 0; $k--)
259             {
260 110 100 100     584 if (($fmt_pic[$k] eq '$') ||
      100        
261             ($fmt_pic[$k] eq ',') ||
262             ($fmt_pic[$k] eq '('))
263             {
264 87         1666 next;
265             }
266             else
267             {
268 23         39 $symbol = $fmt_pic[$k];
269 23         30 last;
270             }
271             }
272 54         69 $fmt_pic[$i] = $symbol;
273             #This is to reprocess this symbol again
274 54         54 $i++;
275 54         191 next;
276             }
277             else
278             {
279 7         11 $fmt_pic[$i] = ' ';
280             }
281             }
282             else
283             {
284 57         63 $HAD_DOLLAR = 1;
285 57         86 $fmt_pic[$i] = '$';
286             }
287             };
288             /\#/ && do
289 509 100       1184 {
290 260         356 $fmt_pic[$i] = ' ';
291             };
292             /\(/ && do
293 509 100       1072 {
294 35 100       66 if ($HAD_PAREN)
295             {
296 21         22 $SUPRESS_LEAD_SPACE = 1;
297 21 100       31 if ($i > 0)
298             {
299 12         17 my $symbol = '#';
300 12         29 for(my $k = $i - 1; $k >= 0; $k--)
301             {
302 27 50 33     68 if (($fmt_pic[$k] eq '(') ||
      33        
303             ($fmt_pic[$k] eq ',') ||
304             ($fmt_pic[$k] eq '$'))
305             {
306 27         56 next;
307             }
308             else
309             {
310 0         0 $symbol = $fmt_pic[$k];
311 0         0 last;
312             }
313             }
314 12         15 $fmt_pic[$i] = $symbol;
315             #This is to reprocess this symbol again
316 12         12 $i++;
317 12         52 next;
318             }
319             else
320             {
321 9         14 $fmt_pic[$i] = ' ';
322             }
323             }
324             else
325             {
326 14         46 $HAD_PAREN = 1;
327 14         20 $fmt_pic[$i] = '(';
328             }
329             };
330             /-|\+/ && do
331 497 100       2766 {
332 73 100       119 if ($HAD_SIGN)
333             {
334 52 100       111 if ($i > 0)
335             {
336 37         43 my $symbol = '#';
337 37         82 for(my $k = $i - 1; $k >= 0; $k--)
338             {
339 79 50 100     399 if (($fmt_pic[$k] eq $_) ||
      66        
340             ($fmt_pic[$k] eq ',') ||
341             ($fmt_pic[$k] eq '$'))
342             {
343 79         152 next;
344             }
345             else
346             {
347 0         0 $symbol = $fmt_pic[$k];
348 0         0 last;
349             }
350             }
351 37         51 $fmt_pic[$i] = $symbol;
352             #This is to reprocess this symbol again
353 37         35 $i++;
354 37         258 next;
355             }
356             else
357             {
358 15         55 $fmt_pic[$i] = ' ';
359             }
360             }
361             else
362             {
363 21         24 $HAD_SIGN = 1;
364 21         77 $fmt_pic[$i] = $_;
365             }
366             };
367             }
368             }
369              
370 114         295 my $pic = join("", @fmt_pic);
371 114 100       309 $pic =~ s/^\s+// if ($SUPRESS_LEAD_SPACE);
372 114         746 return $pic;
373             }
374              
375             1;
376             __END__;