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);
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;
}
XSRETURN(0);
-SV *
+void
veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl)
PROTOTYPE: $$$$$
PREINIT:
- size_t s1, s2, l, o, n;
- char *v1, *v2;
+ size_t s1, s2, l, l1, l2, c1, c2, e1, e2, e;
+ int res = 1;
+ char *v1, *v2;
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");
+
SvUPGRADE(sv1, SVt_PV);
SvUPGRADE(sv2, SVt_PV);
-
- n = BV_SIZE(s1 + l);
- o = SvLEN(sv1);
- if (n > o) {
- l = o * CHAR_BIT - s1;
+ v1 = SvPVX(sv1);
+ v2 = SvPVX(sv2);
+ c1 = SvCUR(sv1) * CHAR_BIT;
+ c2 = SvCUR(sv2) * CHAR_BIT;
+
+ redo:
+ l1 = s1 + l;
+ l2 = s2 + l;
+ e1 = l1 > c1 ? l1 - c1 : 0;
+ e2 = l2 > c2 ? l2 - c2 : 0;
+ e = e1 > e2 ? e1 : e2;
+
+ if (l > e) {
+ size_t p = l - e;
+
+ res = bv_eq(v1, s1, v2, s2, p);
+ if (!res || e == 0)
+ goto done;
+
+ /* Bit vectors are equal up to p < l */
+ s1 += p;
+ s2 += p;
+ l = e;
+ goto redo;
}
- n = BV_SIZE(s2 + l);
- o = SvLEN(sv2);
- if (n > o) {
- l = o * CHAR_BIT - s2;
- }
+ /* l <= max(e1, e2), at least one of the vectors is completely out of bounds */
+ e = e1 < e2 ? e1 : e2;
+ if (l > e) {
+ size_t q = l - e;
- v1 = SvPVX(sv1);
- v2 = SvPVX(sv2);
+ if (s1 < c1)
+ res = bv_zero(v1, s1, q);
+ else if (s2 < c2)
+ res = bv_zero(v2, s2, q);
+ }
- RETVAL = newSVuv(bv_eq(v1, s1, v2, s2, l));
-OUTPUT:
- RETVAL
+ done:
+ ST(0) = res ? &PL_sv_yes : &PL_sv_no;
+ XSRETURN(1);