Skip to content

Commit 806b51b

Browse files
committed
Improve -Dy debugging
Commit 6ceb408 added a way to cleanly output UTF-8 tr/// values. This commit uses that to improve the debug output of compiling and running tr///.
1 parent 95d2ddd commit 806b51b

File tree

4 files changed

+115
-18
lines changed

4 files changed

+115
-18
lines changed

embed.fnc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4969,6 +4969,12 @@ S |OP * |too_many_arguments_pv \
49694969
|NN const char *name \
49704970
|U32 flags
49714971
S |OP * |voidnonfinal |NULLOK OP *o
4972+
# if defined(DEBUGGING)
4973+
S |const char *|get_displayable_tr_operand \
4974+
|NN const U8 *s \
4975+
|STRLEN len \
4976+
|bool is_utf8
4977+
# endif
49724978
#endif /* defined(PERL_IN_OP_C) */
49734979
#if defined(PERL_IN_OP_C) || defined(PERL_IN_PAD_C)
49744980
Ti |bool |PadnameIN_SCOPE|NN const PADNAME * const pn \

embed.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,9 @@
15191519
# define too_few_arguments_pv(a,b,c) S_too_few_arguments_pv(aTHX_ a,b,c)
15201520
# define too_many_arguments_pv(a,b,c) S_too_many_arguments_pv(aTHX_ a,b,c)
15211521
# define voidnonfinal(a) S_voidnonfinal(aTHX_ a)
1522+
# if defined(DEBUGGING)
1523+
# define get_displayable_tr_operand(a,b,c) S_get_displayable_tr_operand(aTHX_ a,b,c)
1524+
# endif
15221525
# endif /* defined(PERL_IN_OP_C) */
15231526
# if defined(PERL_IN_OP_C) || defined(PERL_IN_PAD_C)
15241527
# define PadnameIN_SCOPE S_PadnameIN_SCOPE

op.c

Lines changed: 99 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6179,6 +6179,25 @@ Perl_invmap_dump(pTHX_ SV* invlist, UV *map)
61796179
}
61806180
}
61816181

6182+
#ifdef DEBUGGING
6183+
6184+
static const char *
6185+
S_get_displayable_tr_operand(pTHX_ const U8 * s, STRLEN len, bool is_utf8)
6186+
{
6187+
SV * output = sv_2mortal(newSVpvs(""));
6188+
if (is_utf8) {
6189+
return pv_uni_display(output, s, len, 1000, UNI_DISPLAY_TR_);
6190+
}
6191+
else {
6192+
return pv_pretty(output, (const char *) s, len, 256, NULL, NULL,
6193+
( PERL_PV_ESCAPE_NONASCII
6194+
|PERL_PV_PRETTY_LTGT
6195+
|PERL_PV_PRETTY_ELLIPSES));
6196+
}
6197+
}
6198+
6199+
#endif
6200+
61826201
/* Given an OP_TRANS / OP_TRANSR op o, plus OP_CONST ops expr and repl
61836202
* containing the search and replacement strings, assemble into
61846203
* a translation table attached as o->op_pv.
@@ -6528,6 +6547,13 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
65286547

65296548
PL_hints |= HINT_BLOCK_SCOPE;
65306549

6550+
DEBUG_y(PerlIO_printf(Perl_debug_log,
6551+
"%s: %d: Compiling tr/*t/*r/; /c=%d; /d=%d; /s=%d\n"
6552+
"*t is '%s'\n*r is '%s'\n",
6553+
__FILE__, __LINE__, complement, del, squash,
6554+
get_displayable_tr_operand(t0, tlen, tstr_utf8),
6555+
get_displayable_tr_operand(r0, rlen, rstr_utf8)));
6556+
65316557
/* If /c, the search list is sorted and complemented. This is now done by
65326558
* creating an inversion list from it, and then trivially inverting that.
65336559
* The previous implementation used qsort, but creating the list
@@ -6609,6 +6635,11 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
66096635
tend = t0 + temp_len;
66106636
tstr_utf8 = TRUE;
66116637

6638+
DEBUG_y(PerlIO_printf(Perl_debug_log,
6639+
"%s: %d: *t after complementing=\n%s\n",
6640+
__FILE__, __LINE__,
6641+
get_displayable_tr_operand(t0, temp_len, tstr_utf8)));
6642+
66126643
SvREFCNT_dec_NN(inverted_tlist);
66136644
}
66146645

@@ -6653,8 +6684,8 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
66536684
for (pass2 = 0; pass2 < 2; pass2++) {
66546685
if (pass2) {
66556686

6656-
DEBUG_yv(PerlIO_printf(Perl_debug_log, "After pass1: \n"));
6657-
DEBUG_yv(invmap_dump(t_invlist, r_map));
6687+
DEBUG_y(PerlIO_printf(Perl_debug_log, "After pass1: \n");
6688+
invmap_dump(t_invlist, r_map));
66586689

66596690
/* In the second pass, we start with a single range */
66606691
t_invlist = _add_range_to_invlist(t_invlist, 0, UV_MAX);
@@ -6786,9 +6817,9 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
67866817
r_range_count = t_range_count;
67876818

