X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FScalar-Vec-Util.git;a=blobdiff_plain;f=Util.xs;h=013bea280d069f0caf3f4c6bdeff44a086a48e30;hp=75ba8cabcabc72fd469c12eb9ceb36381c39f15e;hb=607607c4f5ec537ba56acb4edc424bc71900517a;hpb=dec1755eec42f54c4d57813ed03393c0f765a699 diff --git a/Util.xs b/Util.xs index 75ba8ca..013bea2 100644 --- a/Util.xs +++ b/Util.xs @@ -11,7 +11,32 @@ #include "bitvect.h" -STATIC const char svu_error_invarg[] = "Invalid argument"; +STATIC void svu_validate_uv(pTHX_ SV *sv, size_t *offset, const char *desc) { +#define svu_validate_uv(S, O, D) svu_validate_uv(aTHX_ (S), (O), (D)) + IV i; + + if (SvOK(sv) && SvIOK(sv)) { + if (SvIsUV(sv)) + *offset = SvUVX(sv); + else { + i = SvIVX(sv); + if (i < 0) + goto fail; + *offset = i; + } + } else { + i = SvIV(sv); + if (i < 0) + goto fail; + *offset = i; + } + + return; + +fail: + *offset = 0; + croak("Invalid negative %s", desc ? desc : "integer"); +} /* --- XS ------------------------------------------------------------------ */ @@ -33,13 +58,10 @@ 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); + svu_validate_uv(sl, &l, "length"); if (!l) XSRETURN(0); - s = SvUV(ss); + svu_validate_uv(ss, &s, "offset"); f = SvTRUE(sf); SvUPGRADE(sv, SVt_PV); @@ -65,14 +87,11 @@ 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); + svu_validate_uv(sl, &l, "length"); if (!l) XSRETURN(0); - fs = SvUV(sfs); - ts = SvUV(sts); + svu_validate_uv(sfs, &fs, "offset"); + svu_validate_uv(sts, &ts, "offset"); SvUPGRADE(sf, SVt_PV); SvUPGRADE(st, SVt_PV); @@ -114,14 +133,11 @@ 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); + svu_validate_uv(sl, &l, "length"); if (!l) - XSRETURN(0); - s1 = SvUV(ss1); - s2 = SvUV(ss2); + XSRETURN_YES; + svu_validate_uv(ss1, &s1, "offset"); + svu_validate_uv(ss2, &s2, "offset"); SvUPGRADE(sv1, SVt_PV); SvUPGRADE(sv2, SVt_PV);