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