+#define PERL_NO_GET_CONTEXT
+
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
# define SvUOK(sv) SvIOK_UV(sv)
#endif
-double XS_BASE = 0;
-double XS_BASE_LEN = 0;
+/* for Perl v5.6 (RT #63859) */
+#ifndef croak_xs_usage
+# define croak_xs_usage croak
+#endif
+
+static double XS_BASE = 0;
+static double XS_BASE_LEN = 0;
MODULE = Math::BigInt::FastCalc PACKAGE = Math::BigInt::FastCalc
ST(0) = sv_2mortal(newSViv(value)); \
XSRETURN(1);
-#define RETURN_MORTAL_BOOL(temp, comp) \
- ST(0) = sv_2mortal(boolSV( SvIV(temp) == comp));
-
-#define CONSTANT_OBJ(int) \
- RETVAL = newAV(); \
- sv_2mortal((SV*)RETVAL); \
- av_push (RETVAL, newSViv( int ));
-
-void
-_set_XS_BASE(BASE, BASE_LEN)
- SV* BASE
- SV* BASE_LEN
-
- CODE:
- XS_BASE = SvNV(BASE);
- XS_BASE_LEN = SvIV(BASE_LEN);
+BOOT:
+{
+ if (items < 4)
+ croak("Usage: Math::BigInt::FastCalc::BOOT(package, version, base_len, base)");
+ XS_BASE_LEN = SvIV(ST(2));
+ XS_BASE = SvNV(ST(3));
+}
##############################################################################
# _new
-AV *
+SV *
_new(class, x)
SV* x
INIT:
STRLEN len;
char* cur;
STRLEN part_len;
+ AV *av = newAV();
CODE:
- /* create the array */
- RETVAL = newAV();
- sv_2mortal((SV*)RETVAL);
if (SvUOK(x) && SvUV(x) < XS_BASE)
{
/* shortcut for integer arguments */
- av_push (RETVAL, newSVuv( SvUV(x) ));
+ av_push (av, newSVuv( SvUV(x) ));
}
else
{
/* printf ("part '%s' (part_len: %i, len: %i, BASE_LEN: %i)\n", cur, part_len, len, XS_BASE_LEN); */
if (part_len > 0)
{
- av_push (RETVAL, newSVpvn(cur, part_len) );
+ av_push (av, newSVpvn(cur, part_len) );
}
}
}
+ RETVAL = newRV_noinc((SV *)av);
OUTPUT:
RETVAL
INIT:
AV* a;
AV* a2;
- I32 elems;
+ SSize_t elems;
CODE:
a = (AV*)SvRV(x); /* ref to aray, don't check ref */
INIT:
AV* a;
SV* temp;
- I32 elems;
- I32 index;
+ SSize_t elems;
+ SSize_t index;
CODE:
a = (AV*)SvRV(x); /* ref to aray, don't check ref */
INIT:
AV* a;
SV* temp;
- I32 elems;
- I32 index;
+ SSize_t elems;
+ SSize_t index;
NV MAX;
CODE:
INIT:
AV* a;
SV* temp;
- I32 elems;
- I32 index;
+ SSize_t elems;
+ SSize_t index;
NV BASE;
CODE:
XSRETURN(1); /* return x */
##############################################################################
-# Make a number (scalar int/float) from a BigInt object
-
-void
-_num(class,x)
- SV* x
- INIT:
- AV* a;
- NV fac;
- SV* temp;
- NV num;
- I32 elems;
- I32 index;
- NV BASE;
-
- CODE:
- a = (AV*)SvRV(x); /* ref to aray, don't check ref */
- elems = av_len(a); /* number of elems in array */
-
- if (elems == 0) /* only one element? */
- {
- ST(0) = *av_fetch(a, 0, 0); /* fetch first (only) element */
- XSRETURN(1); /* return it */
- }
- fac = 1.0; /* factor */
- index = 0;
- num = 0.0;
- BASE = XS_BASE;
- while (index <= elems)
- {
- temp = *av_fetch(a, index, 0); /* fetch current element */
- num += fac * SvNV(temp);
- fac *= BASE;
- index++;
- }
- ST(0) = newSVnv(num);
-
-##############################################################################
-AV *
+SV *
_zero(class)
+ ALIAS:
+ _one = 1
+ _two = 2
+ _ten = 10
+ PREINIT:
+ AV *av = newAV();
CODE:
- CONSTANT_OBJ(0)
- OUTPUT:
- RETVAL
-
-##############################################################################
-
-AV *
-_one(class)
- CODE:
- CONSTANT_OBJ(1)
- OUTPUT:
- RETVAL
-
-##############################################################################
-
-AV *
-_two(class)
- CODE:
- CONSTANT_OBJ(2)
- OUTPUT:
- RETVAL
-
-##############################################################################
-
-AV *
-_ten(class)
- CODE:
- CONSTANT_OBJ(10)
+ av_push (av, newSViv( ix ));
+ RETVAL = newRV_noinc((SV *)av);
OUTPUT:
RETVAL
void
_is_even(class, x)
SV* x
+ ALIAS:
+ _is_odd = 1
INIT:
AV* a;
SV* temp;
CODE:
a = (AV*)SvRV(x); /* ref to aray, don't check ref */
temp = *av_fetch(a, 0, 0); /* fetch first element */
- ST(0) = sv_2mortal(boolSV((SvIV(temp) & 1) == 0));
-
-##############################################################################
-
-void
-_is_odd(class, x)
- SV* x
- INIT:
- AV* a;
- SV* temp;
-
- CODE:
- a = (AV*)SvRV(x); /* ref to aray, don't check ref */
- temp = *av_fetch(a, 0, 0); /* fetch first element */
- ST(0) = sv_2mortal(boolSV((SvIV(temp) & 1) != 0));
-
-##############################################################################
-
-void
-_is_one(class, x)
- SV* x
- INIT:
- AV* a;
- SV* temp;
-
- CODE:
- a = (AV*)SvRV(x); /* ref to aray, don't check ref */
- if ( av_len(a) != 0)
- {
- ST(0) = &PL_sv_no;
- XSRETURN(1); /* len != 1, can't be '1' */
- }
- temp = *av_fetch(a, 0, 0); /* fetch first element */
- RETURN_MORTAL_BOOL(temp, 1);
-
-##############################################################################
-
-void
-_is_two(class, x)
- SV* x
- INIT:
- AV* a;
- SV* temp;
-
- CODE:
- a = (AV*)SvRV(x); /* ref to aray, don't check ref */
- if ( av_len(a) != 0)
- {
- ST(0) = &PL_sv_no;
- XSRETURN(1); /* len != 1, can't be '2' */
- }
- temp = *av_fetch(a, 0, 0); /* fetch first element */
- RETURN_MORTAL_BOOL(temp, 2);
+ ST(0) = sv_2mortal(boolSV((SvIV(temp) & 1) == ix));
##############################################################################
void
-_is_ten(class, x)
+_is_zero(class, x)
SV* x
+ ALIAS:
+ _is_one = 1
+ _is_two = 2
+ _is_ten = 10
INIT:
AV* a;
- SV* temp;
CODE:
a = (AV*)SvRV(x); /* ref to aray, don't check ref */
if ( av_len(a) != 0)
{
- ST(0) = &PL_sv_no;
- XSRETURN(1); /* len != 1, can't be '10' */
+ ST(0) = &PL_sv_no; /* len != 1, can't be '0' */
}
- temp = *av_fetch(a, 0, 0); /* fetch first element */
- RETURN_MORTAL_BOOL(temp, 10);
-
-##############################################################################
-
-void
-_is_zero(class, x)
- SV* x
- INIT:
- AV* a;
- SV* temp;
-
- CODE:
- a = (AV*)SvRV(x); /* ref to aray, don't check ref */
- if ( av_len(a) != 0)
+ else
{
- ST(0) = &PL_sv_no;
- XSRETURN(1); /* len != 1, can't be '0' */
+ SV *const temp = *av_fetch(a, 0, 0); /* fetch first element */
+ ST(0) = boolSV(SvIV(temp) == ix);
}
- temp = *av_fetch(a, 0, 0); /* fetch first element */
- RETURN_MORTAL_BOOL(temp, 0);
+ XSRETURN(1);
##############################################################################
INIT:
AV* array_x;
AV* array_y;
- I32 elemsx, elemsy, diff;
+ SSize_t elemsx, elemsy, diff;
SV* tempx;
SV* tempy;
STRLEN lenx;
STRLEN leny;
NV diff_nv;
- I32 diff_str;
+ SSize_t diff_str;
CODE:
array_x = (AV*)SvRV(cx); /* ref to aray, don't check ref */
RETURN_MORTAL_INT(-1); /* len differs: X < Y */
}
/* both have same number of elements, so check length of last element
- and see if it differes */
+ and see if it differs */
tempx = *av_fetch(array_x, elemsx, 0); /* fetch last element */
tempy = *av_fetch(array_y, elemsx, 0); /* fetch last element */
SvPV(tempx, lenx); /* convert to string & store length */
SvPV(tempy, leny); /* convert to string & store length */
- diff_str = (I32)lenx - (I32)leny;
+ diff_str = (SSize_t)lenx - (SSize_t)leny;
if (diff_str > 0)
{
RETURN_MORTAL_INT(1); /* same len, but first elems differs in len */