This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_leavesublv(): document PL_sv_undef exception
[perl5.git] / cpan / Math-BigInt-FastCalc / FastCalc.xs
index 6dbe958..eb228e4 100644 (file)
@@ -1,3 +1,5 @@
+#define PERL_NO_GET_CONTEXT
+
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
@@ -7,8 +9,13 @@
 #  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
 
@@ -34,42 +41,31 @@ PROTOTYPES: DISABLE
       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
       {
@@ -95,10 +91,11 @@ _new(class, x)
         /* 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
 
@@ -111,7 +108,7 @@ _copy(class, x)
   INIT:
     AV*        a;
     AV*        a2;
-    I32        elems;
+    SSize_t elems;
 
   CODE:
     a = (AV*)SvRV(x);                  /* ref to aray, don't check ref */
@@ -147,8 +144,8 @@ __strip_zeros(x)
   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 */
@@ -192,8 +189,8 @@ _dec(class,x)
   INIT:
     AV*        a;
     SV*        temp;
-    I32        elems;
-    I32        index;
+    SSize_t elems;
+    SSize_t index;
     NV MAX;
 
   CODE:
@@ -236,8 +233,8 @@ _inc(class,x)
   INIT:
     AV*        a;
     SV*        temp;
-    I32        elems;
-    I32        index;
+    SSize_t elems;
+    SSize_t index;
     NV BASE;
 
   CODE:
@@ -266,75 +263,18 @@ _inc(class,x)
     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
 
@@ -343,6 +283,8 @@ _ten(class)
 void
 _is_even(class, x)
   SV*  x
+  ALIAS:
+    _is_odd = 1
   INIT:
     AV*        a;
     SV*        temp;
@@ -350,97 +292,32 @@ _is_even(class, x)
   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);
 
 ##############################################################################
 
@@ -470,13 +347,13 @@ _acmp(class, cx, cy);
   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 */
@@ -494,12 +371,12 @@ _acmp(class, cx, cy);
       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 */