15759b3d2Safresh1################################################################################
25759b3d2Safresh1##
35759b3d2Safresh1##  Copyright (C) 2017, Pali <pali@cpan.org>
45759b3d2Safresh1##
55759b3d2Safresh1##  This program is free software; you can redistribute it and/or
65759b3d2Safresh1##  modify it under the same terms as Perl itself.
75759b3d2Safresh1##
85759b3d2Safresh1################################################################################
95759b3d2Safresh1
105759b3d2Safresh1=provides
115759b3d2Safresh1
125759b3d2Safresh1croak_sv
135759b3d2Safresh1die_sv
145759b3d2Safresh1mess_sv
155759b3d2Safresh1warn_sv
165759b3d2Safresh1
175759b3d2Safresh1vmess
185759b3d2Safresh1mess_nocontext
195759b3d2Safresh1mess
205759b3d2Safresh1
215759b3d2Safresh1warn_nocontext
225759b3d2Safresh1
235759b3d2Safresh1croak_nocontext
249a4edab6SbluhmPERL_ARGS_ASSERT_CROAK_XS_USAGE
255759b3d2Safresh1
265759b3d2Safresh1croak_no_modify
275759b3d2Safresh1Perl_croak_no_modify
285759b3d2Safresh1
295759b3d2Safresh1croak_memory_wrap
305759b3d2Safresh1croak_xs_usage
315759b3d2Safresh1
325759b3d2Safresh1=dontwarn
335759b3d2Safresh1
345759b3d2Safresh1NEED_mess
355759b3d2Safresh1NEED_mess_nocontext
365759b3d2Safresh1NEED_vmess
375759b3d2Safresh1
385759b3d2Safresh1=implementation
395759b3d2Safresh1
405759b3d2Safresh1#ifdef NEED_mess_sv
415759b3d2Safresh1#define NEED_mess
425759b3d2Safresh1#endif
435759b3d2Safresh1
445759b3d2Safresh1#ifdef NEED_mess
455759b3d2Safresh1#define NEED_mess_nocontext
465759b3d2Safresh1#define NEED_vmess
475759b3d2Safresh1#endif
485759b3d2Safresh1
495759b3d2Safresh1#ifndef croak_sv
505759b3d2Safresh1#if { VERSION >= 5.7.3 } || ( { VERSION >= 5.6.1 } && { VERSION < 5.7.0 } )
515759b3d2Safresh1#  if ( { VERSION >= 5.8.0 } && { VERSION < 5.8.9 } ) || ( { VERSION >= 5.9.0 } && { VERSION < 5.10.1 } )
52de8cc8edSafresh1#    define D_PPP_FIX_UTF8_ERRSV_FOR_SV(sv)                    \
535759b3d2Safresh1        STMT_START {                                           \
54de8cc8edSafresh1            SV *_errsv = ERRSV;                                \
55de8cc8edSafresh1            SvFLAGS(_errsv) = (SvFLAGS(_errsv) & ~SVf_UTF8) |  \
565759b3d2Safresh1                              (SvFLAGS(sv) & SVf_UTF8);        \
575759b3d2Safresh1        } STMT_END
585759b3d2Safresh1#  else
59de8cc8edSafresh1#    define D_PPP_FIX_UTF8_ERRSV_FOR_SV(sv) STMT_START {} STMT_END
605759b3d2Safresh1#  endif
61*e0680481Safresh1PERL_STATIC_INLINE void D_PPP_croak_sv(SV *sv) {
62*e0680481Safresh1    dTHX;
63*e0680481Safresh1    SV *_sv = (sv);
64*e0680481Safresh1    if (SvROK(_sv)) {
65*e0680481Safresh1        sv_setsv(ERRSV, _sv);
66*e0680481Safresh1        croak(NULL);
67*e0680481Safresh1    } else {
68*e0680481Safresh1        D_PPP_FIX_UTF8_ERRSV_FOR_SV(_sv);
69*e0680481Safresh1        croak("%" SVf, SVfARG(_sv));
70*e0680481Safresh1    }
71*e0680481Safresh1}
72*e0680481Safresh1#  define croak_sv(sv) D_PPP_croak_sv(sv)
735759b3d2Safresh1#elif { VERSION >= 5.4.0 }
745759b3d2Safresh1#  define croak_sv(sv) croak("%" SVf, SVfARG(sv))
755759b3d2Safresh1#else
765759b3d2Safresh1#  define croak_sv(sv) croak("%s", SvPV_nolen(sv))
775759b3d2Safresh1#endif
785759b3d2Safresh1#endif
795759b3d2Safresh1
805759b3d2Safresh1#ifndef die_sv
815759b3d2Safresh1#if { NEED die_sv }
825759b3d2Safresh1OP *
83de8cc8edSafresh1die_sv(pTHX_ SV *baseex)
845759b3d2Safresh1{
85de8cc8edSafresh1    croak_sv(baseex);
865759b3d2Safresh1    return (OP *)NULL;
875759b3d2Safresh1}
885759b3d2Safresh1#endif
895759b3d2Safresh1#endif
905759b3d2Safresh1
915759b3d2Safresh1#ifndef warn_sv
925759b3d2Safresh1#if { VERSION >= 5.4.0 }
935759b3d2Safresh1#  define warn_sv(sv) warn("%" SVf, SVfARG(sv))
945759b3d2Safresh1#else
955759b3d2Safresh1#  define warn_sv(sv) warn("%s", SvPV_nolen(sv))
965759b3d2Safresh1#endif
975759b3d2Safresh1#endif
985759b3d2Safresh1
99de8cc8edSafresh1#if ! defined vmess && { VERSION >= 5.4.0 }
1005759b3d2Safresh1#  if { NEED vmess }
101de8cc8edSafresh1
1025759b3d2Safresh1SV*
1035759b3d2Safresh1vmess(pTHX_ const char* pat, va_list* args)
1045759b3d2Safresh1{
1055759b3d2Safresh1    mess(pat, args);
1065759b3d2Safresh1    return PL_mess_sv;
1075759b3d2Safresh1}
1085759b3d2Safresh1#  endif
1095759b3d2Safresh1#endif
1105759b3d2Safresh1
111de8cc8edSafresh1#if { VERSION < 5.6.0 } && { VERSION >= 5.4.0 }
1125759b3d2Safresh1#undef mess
1135759b3d2Safresh1#endif
1145759b3d2Safresh1
115de8cc8edSafresh1#if !defined(mess_nocontext) && !defined(Perl_mess_nocontext) && { VERSION >= 5.4.0 }
1165759b3d2Safresh1#if { NEED mess_nocontext }
1175759b3d2Safresh1SV*
1185759b3d2Safresh1mess_nocontext(const char* pat, ...)
1195759b3d2Safresh1{
1205759b3d2Safresh1    dTHX;
1215759b3d2Safresh1    SV *sv;
1225759b3d2Safresh1    va_list args;
1235759b3d2Safresh1    va_start(args, pat);
1245759b3d2Safresh1    sv = vmess(pat, &args);
1255759b3d2Safresh1    va_end(args);
1265759b3d2Safresh1    return sv;
1275759b3d2Safresh1}
1285759b3d2Safresh1#endif
1295759b3d2Safresh1#endif
1305759b3d2Safresh1
1315759b3d2Safresh1#ifndef mess
1325759b3d2Safresh1#if { NEED mess }
1335759b3d2Safresh1SV*
1345759b3d2Safresh1mess(pTHX_ const char* pat, ...)
1355759b3d2Safresh1{
1365759b3d2Safresh1    SV *sv;
1375759b3d2Safresh1    va_list args;
1385759b3d2Safresh1    va_start(args, pat);
1395759b3d2Safresh1    sv = vmess(pat, &args);
1405759b3d2Safresh1    va_end(args);
1415759b3d2Safresh1    return sv;
1425759b3d2Safresh1}
1435759b3d2Safresh1#ifdef mess_nocontext
1445759b3d2Safresh1#define mess mess_nocontext
1455759b3d2Safresh1#else
1465759b3d2Safresh1#define mess Perl_mess_nocontext
1475759b3d2Safresh1#endif
1485759b3d2Safresh1#endif
1495759b3d2Safresh1#endif
1505759b3d2Safresh1
151de8cc8edSafresh1#if ! defined mess_sv && { VERSION >= 5.4.0 }
1525759b3d2Safresh1#if { NEED mess_sv }
1535759b3d2Safresh1SV *
1545759b3d2Safresh1mess_sv(pTHX_ SV *basemsg, bool consume)
1555759b3d2Safresh1{
1565759b3d2Safresh1    SV *tmp;
1575759b3d2Safresh1    SV *ret;
1585759b3d2Safresh1
1595759b3d2Safresh1    if (SvPOK(basemsg) && SvCUR(basemsg) && *(SvEND(basemsg)-1) == '\n') {
1605759b3d2Safresh1        if (consume)
1615759b3d2Safresh1            return basemsg;
1625759b3d2Safresh1        ret = mess("");
1635759b3d2Safresh1        SvSetSV_nosteal(ret, basemsg);
1645759b3d2Safresh1        return ret;
1655759b3d2Safresh1    }
1665759b3d2Safresh1
1675759b3d2Safresh1    if (consume) {
1685759b3d2Safresh1        sv_catsv(basemsg, mess(""));
1695759b3d2Safresh1        return basemsg;
1705759b3d2Safresh1    }
1715759b3d2Safresh1
1725759b3d2Safresh1    ret = mess("");
1735759b3d2Safresh1    tmp = newSVsv(ret);
1745759b3d2Safresh1    SvSetSV_nosteal(ret, basemsg);
1755759b3d2Safresh1    sv_catsv(ret, tmp);
1765759b3d2Safresh1    sv_dec(tmp);
1775759b3d2Safresh1    return ret;
1785759b3d2Safresh1}
1795759b3d2Safresh1#endif
1805759b3d2Safresh1#endif
1815759b3d2Safresh1
1825759b3d2Safresh1#ifndef warn_nocontext
1835759b3d2Safresh1#define warn_nocontext warn
1845759b3d2Safresh1#endif
1855759b3d2Safresh1
1865759b3d2Safresh1#ifndef croak_nocontext
1875759b3d2Safresh1#define croak_nocontext croak
1885759b3d2Safresh1#endif
1895759b3d2Safresh1
1905759b3d2Safresh1#ifndef croak_no_modify
1915759b3d2Safresh1#define croak_no_modify() croak_nocontext("%s", PL_no_modify)
1925759b3d2Safresh1#define Perl_croak_no_modify() croak_no_modify()
1935759b3d2Safresh1#endif
1945759b3d2Safresh1
1955759b3d2Safresh1#ifndef croak_memory_wrap
1965759b3d2Safresh1#if { VERSION >= 5.9.2 } || ( { VERSION >= 5.8.6 } && { VERSION < 5.9.0 } )
1975759b3d2Safresh1#  define croak_memory_wrap() croak_nocontext("%s", PL_memory_wrap)
1985759b3d2Safresh1#else
1995759b3d2Safresh1#  define croak_memory_wrap() croak_nocontext("panic: memory wrap")
2005759b3d2Safresh1#endif
2015759b3d2Safresh1#endif
2025759b3d2Safresh1
2035759b3d2Safresh1#ifndef croak_xs_usage
2045759b3d2Safresh1#if { NEED croak_xs_usage }
2059a4edab6Sbluhm#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
2069a4edab6Sbluhm#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)
2075759b3d2Safresh1
2085759b3d2Safresh1void
2095759b3d2Safresh1croak_xs_usage(const CV *const cv, const char *const params)
2105759b3d2Safresh1{
2115759b3d2Safresh1    dTHX;
2125759b3d2Safresh1    const GV *const gv = CvGV(cv);
2135759b3d2Safresh1
2145759b3d2Safresh1    PERL_ARGS_ASSERT_CROAK_XS_USAGE;
2155759b3d2Safresh1
2165759b3d2Safresh1    if (gv) {
2175759b3d2Safresh1        const char *const gvname = GvNAME(gv);
2185759b3d2Safresh1        const HV *const stash = GvSTASH(gv);
2195759b3d2Safresh1        const char *const hvname = stash ? HvNAME(stash) : NULL;
2205759b3d2Safresh1
2215759b3d2Safresh1        if (hvname)
2225759b3d2Safresh1            croak("Usage: %s::%s(%s)", hvname, gvname, params);
2235759b3d2Safresh1        else
2245759b3d2Safresh1            croak("Usage: %s(%s)", gvname, params);
2255759b3d2Safresh1    } else {
2265759b3d2Safresh1        /* Pants. I don't think that it should be possible to get here. */
2275759b3d2Safresh1        croak("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
2285759b3d2Safresh1    }
2295759b3d2Safresh1}
2305759b3d2Safresh1#endif
2315759b3d2Safresh1#endif
2329a4edab6Sbluhm#endif
2335759b3d2Safresh1
2345759b3d2Safresh1=xsinit
2355759b3d2Safresh1
2365759b3d2Safresh1#define NEED_die_sv
2375759b3d2Safresh1#define NEED_mess_sv
2385759b3d2Safresh1#define NEED_croak_xs_usage
2395759b3d2Safresh1
240de8cc8edSafresh1=xsmisc
241de8cc8edSafresh1
242de8cc8edSafresh1static IV counter;
243de8cc8edSafresh1static void reset_counter(void) { counter = 0; }
244de8cc8edSafresh1static void inc_counter(void) { counter++; }
245de8cc8edSafresh1
2465759b3d2Safresh1=xsubs
2475759b3d2Safresh1
2485759b3d2Safresh1void
2495759b3d2Safresh1croak_sv(sv)
2505759b3d2Safresh1    SV *sv
2515759b3d2Safresh1CODE:
2525759b3d2Safresh1    croak_sv(sv);
2535759b3d2Safresh1
2545759b3d2Safresh1void
255de8cc8edSafresh1croak_sv_errsv()
256de8cc8edSafresh1CODE:
257de8cc8edSafresh1    croak_sv(ERRSV);
258de8cc8edSafresh1
259de8cc8edSafresh1void
260de8cc8edSafresh1croak_sv_with_counter(sv)
261de8cc8edSafresh1    SV *sv
262de8cc8edSafresh1CODE:
263de8cc8edSafresh1    reset_counter();
264de8cc8edSafresh1    croak_sv((inc_counter(), sv));
265de8cc8edSafresh1
266de8cc8edSafresh1IV
267de8cc8edSafresh1get_counter()
268de8cc8edSafresh1CODE:
269de8cc8edSafresh1    RETVAL = counter;
270de8cc8edSafresh1OUTPUT:
271de8cc8edSafresh1    RETVAL
272de8cc8edSafresh1
273de8cc8edSafresh1void
2745759b3d2Safresh1die_sv(sv)
2755759b3d2Safresh1    SV *sv
2765759b3d2Safresh1CODE:
2775759b3d2Safresh1    (void)die_sv(sv);
2785759b3d2Safresh1
2795759b3d2Safresh1void
2805759b3d2Safresh1warn_sv(sv)
2815759b3d2Safresh1    SV *sv
2825759b3d2Safresh1CODE:
2835759b3d2Safresh1    warn_sv(sv);
2845759b3d2Safresh1
285de8cc8edSafresh1#if { VERSION >= 5.4.0 }
286de8cc8edSafresh1
2875759b3d2Safresh1SV *
2885759b3d2Safresh1mess_sv(sv, consume)
2895759b3d2Safresh1    SV *sv
2905759b3d2Safresh1    bool consume
2915759b3d2Safresh1CODE:
2925759b3d2Safresh1    RETVAL = newSVsv(mess_sv(sv, consume));
2935759b3d2Safresh1OUTPUT:
2945759b3d2Safresh1    RETVAL
2955759b3d2Safresh1
296de8cc8edSafresh1#endif
297de8cc8edSafresh1
2985759b3d2Safresh1void
2995759b3d2Safresh1croak_no_modify()
3005759b3d2Safresh1CODE:
3015759b3d2Safresh1    croak_no_modify();
3025759b3d2Safresh1
3035759b3d2Safresh1void
3045759b3d2Safresh1croak_memory_wrap()
3055759b3d2Safresh1CODE:
3065759b3d2Safresh1    croak_memory_wrap();
3075759b3d2Safresh1
3085759b3d2Safresh1void
3095759b3d2Safresh1croak_xs_usage(params)
3105759b3d2Safresh1    char *params
3115759b3d2Safresh1CODE:
3125759b3d2Safresh1    croak_xs_usage(cv, params);
3135759b3d2Safresh1
314de8cc8edSafresh1=tests plan => 102
3155759b3d2Safresh1
3169a4edab6SbluhmBEGIN { if (ivers($]) < ivers('5.006')) { $^W = 0; } }
3175759b3d2Safresh1
3185759b3d2Safresh1my $warn;
3195759b3d2Safresh1my $die;
3205759b3d2Safresh1local $SIG{__WARN__} = sub { $warn = $_[0] };
3215759b3d2Safresh1local $SIG{__DIE__} = sub { $die = $_[0] };
3225759b3d2Safresh1
3235759b3d2Safresh1my $scalar_ref = \do {my $tmp = 10};
3245759b3d2Safresh1my $array_ref = [];
3255759b3d2Safresh1my $hash_ref = {};
3265759b3d2Safresh1my $obj = bless {}, 'Package';
3275759b3d2Safresh1
3285759b3d2Safresh1undef $die;
3295759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_sv("\xE1\n") };
330de8cc8edSafresh1is $@, "\xE1\n";
331de8cc8edSafresh1is $die, "\xE1\n";
3325759b3d2Safresh1
3335759b3d2Safresh1undef $die;
3345759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_sv(10) };
335de8cc8edSafresh1ok $@ =~ /^10 at \Q$0\E line /;
336de8cc8edSafresh1ok $die =~ /^10 at \Q$0\E line /;
3375759b3d2Safresh1
3385759b3d2Safresh1undef $die;
3395759b3d2Safresh1$@ = 'should not be visible (1)';
3405759b3d2Safresh1ok !defined eval {
3415759b3d2Safresh1    $@ = 'should not be visible (2)';
3425759b3d2Safresh1    Devel::PPPort::croak_sv('');
3435759b3d2Safresh1};
344de8cc8edSafresh1ok $@ =~ /^ at \Q$0\E line /;
345de8cc8edSafresh1ok $die =~ /^ at \Q$0\E line /;
3465759b3d2Safresh1
3475759b3d2Safresh1undef $die;
3485759b3d2Safresh1$@ = 'should not be visible';
3495759b3d2Safresh1ok !defined eval {
3505759b3d2Safresh1    $@ = 'this must be visible';
3515759b3d2Safresh1    Devel::PPPort::croak_sv($@)
3525759b3d2Safresh1};
353de8cc8edSafresh1ok $@ =~ /^this must be visible at \Q$0\E line /;
354de8cc8edSafresh1ok $die =~ /^this must be visible at \Q$0\E line /;
3555759b3d2Safresh1
3565759b3d2Safresh1undef $die;
3575759b3d2Safresh1$@ = 'should not be visible';
3585759b3d2Safresh1ok !defined eval {
3595759b3d2Safresh1    $@ = "this must be visible\n";
3605759b3d2Safresh1    Devel::PPPort::croak_sv($@)
3615759b3d2Safresh1};
362de8cc8edSafresh1is $@, "this must be visible\n";
363de8cc8edSafresh1is $die, "this must be visible\n";
364de8cc8edSafresh1
365de8cc8edSafresh1undef $die;
366de8cc8edSafresh1$@ = 'should not be visible';
367de8cc8edSafresh1ok !defined eval {
368de8cc8edSafresh1    $@ = 'this must be visible';
369de8cc8edSafresh1    Devel::PPPort::croak_sv_errsv()
370de8cc8edSafresh1};
371de8cc8edSafresh1ok $@ =~ /^this must be visible at \Q$0\E line /;
372de8cc8edSafresh1ok $die =~ /^this must be visible at \Q$0\E line /;
373de8cc8edSafresh1
374de8cc8edSafresh1undef $die;
375de8cc8edSafresh1$@ = 'should not be visible';
376de8cc8edSafresh1ok !defined eval {
377de8cc8edSafresh1    $@ = "this must be visible\n";
378de8cc8edSafresh1    Devel::PPPort::croak_sv_errsv()
379de8cc8edSafresh1};
380de8cc8edSafresh1is $@, "this must be visible\n";
381de8cc8edSafresh1is $die, "this must be visible\n";
382de8cc8edSafresh1
383de8cc8edSafresh1undef $die;
384de8cc8edSafresh1ok !defined eval { Devel::PPPort::croak_sv_with_counter("message\n") };
385de8cc8edSafresh1is $@, "message\n";
386de8cc8edSafresh1is Devel::PPPort::get_counter(), 1;
3875759b3d2Safresh1
3885759b3d2Safresh1undef $die;
3895759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_sv('') };
390de8cc8edSafresh1ok $@ =~ /^ at \Q$0\E line /;
391de8cc8edSafresh1ok $die =~ /^ at \Q$0\E line /;
3925759b3d2Safresh1
3935759b3d2Safresh1undef $die;
3945759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_sv("\xE1") };
395de8cc8edSafresh1ok $@ =~ /^\xE1 at \Q$0\E line /;
396de8cc8edSafresh1ok $die =~ /^\xE1 at \Q$0\E line /;
3975759b3d2Safresh1
3985759b3d2Safresh1undef $die;
3995759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_sv("\xC3\xA1") };
400de8cc8edSafresh1ok $@ =~ /^\xC3\xA1 at \Q$0\E line /;
401de8cc8edSafresh1ok $die =~ /^\xC3\xA1 at \Q$0\E line /;
4025759b3d2Safresh1
4035759b3d2Safresh1undef $warn;
4045759b3d2Safresh1Devel::PPPort::warn_sv("\xE1\n");
405de8cc8edSafresh1is $warn, "\xE1\n";
4065759b3d2Safresh1
4075759b3d2Safresh1undef $warn;
4085759b3d2Safresh1Devel::PPPort::warn_sv(10);
409de8cc8edSafresh1ok $warn =~ /^10 at \Q$0\E line /;
4105759b3d2Safresh1
4115759b3d2Safresh1undef $warn;
4125759b3d2Safresh1Devel::PPPort::warn_sv('');
413de8cc8edSafresh1ok $warn =~ /^ at \Q$0\E line /;
4145759b3d2Safresh1
4155759b3d2Safresh1undef $warn;
4165759b3d2Safresh1Devel::PPPort::warn_sv("\xE1");
417de8cc8edSafresh1ok $warn =~ /^\xE1 at \Q$0\E line /;
4185759b3d2Safresh1
4195759b3d2Safresh1undef $warn;
4205759b3d2Safresh1Devel::PPPort::warn_sv("\xC3\xA1");
421de8cc8edSafresh1ok $warn =~ /^\xC3\xA1 at \Q$0\E line /;
4225759b3d2Safresh1
423de8cc8edSafresh1is Devel::PPPort::mess_sv("\xE1\n", 0), "\xE1\n";
424de8cc8edSafresh1is Devel::PPPort::mess_sv(do {my $tmp = "\xE1\n"}, 1), "\xE1\n";
4255759b3d2Safresh1
426de8cc8edSafresh1ok Devel::PPPort::mess_sv(10, 0) =~ /^10 at \Q$0\E line /;
427de8cc8edSafresh1ok Devel::PPPort::mess_sv(do {my $tmp = 10}, 1) =~ /^10 at \Q$0\E line /;
4285759b3d2Safresh1
429de8cc8edSafresh1ok Devel::PPPort::mess_sv('', 0) =~ /^ at \Q$0\E line /;
430de8cc8edSafresh1ok Devel::PPPort::mess_sv(do {my $tmp = ''}, 1) =~ /^ at \Q$0\E line /;
4315759b3d2Safresh1
432de8cc8edSafresh1ok Devel::PPPort::mess_sv("\xE1", 0) =~ /^\xE1 at \Q$0\E line /;
433de8cc8edSafresh1ok Devel::PPPort::mess_sv(do {my $tmp = "\xE1"}, 1) =~ /^\xE1 at \Q$0\E line /;
4345759b3d2Safresh1
435de8cc8edSafresh1ok Devel::PPPort::mess_sv("\xC3\xA1", 0) =~ /^\xC3\xA1 at \Q$0\E line /;
436de8cc8edSafresh1ok Devel::PPPort::mess_sv(do {my $tmp = "\xC3\xA1"}, 1) =~ /^\xC3\xA1 at \Q$0\E line /;
4375759b3d2Safresh1
4389a4edab6Sbluhmif (ivers($]) >= ivers('5.006')) {
4399a4edab6Sbluhm    BEGIN { if (ivers($]) >= ivers('5.006') && ivers($]) < ivers('5.008')) { require utf8; utf8->import(); } }
4405759b3d2Safresh1
4415759b3d2Safresh1    undef $die;
4425759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv("\x{100}\n") };
4439a4edab6Sbluhm    if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.007003')) {
444de8cc8edSafresh1        is $@, "\x{100}\n";
4455759b3d2Safresh1    } else {
446de8cc8edSafresh1        skip 'skip: broken utf8 support in die hook', 1;
447de8cc8edSafresh1    }
4489a4edab6Sbluhm    if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.008')) {
449de8cc8edSafresh1        is $die, "\x{100}\n";
450de8cc8edSafresh1    } else {
451de8cc8edSafresh1        skip 'skip: broken utf8 support in die hook', 1;
4525759b3d2Safresh1    }
4535759b3d2Safresh1
4545759b3d2Safresh1    undef $die;
4555759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv("\x{100}") };
4569a4edab6Sbluhm    if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.007003')) {
457de8cc8edSafresh1        ok $@ =~ /^\x{100} at \Q$0\E line /;
4585759b3d2Safresh1    } else {
459de8cc8edSafresh1        skip 'skip: broken utf8 support in die hook', 1;
460de8cc8edSafresh1    }
4619a4edab6Sbluhm    if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.008')) {
462de8cc8edSafresh1        ok $die =~ /^\x{100} at \Q$0\E line /;
463de8cc8edSafresh1    } else {
464de8cc8edSafresh1        skip 'skip: broken utf8 support in die hook', 1;
4655759b3d2Safresh1    }
4665759b3d2Safresh1
4679a4edab6Sbluhm    if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.008')) {
4685759b3d2Safresh1        undef $warn;
4695759b3d2Safresh1        Devel::PPPort::warn_sv("\x{100}\n");
470de8cc8edSafresh1        is $warn, "\x{100}\n";
4715759b3d2Safresh1
4725759b3d2Safresh1        undef $warn;
4735759b3d2Safresh1        Devel::PPPort::warn_sv("\x{100}");
474de8cc8edSafresh1        ok (my $tmp = $warn) =~ /^\x{100} at \Q$0\E line /;
4755759b3d2Safresh1    } else {
476de8cc8edSafresh1        skip 'skip: broken utf8 support in warn hook', 2;
4775759b3d2Safresh1    }
4785759b3d2Safresh1
479de8cc8edSafresh1    is Devel::PPPort::mess_sv("\x{100}\n", 0), "\x{100}\n";
480de8cc8edSafresh1    is Devel::PPPort::mess_sv(do {my $tmp = "\x{100}\n"}, 1), "\x{100}\n";
4815759b3d2Safresh1
482de8cc8edSafresh1    ok Devel::PPPort::mess_sv("\x{100}", 0) =~ /^\x{100} at \Q$0\E line /;
483de8cc8edSafresh1    ok Devel::PPPort::mess_sv(do {my $tmp = "\x{100}"}, 1) =~ /^\x{100} at \Q$0\E line /;
4845759b3d2Safresh1} else {
485de8cc8edSafresh1    skip 'skip: no utf8 support', 12;
4865759b3d2Safresh1}
4875759b3d2Safresh1
4885759b3d2Safresh1if (ord('A') != 65) {
489de8cc8edSafresh1    skip 'skip: no ASCII support', 24;
4909a4edab6Sbluhm} elsif (      ivers($]) >= ivers('5.008')
4919a4edab6Sbluhm         &&    ivers($]) != ivers('5.013000')     # Broken in these ranges
4929a4edab6Sbluhm         && ! (ivers($]) >= ivers('5.011005') && ivers($]) <= ivers('5.012000')))
493de8cc8edSafresh1{
4945759b3d2Safresh1    undef $die;
4955759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv(eval '"\N{U+E1}\n"') };
496de8cc8edSafresh1    is $@, "\xE1\n";
497de8cc8edSafresh1    is $die, "\xE1\n";
4985759b3d2Safresh1
4995759b3d2Safresh1    undef $die;
5005759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv(eval '"\N{U+E1}"') };
501de8cc8edSafresh1    ok $@ =~ /^\xE1 at \Q$0\E line /;
502de8cc8edSafresh1    ok $die =~ /^\xE1 at \Q$0\E line /;
5035759b3d2Safresh1
5045759b3d2Safresh1    {
5055759b3d2Safresh1        undef $die;
5065759b3d2Safresh1        my $expect = eval '"\N{U+C3}\N{U+A1}\n"';
5075759b3d2Safresh1        ok !defined eval { Devel::PPPort::croak_sv("\xC3\xA1\n") };
508de8cc8edSafresh1        is $@, $expect;
509de8cc8edSafresh1        is $die, $expect;
5105759b3d2Safresh1    }
5115759b3d2Safresh1
5125759b3d2Safresh1    {
5135759b3d2Safresh1        undef $die;
514de8cc8edSafresh1        my $expect = eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
5155759b3d2Safresh1        ok !defined eval { Devel::PPPort::croak_sv("\xC3\xA1") };
5165759b3d2Safresh1        ok $@ =~ $expect;
5175759b3d2Safresh1        ok $die =~ $expect;
5185759b3d2Safresh1    }
5195759b3d2Safresh1
5205759b3d2Safresh1    undef $warn;
5215759b3d2Safresh1    Devel::PPPort::warn_sv(eval '"\N{U+E1}\n"');
522de8cc8edSafresh1    is $warn, "\xE1\n";
5235759b3d2Safresh1
5245759b3d2Safresh1    undef $warn;
5255759b3d2Safresh1    Devel::PPPort::warn_sv(eval '"\N{U+E1}"');
526de8cc8edSafresh1    ok $warn =~ /^\xE1 at \Q$0\E line /;
5275759b3d2Safresh1
5285759b3d2Safresh1    undef $warn;
5295759b3d2Safresh1    Devel::PPPort::warn_sv("\xC3\xA1\n");
530de8cc8edSafresh1    is $warn, eval '"\N{U+C3}\N{U+A1}\n"';
5315759b3d2Safresh1
5325759b3d2Safresh1    undef $warn;
5335759b3d2Safresh1    Devel::PPPort::warn_sv("\xC3\xA1");
534de8cc8edSafresh1    ok $warn =~ eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
5355759b3d2Safresh1
5369a4edab6Sbluhm    if (ivers($]) < ivers('5.004')) {
537de8cc8edSafresh1        skip 'skip: no support for mess_sv', 8;
538de8cc8edSafresh1    }
539de8cc8edSafresh1    else {
540de8cc8edSafresh1      is Devel::PPPort::mess_sv(eval('"\N{U+E1}\n"'), 0), eval '"\N{U+E1}\n"';
541de8cc8edSafresh1      is Devel::PPPort::mess_sv(do {my $tmp = eval '"\N{U+E1}\n"'}, 1), eval '"\N{U+E1}\n"';
5425759b3d2Safresh1
543de8cc8edSafresh1      ok Devel::PPPort::mess_sv(eval('"\N{U+E1}"'), 0) =~ eval 'qr/^\N{U+E1} at \Q$0\E line /';
544de8cc8edSafresh1      ok Devel::PPPort::mess_sv(do {my $tmp = eval '"\N{U+E1}"'}, 1) =~ eval 'qr/^\N{U+E1} at \Q$0\E line /';
5455759b3d2Safresh1
546de8cc8edSafresh1      is Devel::PPPort::mess_sv("\xC3\xA1\n", 0), eval '"\N{U+C3}\N{U+A1}\n"';
547de8cc8edSafresh1      is Devel::PPPort::mess_sv(do {my $tmp = "\xC3\xA1\n"}, 1), eval '"\N{U+C3}\N{U+A1}\n"';
5485759b3d2Safresh1
549de8cc8edSafresh1      ok Devel::PPPort::mess_sv("\xC3\xA1", 0) =~ eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
550de8cc8edSafresh1      ok Devel::PPPort::mess_sv(do {my $tmp = "\xC3\xA1"}, 1) =~ eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
551de8cc8edSafresh1    }
5525759b3d2Safresh1} else {
553de8cc8edSafresh1    skip 'skip: no support for \N{U+..} syntax', 24;
5545759b3d2Safresh1}
5555759b3d2Safresh1
5569a4edab6Sbluhmif (ivers($]) >= ivers('5.007003') or (ivers($]) >= ivers('5.006001') and ivers($]) < ivers('5.007'))) {
5575759b3d2Safresh1    undef $die;
5585759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv($scalar_ref) };
5595759b3d2Safresh1    ok $@ == $scalar_ref;
5605759b3d2Safresh1    ok $die == $scalar_ref;
5615759b3d2Safresh1
5625759b3d2Safresh1    undef $die;
5635759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv($array_ref) };
5645759b3d2Safresh1    ok $@ == $array_ref;
5655759b3d2Safresh1    ok $die == $array_ref;
5665759b3d2Safresh1
5675759b3d2Safresh1    undef $die;
5685759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv($hash_ref) };
5695759b3d2Safresh1    ok $@ == $hash_ref;
5705759b3d2Safresh1    ok $die == $hash_ref;
5715759b3d2Safresh1
5725759b3d2Safresh1    undef $die;
5735759b3d2Safresh1    ok !defined eval { Devel::PPPort::croak_sv($obj) };
5745759b3d2Safresh1    ok $@ == $obj;
5755759b3d2Safresh1    ok $die == $obj;
5765759b3d2Safresh1} else {
577de8cc8edSafresh1    skip 'skip: no support for exceptions', 12;
5785759b3d2Safresh1}
5795759b3d2Safresh1
5805759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_no_modify() };
581de8cc8edSafresh1ok $@ =~ /^Modification of a read-only value attempted at \Q$0\E line /;
5825759b3d2Safresh1
5835759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_memory_wrap() };
584de8cc8edSafresh1ok $@ =~ /^panic: memory wrap at \Q$0\E line /;
5855759b3d2Safresh1
5865759b3d2Safresh1ok !defined eval { Devel::PPPort::croak_xs_usage("params") };
587de8cc8edSafresh1ok $@ =~ /^Usage: Devel::PPPort::croak_xs_usage\(params\) at \Q$0\E line /;
588