]> git.vpit.fr Git - perl/modules/Scalar-Vec-Util.git/blobdiff - Util.xs
Update VPIT::TestHelpers to 15e8aee3
[perl/modules/Scalar-Vec-Util.git] / Util.xs
diff --git a/Util.xs b/Util.xs
index 2c3cc6e8641d0217f0f457a5f6291d870814b78c..d878813aba6d96e200d7dea679b29923683bfa06 100644 (file)
--- a/Util.xs
+++ b/Util.xs
 
 #include "bitvect.h"
 
-STATIC size_t svu_validate_uv(pTHX_ SV *sv, const char *desc) {
+#ifndef SVU_SIZE
+# define SVU_SIZE (CHAR_BIT * sizeof(BV_UNIT))
+#endif
+
+static size_t svu_validate_uv(pTHX_ SV *sv, const char *desc) {
 #define svu_validate_uv(S, D) svu_validate_uv(aTHX_ (S), (D))
  IV i;
 
@@ -33,10 +37,10 @@ STATIC size_t svu_validate_uv(pTHX_ SV *sv, const char *desc) {
  return 0;
 }
 
-STATIC char *svu_prepare_sv(pTHX_ SV *sv, size_t s, size_t l) {
+static char *svu_prepare_sv(pTHX_ SV *sv, size_t s, size_t l) {
 #define svu_prepare_sv(S, I, L) svu_prepare_sv(aTHX_ (S), (I), (L))
  STRLEN  c;
- size_t  n = s + l, i, j1, j2, k, z;
+ size_t  n = s + l, i, js, jz, k, z;
  char   *p;
 
  SvUPGRADE(sv, SVt_PV);
@@ -44,15 +48,15 @@ STATIC char *svu_prepare_sv(pTHX_ SV *sv, size_t s, size_t l) {
  p = SvGROW(sv, BV_SIZE(n));
  c = SvCUR(sv);
 
- j1 = (s / BITS(BV_UNIT)) * sizeof(BV_UNIT);
- k  = j1 + sizeof(BV_UNIT);
- for (i = c < j1 ? j1 : c; i < k; ++i)
+ js = (s / BITS(BV_UNIT)) * sizeof(BV_UNIT);
+ k  = js + sizeof(BV_UNIT);
+ for (i = c < js ? js : c; i < k; ++i)
   p[i] = 0;
 
- j2 = ((s + l - 1) / BITS(BV_UNIT)) * sizeof(BV_UNIT);
- if (j2 > j1) {
-  k = j2 + sizeof(BV_UNIT);
-  for (i = c < j2 ? j2 : c; i < k; ++i)
+ jz = ((s + l - 1) / BITS(BV_UNIT)) * sizeof(BV_UNIT);
+ if (jz > js) {
+  k = jz + sizeof(BV_UNIT);
+  for (i = c < jz ? jz : c; i < k; ++i)
    p[i] = 0;
  }
 
@@ -98,8 +102,8 @@ void
 vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl)
 PROTOTYPE: $$$$$
 PREINIT:
- size_t fs, ts, l, lf = 0, c;
- char *t, *f;
+ size_t fs, ts, l, e, lf, cf;
+ char *vt, *vf;
 CODE:
  l = svu_validate_uv(sl, "length");
  if (!l)
@@ -107,28 +111,29 @@ CODE:
  fs = svu_validate_uv(sfs, "offset");
  ts = svu_validate_uv(sts, "offset");
 
- t = svu_prepare_sv(st, ts, l);
-
- f = SvPVX(sf); /* We do it there in case st == sf. */
- c = SvCUR(sf);
- if (c * CHAR_BIT <= fs + l && c <= SvCUR(st)) {
-  lf = fs + l - c * CHAR_BIT;
-  l  = c * CHAR_BIT - fs;
+ SvUPGRADE(sf, SVt_PV);
+ vt = svu_prepare_sv(st, ts, l);
+
+ /* We fetch vf after upgrading st in case st == sf. */
+ vf = SvPVX(sf);
+ cf = SvCUR(sf) * CHAR_BIT;
+ lf = fs + l;
+ e  = lf > cf ? lf - cf : 0;
+ l  =  l > e  ?  l - e  : 0;
+
+ if (l) {
+  if (vf == vt)
+   bv_move(vf, ts, fs, l);
+  else
+   bv_copy(vt, ts, vf, fs, l);
  }
 
- if (f == t) {
-  bv_move(f, ts, fs, l);
- } else {
-  bv_copy(t, ts, f, fs, l);
- }
-
- if (lf) {
-  bv_fill(t, ts + l, lf, 0);
- }
+ if (e)
+  bv_fill(vt, ts + l, e, 0);
 
  XSRETURN(0);
 
-SV *
+void
 veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl)
 PROTOTYPE: $$$$$
 PREINIT:
@@ -138,7 +143,7 @@ PREINIT:
 CODE:
  l = svu_validate_uv(sl, "length");
  if (!l)
-  XSRETURN_YES;
+  goto done;
  s1 = svu_validate_uv(ss1, "offset");
  s2 = svu_validate_uv(ss2, "offset");
 
@@ -182,6 +187,5 @@ CODE:
  }
 
  done:
- RETVAL = newSVuv(res);
-OUTPUT:
- RETVAL
+ ST(0) = res ? &PL_sv_yes : &PL_sv_no;
+ XSRETURN(1);