Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Escape all C0 and C1 control codes under escape_chars => 'nonascii' #58

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Escape all C0 and C1 control codes under escape_chars => 'nonascii'
Along the way consolidates the five escaping passes in _escape_chars into a
single substitution, with the side effect of causing print_escapes to not
generate redundant color-switch codes.
sorear committed Jan 24, 2015

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 50b407882aca393195b3f4a993cc364873d379f6
64 changes: 29 additions & 35 deletions lib/Data/Printer.pm
Original file line number Diff line number Diff line change
@@ -377,45 +377,39 @@ sub _escape_chars {
$orig_color = color( $orig_color );
my $esc_color = color( $p->{color}{escaped} );

# if we're escaping everything then we don't need to keep swapping
# colors in and out, and we need to return right away because
# we no longer need to print_escapes
if ($p->{escape_chars} eq 'all') {
return $esc_color
. join('', map { sprintf '\x{%02x}', ord $_ } split //, $str)
. $orig_color
}

$str =~ s/\e/$esc_color\\e$orig_color/g if $p->{print_escapes};
my %special_escapes = (
"\n" => '\n',
"\r" => '\r',
"\t" => '\t',
"\f" => '\f',
"\b" => '\b',
"\a" => '\a',
"\0" => '\0',
"\e" => '\e',
);

my $blacklist;

if ($p->{escape_chars} eq 'nonascii') {
$str =~ s{([^\x{00}-\x{7f}]+)}{
$esc_color
. (join '', map { sprintf '\x{%02x}', ord $_ } split //, $1)
. $orig_color
}ge;
if ($p->{escape_chars} eq 'all') {
# escape everything, and systematically
$blacklist = "(.+)";
%special_escapes = ();
} elsif ($p->{escape_chars} eq 'nonascii') {
$blacklist = "([^\x{20}-\x{7e}]+)";
} elsif ($p->{escape_chars} eq 'nonlatin1') {
$str =~ s{([^\x{00}-\x{ff}]+)}{
$esc_color
. (join '', map { sprintf '\x{%02x}', ord $_ } split //, $1) . $orig_color
}ge;
$blacklist = "([^\x{20}-\x{7e}\x{a0}-\x{ff}]+)";
} elsif ($p->{print_escapes}) {
$blacklist = "([\0\e\n\r\t\f\b\a]+)";
} else {
# always escape nulls and the escape character
$blacklist = "([\0\e]+)";
}

if ($p->{print_escapes}) {
my %escaped = (
"\n" => '\n',
"\r" => '\r',
"\t" => '\t',
"\f" => '\f',
"\b" => '\b',
"\a" => '\a',
);
foreach my $k ( keys %escaped ) {
$str =~ s/$k/$esc_color$escaped{$k}$orig_color/g;
}
}
# always escape the null character
$str =~ s/\0/$esc_color\\0$orig_color/g;
$str =~ s{$blacklist}{
$esc_color
. (join '', map { $special_escapes{$_} || sprintf '\x{%02x}', ord $_ } split //, $1)
. $orig_color
}ge;

return $str;
}
6 changes: 5 additions & 1 deletion t/30-print_escapes.t
Original file line number Diff line number Diff line change
@@ -60,7 +60,6 @@ foreach my $item (@stuff) {

$mixed->{original} .= $item->{original};
$mixed->{unescaped} .= $item->{unescaped};
$mixed->{colored} .= $colored;

is(
p( $item->{original} ),
@@ -74,6 +73,11 @@ foreach my $item (@stuff) {
);
}

$mixed->{colored} = color('bright_red')
. $mixed->{unescaped}
. color('bright_yellow')
;

is(
p( $mixed->{original} ),
color('reset')
24 changes: 22 additions & 2 deletions t/40-escape_chars.t
Original file line number Diff line number Diff line change
@@ -16,11 +16,19 @@ BEGIN {
};

my $string = "L\x{e9}on likes to build a m\x{f8}\x{f8}se \x{2603} with \x{2744}\x{2746}";
my $ctl_string = "\n\x{14}\x{7f}\x{9b}"; # "common" control character, C0, DEL, C1
my %hash = ( $string => $string );

sub col(@) {
my $return = color('bright_red');
$return .= '\\x{' . shift . '}' while @_;
$return .= '\\x{' . shift() . '}' while @_;
$return .= color('bright_yellow');
return $return;
}

sub col_sp(@) {
my $return = color('bright_red');
$return .= '\\' . shift() while @_;
$return .= color('bright_yellow');
return $return;
}
@@ -29,7 +37,7 @@ sub str($) {
return color('reset')
. '"'
. color('bright_yellow')
. shift
. shift()
. color('reset')
. '"';
}
@@ -58,6 +66,12 @@ is(
"Testing 'nonascii'"
);

is(
p( $ctl_string ),
str( col_sp('n','x{14}','x{7f}','x{9b}') ),
"Testing 'nonascii' control characters"
);

### nonlatin1 ###

use_ok (
@@ -73,6 +87,12 @@ is(
"Testing 'nonlatin1'"
);

is(
p( $ctl_string ),
str( col_sp('n','x{14}','x{7f}','x{9b}') ),
"Testing 'nonlatin1' control characters"
);

### all ###

use_ok (