This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Devel-PPPort to release 3.62
[perl5.git] / dist / Devel-PPPort / parts / inc / mess
CommitLineData
f87c37b1
P
1################################################################################
2##
3## Copyright (C) 2017, Pali <pali@cpan.org>
4##
5## This program is free software; you can redistribute it and/or
6## modify it under the same terms as Perl itself.
7##
8################################################################################
9
10=provides
11
12croak_sv
13die_sv
14mess_sv
15warn_sv
16
17vmess
18mess_nocontext
19mess
20
21warn_nocontext
f87c37b1
P
22
23croak_nocontext
46677718 24PERL_ARGS_ASSERT_CROAK_XS_USAGE
f87c37b1
P
25
26croak_no_modify
27Perl_croak_no_modify
28
29croak_memory_wrap
30croak_xs_usage
31
f87c37b1
P
32=dontwarn
33
34NEED_mess
35NEED_mess_nocontext
36NEED_vmess
f87c37b1
P
37
38=implementation
39
40#ifdef NEED_mess_sv
41#define NEED_mess
42#endif
43
44#ifdef NEED_mess
45#define NEED_mess_nocontext
46#define NEED_vmess
47#endif
48
49#ifndef croak_sv
50#if { VERSION >= 5.7.3 } || ( { VERSION >= 5.6.1 } && { VERSION < 5.7.0 } )
51# if ( { VERSION >= 5.8.0 } && { VERSION < 5.8.9 } ) || ( { VERSION >= 5.9.0 } && { VERSION < 5.10.1 } )
f1305528
P
52# define D_PPP_FIX_UTF8_ERRSV_FOR_SV(sv) \
53 STMT_START { \
54 SV *_errsv = ERRSV; \
55 SvFLAGS(_errsv) = (SvFLAGS(_errsv) & ~SVf_UTF8) | \
56 (SvFLAGS(sv) & SVf_UTF8); \
f87c37b1
P
57 } STMT_END
58# else
f1305528 59# define D_PPP_FIX_UTF8_ERRSV_FOR_SV(sv) STMT_START {} STMT_END
f87c37b1 60# endif
f1305528
P
61# define croak_sv(sv) \
62 STMT_START { \
63 SV *_sv = (sv); \
64 if (SvROK(_sv)) { \
65 sv_setsv(ERRSV, _sv); \
66 croak(NULL); \
67 } else { \
68 D_PPP_FIX_UTF8_ERRSV_FOR_SV(_sv); \
69 croak("%" SVf, SVfARG(_sv)); \
70 } \
f87c37b1
P
71 } STMT_END
72#elif { VERSION >= 5.4.0 }
73# define croak_sv(sv) croak("%" SVf, SVfARG(sv))
74#else
75# define croak_sv(sv) croak("%s", SvPV_nolen(sv))
76#endif
77#endif
78
79#ifndef die_sv
80#if { NEED die_sv }
81OP *
3250a268 82die_sv(pTHX_ SV *baseex)
f87c37b1 83{
3250a268 84 croak_sv(baseex);
f87c37b1
P
85 return (OP *)NULL;
86}
87#endif
88#endif
89
90#ifndef warn_sv
91#if { VERSION >= 5.4.0 }
92# define warn_sv(sv) warn("%" SVf, SVfARG(sv))
93#else
94# define warn_sv(sv) warn("%s", SvPV_nolen(sv))
95#endif
96#endif
97
c94bdf46
KW
98#if ! defined vmess && { VERSION >= 5.4.0 }
99# if { NEED vmess }
100
f87c37b1
P
101SV*
102vmess(pTHX_ const char* pat, va_list* args)
103{
104 mess(pat, args);
105 return PL_mess_sv;
106}
c94bdf46 107# endif
f87c37b1
P
108#endif
109
c94bdf46 110#if { VERSION < 5.6.0 } && { VERSION >= 5.4.0 }
f87c37b1
P
111#undef mess
112#endif
113
c94bdf46 114#if !defined(mess_nocontext) && !defined(Perl_mess_nocontext) && { VERSION >= 5.4.0 }
f87c37b1
P
115#if { NEED mess_nocontext }
116SV*
117mess_nocontext(const char* pat, ...)
118{
119 dTHX;
120 SV *sv;
121 va_list args;
122 va_start(args, pat);
123 sv = vmess(pat, &args);
124 va_end(args);
125 return sv;
126}
127#endif
128#endif
129
130#ifndef mess
131#if { NEED mess }
132SV*
133mess(pTHX_ const char* pat, ...)
134{
135 SV *sv;
136 va_list args;
137 va_start(args, pat);
138 sv = vmess(pat, &args);
139 va_end(args);
140 return sv;
141}
142#ifdef mess_nocontext
143#define mess mess_nocontext
144#else
145#define mess Perl_mess_nocontext
146#endif
147#endif
148#endif
149
c94bdf46 150#if ! defined mess_sv && { VERSION >= 5.4.0 }
f87c37b1
P
151#if { NEED mess_sv }
152SV *
153mess_sv(pTHX_ SV *basemsg, bool consume)
154{
155 SV *tmp;
156 SV *ret;
157
158 if (SvPOK(basemsg) && SvCUR(basemsg) && *(SvEND(basemsg)-1) == '\n') {
159 if (consume)
160 return basemsg;
161 ret = mess("");
162 SvSetSV_nosteal(ret, basemsg);
163 return ret;
164 }
165
166 if (consume) {
167 sv_catsv(basemsg, mess(""));
168 return basemsg;
169 }
170
171 ret = mess("");
172 tmp = newSVsv(ret);
173 SvSetSV_nosteal(ret, basemsg);
174 sv_catsv(ret, tmp);
175 sv_dec(tmp);
176 return ret;
177}
178#endif
179#endif
180
181#ifndef warn_nocontext
182#define warn_nocontext warn
183#endif
184
f87c37b1
P
185#ifndef croak_nocontext
186#define croak_nocontext croak
187#endif
188
f87c37b1 189#ifndef croak_no_modify
95afac5c 190#define croak_no_modify() croak_nocontext("%s", PL_no_modify)
f87c37b1
P
191#define Perl_croak_no_modify() croak_no_modify()
192#endif
193
194#ifndef croak_memory_wrap
195#if { VERSION >= 5.9.2 } || ( { VERSION >= 5.8.6 } && { VERSION < 5.9.0 } )
95afac5c 196# define croak_memory_wrap() croak_nocontext("%s", PL_memory_wrap)
f87c37b1 197#else
95afac5c 198# define croak_memory_wrap() croak_nocontext("panic: memory wrap")
f87c37b1
P
199#endif
200#endif
201
368e5f5e
TC
202#ifndef croak_xs_usage
203#if { NEED croak_xs_usage }
46677718
N
204#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
205#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)
f87c37b1 206
f87c37b1 207void
0e9335ba 208croak_xs_usage(const CV *const cv, const char *const params)
f87c37b1 209{
d397b1c4 210 dTHX;
f87c37b1
P
211 const GV *const gv = CvGV(cv);
212
213 PERL_ARGS_ASSERT_CROAK_XS_USAGE;
214
215 if (gv) {
216 const char *const gvname = GvNAME(gv);
217 const HV *const stash = GvSTASH(gv);
218 const char *const hvname = stash ? HvNAME(stash) : NULL;
219
220 if (hvname)
221 croak("Usage: %s::%s(%s)", hvname, gvname, params);
222 else
223 croak("Usage: %s(%s)", gvname, params);
224 } else {
225 /* Pants. I don't think that it should be possible to get here. */
226 croak("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
227 }
228}
229#endif
230#endif
46677718 231#endif
f87c37b1
P
232
233=xsinit
234
235#define NEED_die_sv
236#define NEED_mess_sv
237#define NEED_croak_xs_usage
238
f1305528
P
239=xsmisc
240
241static IV counter;
242static void reset_counter(void) { counter = 0; }
243static void inc_counter(void) { counter++; }
244
f87c37b1
P
245=xsubs
246
247void
248croak_sv(sv)
249 SV *sv
250CODE:
251 croak_sv(sv);
252
253void
f1305528
P
254croak_sv_errsv()
255CODE:
256 croak_sv(ERRSV);
257
258void
259croak_sv_with_counter(sv)
260 SV *sv
261CODE:
262 reset_counter();
263 croak_sv((inc_counter(), sv));
264
265IV
266get_counter()
267CODE:
268 RETVAL = counter;
269OUTPUT:
270 RETVAL
271
272void
f87c37b1
P
273die_sv(sv)
274 SV *sv
f87c37b1 275CODE:
61862610 276 (void)die_sv(sv);
f87c37b1
P
277
278void
279warn_sv(sv)
280 SV *sv
281CODE:
282 warn_sv(sv);
283
c94bdf46
KW
284#if { VERSION >= 5.4.0 }
285
f87c37b1
P
286SV *
287mess_sv(sv, consume)
288 SV *sv
289 bool consume
290CODE:
291 RETVAL = newSVsv(mess_sv(sv, consume));
292OUTPUT:
293 RETVAL
294
c94bdf46
KW
295#endif
296
f87c37b1
P
297void
298croak_no_modify()
299CODE:
300 croak_no_modify();
301
302void
303croak_memory_wrap()
304CODE:
305 croak_memory_wrap();
306
307void
308croak_xs_usage(params)
309 char *params
310CODE:
311 croak_xs_usage(cv, params);
312
f1305528 313=tests plan => 102
f87c37b1 314
c8799aff 315BEGIN { if (ivers($]) < ivers('5.006')) { $^W = 0; } }
f87c37b1
P
316
317my $warn;
318my $die;
319local $SIG{__WARN__} = sub { $warn = $_[0] };
320local $SIG{__DIE__} = sub { $die = $_[0] };
321
322my $scalar_ref = \do {my $tmp = 10};
323my $array_ref = [];
324my $hash_ref = {};
325my $obj = bless {}, 'Package';
326
327undef $die;
328ok !defined eval { Devel::PPPort::croak_sv("\xE1\n") };
8154c0b1
KW
329is $@, "\xE1\n";
330is $die, "\xE1\n";
f87c37b1
P
331
332undef $die;
333ok !defined eval { Devel::PPPort::croak_sv(10) };
1dc6f3b5
TK
334ok $@ =~ /^10 at \Q$0\E line /;
335ok $die =~ /^10 at \Q$0\E line /;
f87c37b1
P
336
337undef $die;
338$@ = 'should not be visible (1)';
339ok !defined eval {
340 $@ = 'should not be visible (2)';
341 Devel::PPPort::croak_sv('');
342};
1dc6f3b5
TK
343ok $@ =~ /^ at \Q$0\E line /;
344ok $die =~ /^ at \Q$0\E line /;
f87c37b1
P
345
346undef $die;
347$@ = 'should not be visible';
348ok !defined eval {
349 $@ = 'this must be visible';
350 Devel::PPPort::croak_sv($@)
351};
1dc6f3b5
TK
352ok $@ =~ /^this must be visible at \Q$0\E line /;
353ok $die =~ /^this must be visible at \Q$0\E line /;
f87c37b1
P
354
355undef $die;
356$@ = 'should not be visible';
357ok !defined eval {
358 $@ = "this must be visible\n";
359 Devel::PPPort::croak_sv($@)
360};
8154c0b1
KW
361is $@, "this must be visible\n";
362is $die, "this must be visible\n";
f87c37b1
P
363
364undef $die;
f1305528
P
365$@ = 'should not be visible';
366ok !defined eval {
367 $@ = 'this must be visible';
368 Devel::PPPort::croak_sv_errsv()
369};
1dc6f3b5
TK
370ok $@ =~ /^this must be visible at \Q$0\E line /;
371ok $die =~ /^this must be visible at \Q$0\E line /;
f1305528
P
372
373undef $die;
374$@ = 'should not be visible';
375ok !defined eval {
376 $@ = "this must be visible\n";
377 Devel::PPPort::croak_sv_errsv()
378};
8154c0b1
KW
379is $@, "this must be visible\n";
380is $die, "this must be visible\n";
f1305528
P
381
382undef $die;
383ok !defined eval { Devel::PPPort::croak_sv_with_counter("message\n") };
8154c0b1
KW
384is $@, "message\n";
385is Devel::PPPort::get_counter(), 1;
f1305528
P
386
387undef $die;
f87c37b1 388ok !defined eval { Devel::PPPort::croak_sv('') };
1dc6f3b5
TK
389ok $@ =~ /^ at \Q$0\E line /;
390ok $die =~ /^ at \Q$0\E line /;
f87c37b1
P
391
392undef $die;
393ok !defined eval { Devel::PPPort::croak_sv("\xE1") };
1dc6f3b5
TK
394ok $@ =~ /^\xE1 at \Q$0\E line /;
395ok $die =~ /^\xE1 at \Q$0\E line /;
f87c37b1
P
396
397undef $die;
398ok !defined eval { Devel::PPPort::croak_sv("\xC3\xA1") };
1dc6f3b5
TK
399ok $@ =~ /^\xC3\xA1 at \Q$0\E line /;
400ok $die =~ /^\xC3\xA1 at \Q$0\E line /;
f87c37b1
P
401
402undef $warn;
403Devel::PPPort::warn_sv("\xE1\n");
8154c0b1 404is $warn, "\xE1\n";
f87c37b1
P
405
406undef $warn;
407Devel::PPPort::warn_sv(10);
1dc6f3b5 408ok $warn =~ /^10 at \Q$0\E line /;
f87c37b1
P
409
410undef $warn;
411Devel::PPPort::warn_sv('');
1dc6f3b5 412ok $warn =~ /^ at \Q$0\E line /;
f87c37b1
P
413
414undef $warn;
415Devel::PPPort::warn_sv("\xE1");
1dc6f3b5 416ok $warn =~ /^\xE1 at \Q$0\E line /;
f87c37b1
P
417
418undef $warn;
419Devel::PPPort::warn_sv("\xC3\xA1");
1dc6f3b5 420ok $warn =~ /^\xC3\xA1 at \Q$0\E line /;
f87c37b1 421
8154c0b1
KW
422is Devel::PPPort::mess_sv("\xE1\n", 0), "\xE1\n";
423is Devel::PPPort::mess_sv(do {my $tmp = "\xE1\n"}, 1), "\xE1\n";
f87c37b1 424
1dc6f3b5
TK
425ok Devel::PPPort::mess_sv(10, 0) =~ /^10 at \Q$0\E line /;
426ok Devel::PPPort::mess_sv(do {my $tmp = 10}, 1) =~ /^10 at \Q$0\E line /;
f87c37b1 427
1dc6f3b5
TK
428ok Devel::PPPort::mess_sv('', 0) =~ /^ at \Q$0\E line /;
429ok Devel::PPPort::mess_sv(do {my $tmp = ''}, 1) =~ /^ at \Q$0\E line /;
f87c37b1 430
1dc6f3b5
TK
431ok Devel::PPPort::mess_sv("\xE1", 0) =~ /^\xE1 at \Q$0\E line /;
432ok Devel::PPPort::mess_sv(do {my $tmp = "\xE1"}, 1) =~ /^\xE1 at \Q$0\E line /;
f87c37b1 433
1dc6f3b5
TK
434ok Devel::PPPort::mess_sv("\xC3\xA1", 0) =~ /^\xC3\xA1 at \Q$0\E line /;
435ok Devel::PPPort::mess_sv(do {my $tmp = "\xC3\xA1"}, 1) =~ /^\xC3\xA1 at \Q$0\E line /;
f87c37b1 436
c8799aff
N
437if (ivers($]) >= ivers('5.006')) {
438 BEGIN { if (ivers($]) >= ivers('5.006') && ivers($]) < ivers('5.008')) { require utf8; utf8->import(); } }
f87c37b1
P
439
440 undef $die;
441 ok !defined eval { Devel::PPPort::croak_sv("\x{100}\n") };
c8799aff 442 if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.007003')) {
8154c0b1 443 is $@, "\x{100}\n";
04902fb8 444 } else {
c6e41a0a 445 skip 'skip: broken utf8 support in die hook', 1;
04902fb8 446 }
c8799aff 447 if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.008')) {
8154c0b1 448 is $die, "\x{100}\n";
f87c37b1 449 } else {
c6e41a0a 450 skip 'skip: broken utf8 support in die hook', 1;
f87c37b1
P
451 }
452
453 undef $die;
454 ok !defined eval { Devel::PPPort::croak_sv("\x{100}") };
c8799aff 455 if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.007003')) {
1dc6f3b5 456 ok $@ =~ /^\x{100} at \Q$0\E line /;
04902fb8 457 } else {
c6e41a0a 458 skip 'skip: broken utf8 support in die hook', 1;
04902fb8 459 }
c8799aff 460 if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.008')) {
1dc6f3b5 461 ok $die =~ /^\x{100} at \Q$0\E line /;
f87c37b1 462 } else {
c6e41a0a 463 skip 'skip: broken utf8 support in die hook', 1;
f87c37b1
P
464 }
465
c8799aff 466 if (ivers($]) < ivers('5.007001') || ivers($]) > ivers('5.008')) {
f87c37b1
P
467 undef $warn;
468 Devel::PPPort::warn_sv("\x{100}\n");
8154c0b1 469 is $warn, "\x{100}\n";
f87c37b1
P
470
471 undef $warn;
472 Devel::PPPort::warn_sv("\x{100}");
1dc6f3b5 473 ok (my $tmp = $warn) =~ /^\x{100} at \Q$0\E line /;
f87c37b1 474 } else {
c6e41a0a 475 skip 'skip: broken utf8 support in warn hook', 2;
f87c37b1
P
476 }
477
8154c0b1
KW
478 is Devel::PPPort::mess_sv("\x{100}\n", 0), "\x{100}\n";
479 is Devel::PPPort::mess_sv(do {my $tmp = "\x{100}\n"}, 1), "\x{100}\n";
f87c37b1 480
1dc6f3b5
TK
481 ok Devel::PPPort::mess_sv("\x{100}", 0) =~ /^\x{100} at \Q$0\E line /;
482 ok Devel::PPPort::mess_sv(do {my $tmp = "\x{100}"}, 1) =~ /^\x{100} at \Q$0\E line /;
f87c37b1 483} else {
c6e41a0a 484 skip 'skip: no utf8 support', 12;
f87c37b1
P
485}
486
10417d47 487if (ord('A') != 65) {
c6e41a0a 488 skip 'skip: no ASCII support', 24;
c8799aff
N
489} elsif ( ivers($]) >= ivers('5.008')
490 && ivers($]) != ivers('5.013000') # Broken in these ranges
491 && ! (ivers($]) >= ivers('5.011005') && ivers($]) <= ivers('5.012000')))
a44e86ee 492{
f87c37b1
P
493 undef $die;
494 ok !defined eval { Devel::PPPort::croak_sv(eval '"\N{U+E1}\n"') };
8154c0b1
KW
495 is $@, "\xE1\n";
496 is $die, "\xE1\n";
f87c37b1
P
497
498 undef $die;
499 ok !defined eval { Devel::PPPort::croak_sv(eval '"\N{U+E1}"') };
1dc6f3b5
TK
500 ok $@ =~ /^\xE1 at \Q$0\E line /;
501 ok $die =~ /^\xE1 at \Q$0\E line /;
f87c37b1
P
502
503 {
504 undef $die;
505 my $expect = eval '"\N{U+C3}\N{U+A1}\n"';
506 ok !defined eval { Devel::PPPort::croak_sv("\xC3\xA1\n") };
8154c0b1
KW
507 is $@, $expect;
508 is $die, $expect;
f87c37b1
P
509 }
510
511 {
512 undef $die;
1dc6f3b5 513 my $expect = eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
f87c37b1
P
514 ok !defined eval { Devel::PPPort::croak_sv("\xC3\xA1") };
515 ok $@ =~ $expect;
516 ok $die =~ $expect;
517 }
518
519 undef $warn;
520 Devel::PPPort::warn_sv(eval '"\N{U+E1}\n"');
8154c0b1 521 is $warn, "\xE1\n";
f87c37b1
P
522
523 undef $warn;
524 Devel::PPPort::warn_sv(eval '"\N{U+E1}"');
1dc6f3b5 525 ok $warn =~ /^\xE1 at \Q$0\E line /;
f87c37b1
P
526
527 undef $warn;
528 Devel::PPPort::warn_sv("\xC3\xA1\n");
8154c0b1 529 is $warn, eval '"\N{U+C3}\N{U+A1}\n"';
f87c37b1
P
530
531 undef $warn;
532 Devel::PPPort::warn_sv("\xC3\xA1");
1dc6f3b5 533 ok $warn =~ eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
f87c37b1 534
c8799aff 535 if (ivers($]) < ivers('5.004')) {
c6e41a0a 536 skip 'skip: no support for mess_sv', 8;
c94bdf46
KW
537 }
538 else {
8154c0b1
KW
539 is Devel::PPPort::mess_sv(eval('"\N{U+E1}\n"'), 0), eval '"\N{U+E1}\n"';
540 is Devel::PPPort::mess_sv(do {my $tmp = eval '"\N{U+E1}\n"'}, 1), eval '"\N{U+E1}\n"';
f87c37b1 541
1dc6f3b5
TK
542 ok Devel::PPPort::mess_sv(eval('"\N{U+E1}"'), 0) =~ eval 'qr/^\N{U+E1} at \Q$0\E line /';
543 ok Devel::PPPort::mess_sv(do {my $tmp = eval '"\N{U+E1}"'}, 1) =~ eval 'qr/^\N{U+E1} at \Q$0\E line /';
f87c37b1 544
8154c0b1
KW
545 is Devel::PPPort::mess_sv("\xC3\xA1\n", 0), eval '"\N{U+C3}\N{U+A1}\n"';
546 is Devel::PPPort::mess_sv(do {my $tmp = "\xC3\xA1\n"}, 1), eval '"\N{U+C3}\N{U+A1}\n"';
f87c37b1 547
1dc6f3b5
TK
548 ok Devel::PPPort::mess_sv("\xC3\xA1", 0) =~ eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
549 ok Devel::PPPort::mess_sv(do {my $tmp = "\xC3\xA1"}, 1) =~ eval 'qr/^\N{U+C3}\N{U+A1} at \Q$0\E line /';
c94bdf46 550 }
f87c37b1 551} else {
c6e41a0a 552 skip 'skip: no support for \N{U+..} syntax', 24;
f87c37b1
P
553}
554
c8799aff 555if (ivers($]) >= ivers('5.007003') or (ivers($]) >= ivers('5.006001') and ivers($]) < ivers('5.007'))) {
f87c37b1
P
556 undef $die;
557 ok !defined eval { Devel::PPPort::croak_sv($scalar_ref) };
558 ok $@ == $scalar_ref;
559 ok $die == $scalar_ref;
560
561 undef $die;
562 ok !defined eval { Devel::PPPort::croak_sv($array_ref) };
563 ok $@ == $array_ref;
564 ok $die == $array_ref;
565
566 undef $die;
567 ok !defined eval { Devel::PPPort::croak_sv($hash_ref) };
568 ok $@ == $hash_ref;
569 ok $die == $hash_ref;
570
571 undef $die;
572 ok !defined eval { Devel::PPPort::croak_sv($obj) };
573 ok $@ == $obj;
574 ok $die == $obj;
575} else {
c6e41a0a 576 skip 'skip: no support for exceptions', 12;
f87c37b1
P
577}
578
579ok !defined eval { Devel::PPPort::croak_no_modify() };
1dc6f3b5 580ok $@ =~ /^Modification of a read-only value attempted at \Q$0\E line /;
f87c37b1
P
581
582ok !defined eval { Devel::PPPort::croak_memory_wrap() };
1dc6f3b5 583ok $@ =~ /^panic: memory wrap at \Q$0\E line /;
f87c37b1
P
584
585ok !defined eval { Devel::PPPort::croak_xs_usage("params") };
1dc6f3b5 586ok $@ =~ /^Usage: Devel::PPPort::croak_xs_usage\(params\) at \Q$0\E line /;