67886819
#ifdef DEBUGGING
6789-
if (DEBUG_y_TEST && ! del) {
6820+
if (DEBUG_yv_TEST && ! del) {
67906821
PerlIO_printf(Perl_debug_log,
6791-
"final_map =%" UVXf "\n", final_map);
6822+
"final_map = %" UVXf "\n", final_map);
67926823
}
67936824
#endif
67946825
}
@@ -6904,9 +6935,25 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
69046935
* has been set up so that all members in it will be of the same
69056936
* ilk) */
69066937
if (r_map[i] == TR_UNLISTED) {
6907-
DEBUG_yv(PerlIO_printf(Perl_debug_log,
6908-
"Processing %" UVxf "-%" UVxf " => %" UVxf "-%" UVxf "\n",
6909-
t_cp, t_cp_end, r_cp, r_cp_end));
6938+
6939+
#ifdef DEBUGGING
6940+
if (DEBUG_yv_TEST) {
6941+
PerlIO_printf(Perl_debug_log,
6942+
"Processing %" UVxf "-%" UVxf " => ",
6943+
t_cp, t_cp_end);
6944+
if (r_cp == r_cp_end && r_cp == TR_UNLISTED) {
6945+
PerlIO_printf(Perl_debug_log, "TR_UNLISTED\n");
6946+
}
6947+
else if (r_cp == r_cp_end && r_cp == TR_SPECIAL_HANDLING) {
6948+
PerlIO_printf(Perl_debug_log, "TR_SPECIAL_HANDLING\n");
6949+
}
6950+
else {
6951+
PerlIO_printf(Perl_debug_log,
6952+
"%" UVxf "-%" UVxf "\n",
6953+
r_cp, r_cp_end);
6954+
}
6955+
}
6956+
#endif
69106957

69116958
/* This is the first definition for this chunk, hence is valid
69126959
* and needs to be processed. Here and in the comments below,
@@ -7211,8 +7258,8 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
72117258

72127259
DEBUG_yv(PerlIO_printf(Perl_debug_log,
72137260
"Before fixing up: len=%d, i=%d\n",
7214-
(int) len, (int) i));
7215-
DEBUG_yv(invmap_dump(t_invlist, r_map));
7261+
(int) len, (int) i);
7262+
invmap_dump(t_invlist, r_map));
72167263

72177264
invlist_extend(t_invlist, len + 2);
72187265
t_array = invlist_array(t_invlist);
@@ -7234,10 +7281,11 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
72347281
r_map[i+2] = TR_UNLISTED;
72357282
}
72367283
DEBUG_yv(PerlIO_printf(Perl_debug_log,
7237-
"After iteration: span=%" UVuf ", t_range_count=%"
7238-
UVuf " r_range_count=%" UVuf "\n",
7239-
span, t_range_count, r_range_count));
7240-
DEBUG_yv(invmap_dump(t_invlist, r_map));
7284+
"After iteration: span=%" UVuf
7285+
", t_range_count=%" UVuf
7286+
" r_range_count=%" UVuf "\n",
7287+
span, t_range_count, r_range_count);
7288+
invmap_dump(t_invlist, r_map));
72417289
} /* End of this chunk needs to be processed */
72427290

72437291
/* Done with this chunk. */
@@ -7266,8 +7314,8 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
72667314

72677315
SvREFCNT_dec(inverted_tstr);
72687316

7269-
DEBUG_y(PerlIO_printf(Perl_debug_log, "After everything: \n"));
7270-
DEBUG_y(invmap_dump(t_invlist, r_map));
7317+
DEBUG_y(PerlIO_printf(Perl_debug_log, "After everything: \n");
7318+
invmap_dump(t_invlist, r_map));
72717319

72727320
/* We now have normalized the input into an inversion map.
72737321
*
@@ -7417,7 +7465,16 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
74177465
: (short) TR_R_EMPTY;
74187466
#ifdef DEBUGGING
74197467
if (DEBUG_y_TEST) {
7420-
PerlIO_printf(Perl_debug_log,"%s: %d\n", __FILE__, __LINE__);
7468+
PerlIO_printf(Perl_debug_log,
7469+
"\n%s: %d: Final generated translation table:\n %"
7470+
IVdf " means this char not involved in this transliteration\n",
7471+
__FILE__, __LINE__, TR_UNLISTED);
7472+
if (del) {
7473+
PerlIO_printf(Perl_debug_log,
7474+
" %" IVdf " means delete this char\n",
7475+
TR_SPECIAL_HANDLING);
7476+
}
7477+
74217478
for (i = 0; i < tbl->size; i++) {
74227479
if (tbl->map[i] < 0) {
74237480
PerlIO_printf(Perl_debug_log," %02x=>%d",
@@ -7431,8 +7488,32 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
74317488
PerlIO_printf(Perl_debug_log,"\n");
74327489
}
74337490
}
7434-
PerlIO_printf(Perl_debug_log,"Final map 0x%x=>%02x\n",
7435-
(unsigned) tbl->size, tbl->map[tbl->size]);
7491+
7492+
PerlIO_printf(Perl_debug_log,
7493+
"The next (and final) byte ");
7494+
if ((UV) tbl->map[tbl->size] == TR_UNLISTED) {
7495+
PerlIO_printf(Perl_debug_log,
7496+
" indicates no other characters are involved in"
7497+
" the transliteration\n");
7498+
}
7499+
else if ((UV) tbl->map[tbl->size] == TR_SPECIAL_HANDLING) {
7500+
if (! del) {
7501+
const int size = tbl->size;
7502+
Perl_croak(aTHX_ "panic: Unexpected value %x in [%d]",
7503+
tbl->map[size], size);
7504+
}
7505+
else {
7506+
PerlIO_printf(Perl_debug_log,
7507+
"indicates that all code points above"
7508+
" 0xFF are to be deleted\n");
7509+
}
7510+
}
7511+
else if ((UV) tbl->map[tbl->size] == TR_R_EMPTY) {
7512+
PerlIO_printf(Perl_debug_log, "is unused\n");
7513+
}
7514+
else {
7515+
PerlIO_printf(Perl_debug_log, "%x UNUSED\n", tbl->map[256]);
7516+
}
74367517
};
74377518
#endif
74387519

proto.h

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)