This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
toke.c: Simplify finding mirror-image close delimiter
authorKarl Williamson <khw@cpan.org>
Tue, 20 Dec 2016 20:07:23 +0000 (13:07 -0700)
committerKarl Williamson <khw@cpan.org>
Fri, 23 Dec 2016 00:59:10 +0000 (17:59 -0700)
This is the code that figures out what the closing delimiter is for a
given opening string delimiter.  For most, it is the same character,
but for a few, it is a mirror-image character.

I have had to figure out multiple times how these couple lines of code
works.  This time, as I started to comment it, so I wouldn't have to do
figure it out again, I realized that its cleverness wasn't really saving
anything, and might slow things down.  So split into two parallel strings,
with one string containing the opening delimiters which have mirror
image closing ones, and the other containing those closing delimiters,
in the same order.  So we find the offset into the first string of the
opening delimiter.  If it isn't in that string, it isn't mirrored, but
if it does, the corresponding closing delimiter is found at the same
offset in the other string.

toke.c

diff --git a/toke.c b/toke.c
index 8052708..f695265 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -10192,6 +10192,10 @@ S_scan_str(pTHX_ char *start, int keep_bracketed_quoted, int keep_delims, int re
     STRLEN termlen;            /* length of terminating string */
     line_t herelines;
 
+    /* The delimiters that have a mirror-image closing one */
+    const char * opening_delims = "([{<";
+    const char * closing_delims = ")]}>";
+
     PERL_ARGS_ASSERT_SCAN_STR;
 
     /* skip space before the delimiter */
@@ -10218,9 +10222,10 @@ S_scan_str(pTHX_ char *start, int keep_bracketed_quoted, int keep_delims, int re
     PL_multi_open = termcode;
     herelines = PL_parser->herelines;
 
-    /* find corresponding closing delimiter */
-    if (term && (tmps = strchr("([{< )]}> )]}>",term)))
-       termcode = termstr[0] = term = tmps[5];
+    /* If the delimiter has a mirror-image closing one, get it */
+    if (term && (tmps = strchr(opening_delims, term))) {
+        termcode = termstr[0] = term = closing_delims[tmps - opening_delims];
+    }
 
     PL_multi_close = termcode;