File Coverage

lib/Date/Manip/Obj.pm
Criterion Covered Total %
statement 154 167 93.4
branch 64 68 95.5
condition 15 18 83.3
subroutine 22 23 95.6
pod 14 14 100.0
total 269 290 93.7


line stmt bran cond sub pod time code
1             package Date::Manip::Obj;
2             # Copyright (c) 2008-2022 Sullivan Beck. All rights reserved.
3             # This program is free software; you can redistribute it and/or modify it
4             # under the same terms as Perl itself.
5              
6             ########################################################################
7             ########################################################################
8              
9             require 5.010000;
10 168     168   1101 use warnings;
  168         344  
  168         5908  
11 168     168   876 use strict;
  168         340  
  168         5355  
12 168     168   1280 use IO::File;
  168         272  
  168         24619  
13 168     168   102063 use Storable qw(dclone);
  168         550789  
  168         10686  
14 168     168   1243 use Carp;
  168         358  
  168         289589  
15              
16             our ($VERSION);
17             $VERSION='6.90';
18 168     168   0 END { undef $VERSION; }
19              
20             ########################################################################
21             # METHODS
22             ########################################################################
23              
24             my %classes = ( 'Date::Manip::Base' => 1,
25             'Date::Manip::TZ' => 1,
26             'Date::Manip::Date' => 1,
27             'Date::Manip::Delta' => 1,
28             'Date::Manip::Recur' => 1,
29             );
30              
31             sub new {
32 21227     21227 1 134088 my(@args) = @_;
33 21227         35831 my(@allargs) = @args;
34              
35             # $old is the object (if any) being used to create a new object
36             # $new is the new object
37             # $class is the class of the new object
38             # $tz is a Date::Manip::TZ object to base the new object on
39             # (only for Date, Delta, Recur objects)
40             # $base is the Date::Manip::Base object to base the new object on
41             # @opts options to pass to config method
42              
43 21227         33756 my($old,$new,$class,$tz,$base,@opts);
44              
45             # Get the class of the new object
46              
47 21227 100       45015 if (exists $classes{ $args[0] }) {
48              
49             # $obj = new CLASS
50 21214         34146 $class = shift(@args);
51              
52             } else {
53              
54             # $obj->new
55 13         21 $class = ref($args[0]);
56             }
57              
58             # Find out if there are any config options (which will be the
59             # final argument).
60              
61 21227 100 100     88847 if (@args && ref($args[$#args]) eq 'ARRAY') {
62 16         29 @opts = @{ pop(@args) };
  16         70  
63             }
64              
65             # Get an old object
66              
67 21227 100       86693 if (ref($args[0]) =~ /^Date::Manip/) {
68             # $old->new
69             # new CLASS $old
70 19777         33912 $old = shift(@args);
71             }
72              
73             # Additional arguments will be passed to parse.
74              
75             ########################
76              
77             # Get Base/TZ objects from an existing object
78              
79 21227 100       44591 if ($old) {
80 19777 100       48703 if (ref($old) eq 'Date::Manip::Base') {
    100          
81 17         28 $base = $old;
82             } elsif (ref($old) eq 'Date::Manip::TZ') {
83 3         11 $tz = $old;
84 3         5 $base = $$tz{'base'};
85              
86             # *** I think this is useless code, deprecate
87             # } elsif (ref($old) eq 'ARRAY') {
88             # my %old = @$old;
89             # $tz = $old{'tz'};
90             # $base = $$tz{'base'};
91              
92             } else {
93 19757         32834 $tz = $$old{'tz'};
94 19757         30199 $base = $$tz{'base'};
95             }
96             }
97              
98             # Create a new empty object.
99              
100             $new = {
101 21227         63890 'data' => {},
102             'err' => '',
103             };
104              
105             # Create Base/TZ objects if necessary
106              
107 21227 100 100     72022 if ($base && @opts) {
108 13         28 $base = _clone($base);
109 13 100       60 $tz = new Date::Manip::TZ $base if ($tz);
110             }
111              
112 21227         33665 my $init = 1;
113 21227 100       49765 if ($class eq 'Date::Manip::Base') {
    100          
114 503 100       1793 if ($base) {
115             # new Date::Manip::Base $base
116             #
117             # We have to clone it (which we already did if @opts was given)
118             #
119 4 100       11 if (@opts) {
120 2         5 $new = $base;
121             } else {
122 2         6 $new = _clone($base);
123             }
124 4         7 $init = 0;
125             }
126              
127             } elsif ($class eq 'Date::Manip::TZ') {
128 512 100       2569 if ($tz) {
    100          
129             # new Date::Manip::TZ $tz
130 3 100       9 if (@opts) {
131 2         5 $new = $tz;
132             } else {
133 1         3 $new = _clone($tz);
134             }
135 3         6 $init = 0;
136             } elsif (! $base) {
137 496         3329 $base = new Date::Manip::Base;
138             }
139 512         3084 $$new{'base'} = $base;
140              
141             } else {
142 20212 100       38928 if (! $tz) {
143 456 100       1142 if ($base) {
144 1         3 $tz = new Date::Manip::TZ $base;
145             } else {
146 455         3063 $tz = new Date::Manip::TZ;
147             }
148             }
149 20212         35599 $$new{'tz'} = $tz;
150             }
151              
152 21227         41779 $$new{'args'} = [ @args ];
153 21227         39048 bless $new,$class;
154              
155 21227 100       82644 $new->_init() if ($init);
156 21227 100       48001 $new->config(@opts) if (@opts);
157 21227 100       40602 $new->_init_args() if (@args);
158 21227         57860 $new->_init_final();
159 21227         60938 return $new;
160             }
161              
162             # This clones an object. Currently, it only clones a Base or TZ
163             # object, but dclone can't handle stored regexps so we have to copy
164             # them manually.
165             #
166             sub _clone {
167 16     16   58 my($obj) = @_;
168              
169 16 100       36 if (ref($obj) eq 'Date::Manip::Base') {
170              
171 15         28 my $tmp = $$obj{'data'}{'rx'};
172 15         30 delete $$obj{'data'}{'rx'};
173 15         9021 my $new = dclone($obj);
174 15         67 $$obj{'data'}{'rx'} = $tmp;
175 15         27 $$new{'data'}{'rx'} = $tmp;
176 15         50 return $new;
177              
178             } else {
179              
180 1         4 my $base = $$obj{'base'};
181 1         3 delete $$obj{'base'};
182              
183 1         4 my @rx = qw(namerx zonerx abbrx offrx zrx offabbrx orrparrx);
184 1         2 my @tmp;
185 1         4 foreach my $rx (@rx) {
186 7         12 push(@tmp,$$obj{'data'}{$rx});
187 7         12 delete $$obj{'data'}{$rx};
188             }
189              
190 1         2398 my $new = dclone($obj);
191              
192 1         6 foreach my $rx (@rx) {
193 7         11 my $r = shift(@tmp);
194 7         12 $$obj{'data'}{$rx} = $r;
195 7         15 $$new{'data'}{$rx} = $r;
196             }
197              
198 1         2 $$obj{'base'} = $base;
199 1         2 $$new{'base'} = $base;
200 1         5 return $new;
201             }
202             }
203              
204             # Only called if extra @args exist
205             sub _init_args {
206 0     0   0 my($self) = @_;
207              
208 0         0 my @args = @{ $$self{'args'} };
  0         0  
209 0         0 carp "WARNING: [new] invalid arguments: @args";
210              
211 0         0 return;
212             }
213              
214             sub _init_final {
215 20715     20715   33843 my($self) = @_;
216 20715         29745 return;
217             }
218              
219             sub new_config {
220 8     8 1 1367 my(@args) = @_;
221              
222             # Make sure that @opts is passed in as the final argument.
223              
224 8 100 66     41 if (! @args ||
225             ! (ref($args[$#args]) eq 'ARRAY')) {
226 6         16 push(@args,['ignore','ignore']);
227             }
228              
229 8         20 return new(@args);
230             }
231              
232             sub new_date {
233 13957     13957 1 25907 my(@args) = @_;
234 13957         71571 require Date::Manip::Date;
235 13957         38144 return new Date::Manip::Date @args;
236             }
237             sub new_delta {
238 5508     5508 1 288180 my(@args) = @_;
239 5508         123117 require Date::Manip::Delta;
240 5508         17207 return new Date::Manip::Delta @args;
241             }
242             sub new_recur {
243 277     277 1 966 my(@args) = @_;
244 277         123866 require Date::Manip::Recur;
245 277         2686 return new Date::Manip::Recur @args;
246             }
247              
248             sub base {
249 19597     19597 1 32780 my($self) = @_;
250 19597         31046 my $t = ref($self);
251 19597 100       44807 if ($t eq 'Date::Manip::Base') {
    100          
252 1         3 return undef;
253             } elsif ($t eq 'Date::Manip::TZ') {
254 17885         41653 return $$self{'base'};
255             } else {
256 1711         2950 my $dmt = $$self{'tz'};
257 1711         4540 return $$dmt{'base'};
258             }
259             }
260              
261             sub tz {
262 193     193 1 971 my($self) = @_;
263 193         502 my $t = ref($self);
264              
265 193 100 100     1398 if ($t eq 'Date::Manip::Base' ||
266             $t eq 'Date::Manip::TZ') {
267 2         5 return undef;
268             }
269              
270 191         654 return $$self{'tz'};
271             }
272              
273             sub config {
274 467     467 1 168156 my($self,@opts) = @_;
275 467         779 my $obj;
276 467 100 100     2948 if (ref($self) eq 'Date::Manip::Base' ||
277             ref($self) eq 'Date::Manip::TZ') {
278 83         181 $obj = $self;
279             } else {
280 384         1046 $obj = $$self{'tz'};
281             }
282              
283 467         1464 while (@opts) {
284 501         1199 my $var = shift(@opts);
285 501         1050 my $val = shift(@opts);
286 501         2630 $obj->_config_var($var,$val);
287             }
288              
289 467         1441 return;
290             }
291              
292             sub get_config {
293 8     8 1 1048 my($self,@args) = @_;
294              
295 8         12 my $base;
296 8         14 my $t = ref($self);
297 8 100       21 if ($t eq 'Date::Manip::Base') {
    100          
298 2         4 $base = $self;
299             } elsif ($t eq 'Date::Manip::TZ') {
300 2         4 $base = $$self{'base'};
301             } else {
302 4         9 my $dmt = $$self{'tz'};
303 4         7 $base = $$dmt{'base'};
304             }
305              
306 8 100       17 if (@args) {
307 7         9 my @ret;
308 7         11 foreach my $var (@args) {
309             # uncoverable branch false
310 8 50       28 if (exists $$base{'data'}{'sections'}{'conf'}{lc($var)}) {
311 8         19 push @ret,$$base{'data'}{'sections'}{'conf'}{lc($var)};
312             } else {
313             # uncoverable statement
314 0         0 carp "ERROR: [config] invalid config variable: $var";
315             # uncoverable statement
316 0         0 return '';
317             }
318             }
319              
320 7 100       15 if (@ret == 1) {
321 6         17 return $ret[0];
322             } else {
323 1         4 return @ret;
324             }
325             }
326              
327 1         3 my @ret = sort keys %{ $$base{'data'}{'sections'}{'conf'} };
  1         15  
328 1         9 return @ret;
329             }
330              
331             sub err {
332 11013     11013 1 47022 my($self,$arg) = @_;
333 11013 100       19299 if ($arg) {
334 1419         2644 $$self{'err'} = '';
335 1419         2913 return;
336             } else {
337 9594         27886 return $$self{'err'};
338             }
339             }
340              
341             sub is_date {
342 2     2 1 3654 return 0;
343             }
344             sub is_delta {
345 2     2 1 427 return 0;
346             }
347             sub is_recur {
348 2     2 1 237 return 0;
349             }
350              
351             sub version {
352 168     168 1 708 my($self,$flag) = @_;
353 168 50 33     1079 if ($flag && ref($self) ne 'Date::Manip::Base') {
354 0         0 my $dmt;
355 0 0       0 if (ref($self) eq 'Date::Manip::TZ') {
356 0         0 $dmt = $self;
357             } else {
358 0         0 $dmt = $$self{'tz'};
359             }
360 0         0 my $tz = $dmt->_now('systz');
361 0         0 return "$VERSION [$tz]";
362             } else {
363 168         1293 return $VERSION;
364             }
365             }
366              
367             1;
368             # Local Variables:
369             # mode: cperl
370             # indent-tabs-mode: nil
371             # cperl-indent-level: 3
372             # cperl-continued-statement-offset: 2
373             # cperl-continued-brace-offset: 0
374             # cperl-brace-offset: 0
375             # cperl-brace-imaginary-offset: 0
376             # cperl-label-offset: 0
377             # End: