#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 ------------------------------------------------------------------ */
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);
+ l = svu_validate_uv(sl, "length");
if (!l)
XSRETURN(0);
- s = SvUV(ss);
+ s = svu_validate_uv(ss, "offset");
f = SvTRUE(sf);
SvUPGRADE(sv, SVt_PV);
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);
+ l = svu_validate_uv(sl, "length");
if (!l)
XSRETURN(0);
- fs = SvUV(sfs);
- ts = SvUV(sts);
+ fs = svu_validate_uv(sfs, "offset");
+ ts = svu_validate_uv(sts, "offset");
SvUPGRADE(sf, SVt_PV);
SvUPGRADE(st, SVt_PV);
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);
+ l = svu_validate_uv(sl, "length");
if (!l)
- XSRETURN(0);
- s1 = SvUV(ss1);
- s2 = SvUV(ss2);
+ XSRETURN_YES;
+ s1 = svu_validate_uv(ss1, "offset");
+ s2 = svu_validate_uv(ss2, "offset");
SvUPGRADE(sv1, SVt_PV);
SvUPGRADE(sv2, SVt_PV);