From fcaf065a1097420466ccb1eb1d9a514a9f938a70 Mon Sep 17 00:00:00 2001 From: Michael Mikonos <127171689+mknos@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:52:10 +0800 Subject: [PATCH] ed: simplify escape_line() (#763) * Pre-compute all binary escape values in a handy mapping table to avoid branching in escape_line() * I confirmed that the "l" command produces the same output as for the previous commit --- bin/ed | 60 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/bin/ed b/bin/ed index e44a827a..f14c3044 100755 --- a/bin/ed +++ b/bin/ed @@ -110,16 +110,39 @@ my $PRINT_BIN = 2; our $VERSION = '0.5'; -my %ESC = ( - 7 => '\a', - 8 => '\b', - 9 => '\t', - 10 => "\$\n", - 11 => '\v', - 12 => '\f', - 13 => '\r', - 36 => '\\$', - 92 => '\\\\', +my @ESC = ( + '\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\a', + '\\b', '\\t', "\$\n", '\\v', '\\f', '\\r', '\\016', '\\017', + '\\020', '\\021', '\\022', '\\023', '\\024', '\\025', '\\026', '\\027', + '\\030', '\\031', '\\032', '\\033', '\\034', '\\035', '\\036', '\\037', + ' ', '!', '"', '#', '\\$', '%', '&', q('), + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', '\\177', + '\\200', '\\201', '\\202', '\\203', '\\204', '\\205', '\\206', '\\207', + '\\210', '\\211', '\\212', '\\213', '\\214', '\\215', '\\216', '\\217', + '\\220', '\\221', '\\222', '\\223', '\\224', '\\225', '\\226', '\\227', + '\\230', '\\231', '\\232', '\\233', '\\234', '\\235', '\\236', '\\237', + '\\240', '\\241', '\\242', '\\243', '\\244', '\\245', '\\246', '\\247', + '\\250', '\\251', '\\252', '\\253', '\\254', '\\255', '\\256', '\\257', + '\\260', '\\261', '\\262', '\\263', '\\264', '\\265', '\\266', '\\267', + '\\270', '\\271', '\\272', '\\273', '\\274', '\\275', '\\276', '\\277', + '\\300', '\\301', '\\302', '\\303', '\\304', '\\305', '\\306', '\\307', + '\\310', '\\311', '\\312', '\\313', '\\314', '\\315', '\\316', '\\317', + '\\320', '\\321', '\\322', '\\323', '\\324', '\\325', '\\326', '\\327', + '\\330', '\\331', '\\332', '\\333', '\\334', '\\335', '\\336', '\\337', + '\\340', '\\341', '\\342', '\\343', '\\344', '\\345', '\\346', '\\347', + '\\350', '\\351', '\\352', '\\353', '\\354', '\\355', '\\356', '\\357', + '\\360', '\\361', '\\362', '\\363', '\\364', '\\365', '\\366', '\\367', + '\\370', '\\371', '\\372', '\\373', '\\374', '\\375', '\\376', '\\377', ); my %WANT_FILE = ( @@ -325,20 +348,9 @@ sub escape_line { my $idx = shift; my @chars = unpack 'C*', $lines[$idx]; - if (scalar(@chars) == 0) { - die 'internal error: unpack'; - } - my $s = ''; - foreach my $c (@chars) { - if (exists $ESC{$c}) { - $s .= $ESC{$c}; - } elsif (chr($c) !~ m/[[:print:]]/) { - $s .= sprintf '\%03o', $c; - } else { - $s .= chr($c); - } - } - return $s; + die 'internal error: unpack' unless @chars; + my @s = map { $ESC[$_] } @chars; + return join '', @s; } # does not modify buffer