Affix

 view release on metacpan or  search on metacpan

lib/Affix.c  view on Meta::CPAN

    char buffer[256];
    if (infix_type_print(buffer, sizeof(buffer), pin->type, INFIX_DIALECT_SIGNATURE) == INFIX_SUCCESS)
        ST(0) = sv_2mortal(newSVpv(buffer, 0));
    else
        XSRETURN_UNDEF;
    XSRETURN(1);
}

XS_INTERNAL(Affix_pin_element_type) {
    dXSARGS;
    if (items != 1)
        croak_xs_usage(cv, "pin");
    Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ ST(0));
    if (!pin || !pin->type)
        XSRETURN_UNDEF;
    const infix_type * elem_type = pin->type;
    if (elem_type->category == INFIX_TYPE_ARRAY)
        elem_type = elem_type->meta.array_info.element_type;
    else if (elem_type->category == INFIX_TYPE_POINTER)
        elem_type = elem_type->meta.pointer_info.pointee_type;

    char buffer[256];
    if (infix_type_print(buffer, sizeof(buffer), elem_type, INFIX_DIALECT_SIGNATURE) == INFIX_SUCCESS)
        ST(0) = sv_2mortal(newSVpv(buffer, 0));
    else
        XSRETURN_UNDEF;
    XSRETURN(1);
}

XS_INTERNAL(Affix_pin_count) {
    dXSARGS;
    if (items != 1)
        croak_xs_usage(cv, "pin");
    Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ ST(0));
    if (pin && pin->type) {
        if (pin->type->category == INFIX_TYPE_ARRAY) {
            ST(0) = sv_2mortal(newSVuv(pin->type->meta.array_info.num_elements));
            XSRETURN(1);
        }
    }
    XSRETURN_UNDEF;
}

XS_INTERNAL(Affix_pin_size) {
    dXSARGS;
    if (items != 1)
        croak_xs_usage(cv, "pin");

    Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ ST(0));
    if (pin && pin->type) {
        ST(0) = sv_2mortal(newSVuv(infix_type_get_size(pin->type)));
        XSRETURN(1);
    }
    XSRETURN_UNDEF;
}

// Helper to register core internal types
static void _register_core_types(infix_registry_t * registry) {
    // Register SV as a named type (dummy struct ensures it keeps the name in the registry).
    // This allows signature parsing of "@SV" or "SV" (via hack) to map to a named opaque type.
    // Direct usage of this type is blocked in get_opcode_for_type; it must be wrapped in Pointer[].
    if (infix_register_types(registry, "@SV = { __sv_opaque: uint8 };") != INFIX_SUCCESS)
        croak("Failed to register internal type alias '@SV'");

    // We register File and PerlIO as opaque structs.
    // This semantically matches C's FILE struct which (for now) will remain opaque to the user.
    // We require "Pointer[File]" to mean "FILE*"
    if (infix_register_types(registry, "@File = { _opaque: [0:uchar] };") != INFIX_SUCCESS)
        croak("Failed to register internal type alias '@File'");
    if (infix_register_types(registry, "@PerlIO = { _opaque: [0:uchar] };") != INFIX_SUCCESS)
        croak("Failed to register internal type alias '@PerlIO'");

    // Other special types are opaque structs too. ...but they don't always mean anything in particular.
    if (infix_register_types(registry, "@StringList = **char;") != INFIX_SUCCESS)
        croak("Failed to register internal type alias '@StringList'");
    if (infix_register_types(registry, "@Buffer = *void;") != INFIX_SUCCESS)
        croak("Failed to register internal type alias '@Buffer'");
    if (infix_register_types(registry, "@SockAddr = *void;") != INFIX_SUCCESS)
        croak("Failed to register internal type alias '@SockAddr'");
}


static void _set_readonly_recursive(pTHX_ SV * sv, bool ro) {
    if (!sv || !SvOK(sv))
        return;
    SV * target = SvROK(sv) ? SvRV(sv) : sv;
    Affix_Pin_2_Point_Oh * pin = get_pin_v2(aTHX_ target);
    if (pin)
        pin->readonly = ro;

    if (SvTYPE(target) == SVt_PVHV) {
        HV * hv = (HV *)target;
        HE * entry;
        hv_iterinit(hv);
        while ((entry = hv_iternext(hv)))
            _set_readonly_recursive(aTHX_ hv_iterval(hv, entry), ro);
    }
    else if (SvTYPE(target) == SVt_PVAV) {
        AV * av = (AV *)target;
        SSize_t len = av_len(av);
        for (SSize_t i = 0; i <= len; i++) {
            SV ** val = av_fetch(av, i, 0);
            if (val && *val)
                _set_readonly_recursive(aTHX_ * val, ro);
        }
    }
}

XS_INTERNAL(Affix_readonly) {
    dXSARGS;
    if (items < 1)
        croak_xs_usage(cv, "pin, [readonly]");

    // Check for V2 Pin first
    if (is_pin_v2(aTHX_ ST(0))) {
        Affix_Pin_2_Point_Oh * pin_v2 = get_pin_v2(aTHX_ ST(0));
        if (items > 1) {
            bool ro = SvTRUE(ST(1));
            _set_readonly_recursive(aTHX_ ST(0), ro);
        }
        ST(0) = pin_v2->readonly ? &PL_sv_yes : &PL_sv_no;



( run in 1.172 second using v1.01-cache-2.11-cpan-800906f7e73 )