ae4d77f80a8b662a31b3a70b8b4e5cb51b6beae9
[debian/amanda] / perl / Amanda / BigIntCompat.pm
1 # Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License version 2 as published
5 # by the Free Software Foundation.
6 #
7 # This program is distributed in the hope that it will be useful, but
8 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10 # for more details.
11 #
12 # You should have received a copy of the GNU General Public License along
13 # with this program; if not, write to the Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 #
16 # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
17 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
18
19 package Amanda::BigIntCompat;
20
21 use strict;
22 use warnings;
23 use overload;
24 use Math::BigInt;
25
26 =head1 NAME
27
28 Amanda::BigIntCompat -- make C<Math::BigInt> behave consistently
29
30 =head1 SYNOPSIS
31
32   use Amanda::BigIntCompat;
33   use Math::BigInt;
34
35   my $bn = Math::BigInt->new(1);
36   print "okay\n" if $bn eq "1";
37
38 =head1 INTERFACE
39
40 This module will modify C<Math::BigInt> to hide inconsistent behaviors across
41 Perl versions. Specifically, it handles the following.
42
43 =over
44
45 =item stringification
46
47 Older versions of C<Math::BigInt>, like the one shipped with Perl 5.6.1,
48 stringify positive numbers with a leading C<+> (e.g. C<+1> instead of C<1>).
49
50 =back
51
52 =cut
53
54 my $test_num = Math::BigInt->new(1);
55
56 our $stringify = overload::Method($test_num, '""');
57 # convince older perls that $stringify really is used
58 $stringify = $stringify;
59
60 if ($test_num =~ /^\+/) {
61     eval <<'EVAL';
62         package Math::BigInt;
63         use overload 'eq' => sub {
64             my ($self, $other) = @_;
65             return "$self" eq "$other";
66         };
67
68         # stringify is already overloaded; seems to be no good way to
69         # re-overload it without triggering a warning
70         no warnings 'redefine';
71         sub stringify {
72             my $str = $Amanda::BigIntCompat::stringify->(@_);
73             $str =~ s/^\+//;
74             return $str;
75         }
76 EVAL
77     die $@ if $@;
78 }
79
80 # the "sign" method does not exist in older versions, either, but is used
81 # by bigint2uint64().
82 if (!$test_num->can("sign")) {
83     eval <<'EVAL';
84         package Math::BigInt;
85         sub sign { ($_[0] =~ /^-/)? "-" : "+"; }
86 EVAL
87     die $@ if $@;
88 }
89
90 # similarly for bstr
91 if (!$test_num->can("bstr")) {
92     eval <<'EVAL';
93         package Math::BigInt;
94         sub bstr { "$_[0]"; }
95 EVAL
96     die $@ if $@;
97 }
98 1;