X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Util.xs;h=f48753935ca5bbe54c1b7beb730acf74a8a970e4;hb=7ba2153f86d49fbe0fe44c561365310c114622ca;hp=8c03e45029b684e2c5b9fa89514a11837ae2576d;hpb=f77706f0734eb34a9623cc492b5d73061fba9b62;p=perl%2Fmodules%2FScalar-Vec-Util.git diff --git a/Util.xs b/Util.xs index 8c03e45..f487539 100644 --- a/Util.xs +++ b/Util.xs @@ -6,11 +6,32 @@ #include "perl.h" #include "XSUB.h" -#define __PACKAGE__ "Scalar::Vec::Util" +#define __PACKAGE__ "Scalar::Vec::Util" +#define __PACKAGE_LEN__ (sizeof(__PACKAGE__)-1) #include "bitvect.h" -STATIC const char svu_error_invarg[] = "Invalid argument"; +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; + + if (SvOK(sv) && SvIOK(sv)) { + if (SvIsUV(sv)) + return SvUVX(sv); + else { + i = SvIVX(sv); + if (i >= 0) + return i; + } + } else { + i = SvIV(sv); + if (i >= 0) + return i; + } + + croak("Invalid negative %s", desc ? desc : "integer"); + return 0; +} /* --- XS ------------------------------------------------------------------ */ @@ -20,26 +41,24 @@ PROTOTYPES: ENABLE BOOT: { - HV *stash = gv_stashpv(__PACKAGE__, 1); + HV *stash = gv_stashpvn(__PACKAGE__, __PACKAGE_LEN__, 1); newCONSTSUB(stash, "SVU_PP", newSVuv(0)); newCONSTSUB(stash, "SVU_SIZE", newSVuv(SVU_SIZE)); } void vfill(SV *sv, SV *ss, SV *sl, SV *sf) +PROTOTYPE: $$$$ PREINIT: size_t s, l, n, o; char f, *v; CODE: - if (!SvOK(sv) || !SvOK(ss) || !SvOK(sl) || !SvOK(sf)) { - croak(svu_error_invarg); - } - - l = SvUV(sl); - if (!l) { XSRETURN(0); } - s = SvUV(ss); + l = svu_validate_uv(sl, "length"); + if (!l) + XSRETURN(0); + s = svu_validate_uv(ss, "offset"); f = SvTRUE(sf); - if (SvTYPE(sv) < SVt_PV) { SvUPGRADE(sv, SVt_PV); } + SvUPGRADE(sv, SVt_PV); n = BV_SIZE(s + l); o = SvLEN(sv); @@ -49,9 +68,8 @@ CODE: } else { v = SvPVX(sv); } - if (SvCUR(sv) < n) { + if (SvCUR(sv) < n) SvCUR_set(sv, n); - } bv_fill(v, s, l, f); @@ -59,20 +77,18 @@ CODE: void vcopy(SV *sf, SV *sfs, SV *st, SV *sts, SV *sl) +PROTOTYPE: $$$$$ PREINIT: size_t fs, ts, l, lf = 0, n, o; char *t, *f; CODE: - if (!SvOK(sf) || !SvOK(sfs) || !SvOK(st) || !SvOK(sts) || !SvOK(sl)) { - croak(svu_error_invarg); - } - - l = SvUV(sl); - if (!l) { XSRETURN(0); } - fs = SvUV(sfs); - ts = SvUV(sts); - if (SvTYPE(sf) < SVt_PV) { SvUPGRADE(sf, SVt_PV); } - if (SvTYPE(st) < SVt_PV) { SvUPGRADE(st, SVt_PV); } + l = svu_validate_uv(sl, "length"); + if (!l) + XSRETURN(0); + fs = svu_validate_uv(sfs, "offset"); + ts = svu_validate_uv(sts, "offset"); + SvUPGRADE(sf, SVt_PV); + SvUPGRADE(st, SVt_PV); n = BV_SIZE(ts + l); o = SvLEN(st); @@ -82,9 +98,8 @@ CODE: } else { t = SvPVX(st); } - if (SvCUR(st) < n) { + if (SvCUR(st) < n) SvCUR_set(st, n); - } f = SvPVX(sf); /* We do it there in case st == sf. */ n = BV_SIZE(fs + l); @@ -108,19 +123,18 @@ CODE: SV * veq(SV *sv1, SV *ss1, SV *sv2, SV *ss2, SV *sl) +PROTOTYPE: $$$$$ PREINIT: size_t s1, s2, l, o, n; char *v1, *v2; CODE: - if (!SvOK(sv1) || !SvOK(ss1) || !SvOK(sv2) || !SvOK(ss2) || !SvOK(sl)) { - croak(svu_error_invarg); - } - - l = SvUV(sl); - s1 = SvUV(ss1); - s2 = SvUV(ss2); - if (SvTYPE(sv1) < SVt_PV) { SvUPGRADE(sv1, SVt_PV); } - if (SvTYPE(sv2) < SVt_PV) { SvUPGRADE(sv2, SVt_PV); } + l = svu_validate_uv(sl, "length"); + if (!l) + XSRETURN_YES; + 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);