Blame Util.xs

Packit 37d9e7
#include "EXTERN.h"
Packit 37d9e7
#include "perl.h"
Packit 37d9e7
#include "XSUB.h"
Packit 37d9e7
Packit 37d9e7
/* Changes in 5.7 series mean that now IOK is only set if scalar is
Packit 37d9e7
   precisely integer but in 5.6 and earlier we need to do a more
Packit 37d9e7
   complex test  */
Packit 37d9e7
#if PERL_VERSION <= 6
Packit 37d9e7
#define DD_is_integer(sv) (SvIOK(sv) && (SvIsUV(val) ? SvUV(sv) == SvNV(sv) : SvIV(sv) == SvNV(sv)))
Packit 37d9e7
#else
Packit 37d9e7
#define DD_is_integer(sv) SvIOK(sv)
Packit 37d9e7
#endif
Packit 37d9e7
Packit 37d9e7
static int
Packit 37d9e7
is_string0( SV *sv )
Packit 37d9e7
{
Packit 37d9e7
    return SvFLAGS(sv) & (SVf_OK & ~SVf_ROK);
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
static int
Packit 37d9e7
is_string( SV *sv )
Packit 37d9e7
{
Packit 37d9e7
    STRLEN len = 0;
Packit 37d9e7
    if( is_string0(sv) )
Packit 37d9e7
    {
Packit 37d9e7
        const char *pv = SvPV(sv, len);
Packit 37d9e7
    }
Packit 37d9e7
    return len;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
static int
Packit 37d9e7
is_array( SV *sv )
Packit 37d9e7
{
Packit 37d9e7
    return SvROK(sv) && ( SVt_PVAV == SvTYPE(SvRV(sv) ) );
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
static int
Packit 37d9e7
is_hash( SV *sv )
Packit 37d9e7
{
Packit 37d9e7
    return SvROK(sv) && ( SVt_PVHV == SvTYPE(SvRV(sv) ) );
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
static int
Packit 37d9e7
is_like( SV *sv, const char *like )
Packit 37d9e7
{
Packit 37d9e7
    int likely = 0;
Packit 37d9e7
    if( sv_isobject( sv ) )
Packit 37d9e7
    {
Packit 37d9e7
        dSP;
Packit 37d9e7
        int count;
Packit 37d9e7
Packit 37d9e7
        ENTER;
Packit 37d9e7
        SAVETMPS;
Packit 37d9e7
        PUSHMARK(SP);
Packit 37d9e7
        XPUSHs( sv_2mortal( newSVsv( sv ) ) );
Packit 37d9e7
        XPUSHs( sv_2mortal( newSVpv( like, strlen(like) ) ) );
Packit 37d9e7
        PUTBACK;
Packit 37d9e7
Packit 37d9e7
        if( ( count = call_pv("overload::Method", G_SCALAR) ) )
Packit 37d9e7
        {
Packit 37d9e7
            I32 ax;
Packit 37d9e7
            SPAGAIN;
Packit 37d9e7
Packit 37d9e7
            SP -= count;
Packit 37d9e7
            ax = (SP - PL_stack_base) + 1;
Packit 37d9e7
            if( SvTRUE(ST(0)) )
Packit 37d9e7
                ++likely;
Packit 37d9e7
        }
Packit 37d9e7
Packit 37d9e7
        PUTBACK;
Packit 37d9e7
        FREETMPS;
Packit 37d9e7
        LEAVE;
Packit 37d9e7
    }
Packit 37d9e7
Packit 37d9e7
    return likely;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
MODULE = Params::Util		PACKAGE = Params::Util
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_STRING(sv)
Packit 37d9e7
    SV *sv
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(sv) )
Packit 37d9e7
        mg_get(sv);
Packit 37d9e7
    if( is_string( sv ) )
Packit 37d9e7
    {
Packit 37d9e7
        ST(0) = sv;
Packit 37d9e7
        XSRETURN(1);
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_NUMBER(sv)
Packit 37d9e7
    SV *sv;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(sv) )
Packit 37d9e7
        mg_get(sv);
Packit 37d9e7
    if( ( SvIOK(sv) ) || ( SvNOK(sv) ) || ( is_string( sv ) && looks_like_number( sv ) ) )
Packit 37d9e7
    {
Packit 37d9e7
        ST(0) = sv;
Packit 37d9e7
        XSRETURN(1);
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_SCALAR0(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        if( ( SvTYPE(SvRV(ref)) <= SVt_PVBM ) && !sv_isobject(ref) )
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_SCALAR(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        svtype tp = SvTYPE(SvRV(ref));
Packit 37d9e7
        if( ( SvTYPE(SvRV(ref)) <= SVt_PVBM ) && (!sv_isobject(ref)) && is_string( SvRV(ref) ) )
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_REGEX(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        svtype tp = SvTYPE(SvRV(ref));
Packit 37d9e7
#if PERL_VERSION >= 11
Packit 37d9e7
        if( ( SVt_REGEXP == tp ) )
Packit 37d9e7
#else
Packit 37d9e7
        if( ( SVt_PVMG == tp ) && sv_isobject(ref)
Packit 37d9e7
         && ( 0 == strncmp( "Regexp", sv_reftype(SvRV(ref),TRUE),
Packit 37d9e7
                            strlen("Regexp") ) ) )
Packit 37d9e7
#endif
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_ARRAY0(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( is_array(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        ST(0) = ref;
Packit 37d9e7
        XSRETURN(1);
Packit 37d9e7
    }
Packit 37d9e7
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_ARRAY(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( is_array(ref) && ( av_len((AV *)(SvRV(ref))) >= 0 ) )
Packit 37d9e7
    {
Packit 37d9e7
        ST(0) = ref;
Packit 37d9e7
        XSRETURN(1);
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_ARRAYLIKE(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        if( is_array(ref) || is_like( ref, "@{}" ) )
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_HASH0(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( is_hash(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        ST(0) = ref;
Packit 37d9e7
        XSRETURN(1);
Packit 37d9e7
    }
Packit 37d9e7
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_HASH(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( is_hash(ref) && ( HvKEYS(SvRV(ref)) >= 1 ) )
Packit 37d9e7
    {
Packit 37d9e7
        ST(0) = ref;
Packit 37d9e7
        XSRETURN(1);
Packit 37d9e7
    }
Packit 37d9e7
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_HASHLIKE(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        if( is_hash(ref) || is_like( ref, "%{}" ) )
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_CODE(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        if( SVt_PVCV == SvTYPE(SvRV(ref)) )
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_CODELIKE(ref)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
PROTOTYPE: $
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) )
Packit 37d9e7
    {
Packit 37d9e7
        if( ( SVt_PVCV == SvTYPE(SvRV(ref)) ) || ( is_like(ref, "&{}" ) ) )
Packit 37d9e7
        {
Packit 37d9e7
            ST(0) = ref;
Packit 37d9e7
            XSRETURN(1);
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7
Packit 37d9e7
void
Packit 37d9e7
_INSTANCE(ref,type)
Packit 37d9e7
    SV *ref;
Packit 37d9e7
    char *type;
Packit 37d9e7
PROTOTYPE: $$
Packit 37d9e7
CODE:
Packit 37d9e7
{
Packit 37d9e7
    STRLEN len;
Packit 37d9e7
    if( SvMAGICAL(ref) )
Packit 37d9e7
        mg_get(ref);
Packit 37d9e7
    if( SvROK(ref) && type && ( ( len = strlen(type) ) > 0 ) )
Packit 37d9e7
    {
Packit 37d9e7
        if( sv_isobject(ref) )
Packit 37d9e7
        {
Packit 37d9e7
            I32 isa_type = 0;
Packit 37d9e7
            int count;
Packit 37d9e7
Packit 37d9e7
            ENTER;
Packit 37d9e7
            SAVETMPS;
Packit 37d9e7
            PUSHMARK(SP);
Packit 37d9e7
            XPUSHs( sv_2mortal( newSVsv( ref ) ) );
Packit 37d9e7
            XPUSHs( sv_2mortal( newSVpv( type, len ) ) );
Packit 37d9e7
            PUTBACK;
Packit 37d9e7
Packit 37d9e7
            if( ( count = call_method("isa", G_SCALAR) ) )
Packit 37d9e7
            {
Packit 37d9e7
                I32 oldax = ax;
Packit 37d9e7
                SPAGAIN;
Packit 37d9e7
                SP -= count;
Packit 37d9e7
                ax = (SP - PL_stack_base) + 1;
Packit 37d9e7
                isa_type = SvTRUE(ST(0));
Packit 37d9e7
                ax = oldax;
Packit 37d9e7
            }
Packit 37d9e7
Packit 37d9e7
            PUTBACK;
Packit 37d9e7
            FREETMPS;
Packit 37d9e7
            LEAVE;
Packit 37d9e7
Packit 37d9e7
            if( isa_type )
Packit 37d9e7
            {
Packit 37d9e7
                ST(0) = ref;
Packit 37d9e7
                XSRETURN(1);
Packit 37d9e7
            }
Packit 37d9e7
        }
Packit 37d9e7
    }
Packit 37d9e7
    XSRETURN_UNDEF;
Packit 37d9e7
}
Packit 37d9e7