summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-01-02 20:28:13 +0900
committerGitHub <[email protected]>2021-01-02 20:28:13 +0900
commit15e7b3e8fef33f3b5cf657580f5b410053b2d31e (patch)
treef519e340162ece9de13b05b7557256da70515f3c
parent12cb7207ecb7c67bc0c63e61b8726f1f98957b27 (diff)
parent1099050377f82732d5e716e23aeb511b364d41e7 (diff)
downloadmruby-15e7b3e8fef33f3b5cf657580f5b410053b2d31e.tar.gz
mruby-15e7b3e8fef33f3b5cf657580f5b410053b2d31e.zip
Merge pull request #5251 from SeekingMeaning/squiggly-fix-3
Fix regression for squiggly heredocs
-rw-r--r--include/mruby/compile.h1
-rw-r--r--mrbgems/mruby-compiler/core/parse.y50
-rw-r--r--mrbgems/mruby-compiler/core/y.tab.c50
-rw-r--r--test/t/literals.rb5
4 files changed, 65 insertions, 41 deletions
diff --git a/include/mruby/compile.h b/include/mruby/compile.h
index ff4bbe9bd..8159cd696 100644
--- a/include/mruby/compile.h
+++ b/include/mruby/compile.h
@@ -100,7 +100,6 @@ enum mrb_string_type {
struct mrb_parser_heredoc_info {
mrb_bool allow_indent:1;
mrb_bool remove_indent:1;
- char indent_char;
size_t indent;
mrb_ast_node *indented;
mrb_bool line_head:1;
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 4a031abde..f66287053 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -4664,16 +4664,29 @@ parse_string(parser_state *p)
if (hinf->remove_indent && hinf->indent > 0) {
node *tmp = hinf->indented;
while (tmp) {
- node *n = tmp->car;
- size_t indent = (size_t)n->car;
- if (indent > hinf->indent)
- indent = hinf->indent;
+ node *pair = tmp->car;
+ const char *str = (char*)pair->car;
+ size_t len = (size_t)pair->cdr;
+ size_t indent = 0;
+ size_t offset = 0;
+ for (size_t i = 0; i < len; i++) {
+ size_t size;
+ if (str[i] == '\n')
+ break;
+ else if (str[i] == '\t')
+ size = 8;
+ else if (ISSPACE(str[i]))
+ size = 1;
+ else
+ break;
+ if (indent + size > hinf->indent)
+ break;
+ indent += size;
+ ++offset;
+ }
if (indent > 0) {
- node *pair = n->cdr;
- const char *str = (char*)pair->car;
- size_t len = (size_t)pair->cdr;
- pair->car = (node*)(str + indent);
- pair->cdr = (node*)(len - indent);
+ pair->car = (node*)(str + offset);
+ pair->cdr = (node*)(len - offset);
}
tmp = tmp->cdr;
}
@@ -4699,19 +4712,17 @@ parse_string(parser_state *p)
node *nd = new_str(p, tok(p), toklen(p));
pylval.nd = nd;
if (head) {
- hinf->indented = push(hinf->indented, cons((node*)spaces, nd->cdr));
- if ((hinf->indent == -1 || spaces < hinf->indent) && (!empty || !hinf->line_head))
+ hinf->indented = push(hinf->indented, nd->cdr);
+ if ((hinf->indent == -1 || spaces < hinf->indent) && (!empty || !line_head))
hinf->indent = spaces;
}
return tHD_STRING_MID;
}
- if (hinf && hinf->line_head) {
- if (ISSPACE(c)) {
- if (hinf->indent_char == -1)
- hinf->indent_char = c;
- if (c == hinf->indent_char)
- ++spaces;
- }
+ if (hinf && hinf->line_head && empty) {
+ if (c == '\t')
+ spaces += 8;
+ else if (ISSPACE(c))
+ ++spaces;
else
empty = FALSE;
}
@@ -4789,7 +4800,7 @@ parse_string(parser_state *p)
pylval.nd = nd;
if (hinf) {
if (head) {
- hinf->indented = push(hinf->indented, cons((node*)spaces, nd->cdr));
+ hinf->indented = push(hinf->indented, nd->cdr);
if (hinf->indent == -1 || spaces < hinf->indent)
hinf->indent = spaces;
}
@@ -5009,7 +5020,6 @@ heredoc_identifier(parser_state *p)
info->type = (string_type)type;
info->allow_indent = indent || squiggly;
info->remove_indent = squiggly;
- info->indent_char = -1;
info->indent = -1;
info->indented = NULL;
info->line_head = TRUE;
diff --git a/mrbgems/mruby-compiler/core/y.tab.c b/mrbgems/mruby-compiler/core/y.tab.c
index ea3cf2db7..3c53b3e4a 100644
--- a/mrbgems/mruby-compiler/core/y.tab.c
+++ b/mrbgems/mruby-compiler/core/y.tab.c
@@ -11049,16 +11049,29 @@ parse_string(parser_state *p)
if (hinf->remove_indent && hinf->indent > 0) {
node *tmp = hinf->indented;
while (tmp) {
- node *n = tmp->car;
- size_t indent = (size_t)n->car;
- if (indent > hinf->indent)
- indent = hinf->indent;
+ node *pair = tmp->car;
+ const char *str = (char*)pair->car;
+ size_t len = (size_t)pair->cdr;
+ size_t indent = 0;
+ size_t offset = 0;
+ for (size_t i = 0; i < len; i++) {
+ size_t size;
+ if (str[i] == '\n')
+ break;
+ else if (str[i] == '\t')
+ size = 8;
+ else if (ISSPACE(str[i]))
+ size = 1;
+ else
+ break;
+ if (indent + size > hinf->indent)
+ break;
+ indent += size;
+ ++offset;
+ }
if (indent > 0) {
- node *pair = n->cdr;
- const char *str = (char*)pair->car;
- size_t len = (size_t)pair->cdr;
- pair->car = (node*)(str + indent);
- pair->cdr = (node*)(len - indent);
+ pair->car = (node*)(str + offset);
+ pair->cdr = (node*)(len - offset);
}
tmp = tmp->cdr;
}
@@ -11084,19 +11097,17 @@ parse_string(parser_state *p)
node *nd = new_str(p, tok(p), toklen(p));
pylval.nd = nd;
if (head) {
- hinf->indented = push(hinf->indented, cons((node*)spaces, nd->cdr));
- if ((hinf->indent == -1 || spaces < hinf->indent) && (!empty || !hinf->line_head))
+ hinf->indented = push(hinf->indented, nd->cdr);
+ if ((hinf->indent == -1 || spaces < hinf->indent) && (!empty || !line_head))
hinf->indent = spaces;
}
return tHD_STRING_MID;
}
- if (hinf && hinf->line_head) {
- if (ISSPACE(c)) {
- if (hinf->indent_char == -1)
- hinf->indent_char = c;
- if (c == hinf->indent_char)
- ++spaces;
- }
+ if (hinf && hinf->line_head && empty) {
+ if (c == '\t')
+ spaces += 8;
+ else if (ISSPACE(c))
+ ++spaces;
else
empty = FALSE;
}
@@ -11174,7 +11185,7 @@ parse_string(parser_state *p)
pylval.nd = nd;
if (hinf) {
if (head) {
- hinf->indented = push(hinf->indented, cons((node*)spaces, nd->cdr));
+ hinf->indented = push(hinf->indented, nd->cdr);
if (hinf->indent == -1 || spaces < hinf->indent)
hinf->indent = spaces;
}
@@ -11394,7 +11405,6 @@ heredoc_identifier(parser_state *p)
info->type = (string_type)type;
info->allow_indent = indent || squiggly;
info->remove_indent = squiggly;
- info->indent_char = -1;
info->indent = -1;
info->indented = NULL;
info->line_head = TRUE;
diff --git a/test/t/literals.rb b/test/t/literals.rb
index dad5c872a..682e5317a 100644
--- a/test/t/literals.rb
+++ b/test/t/literals.rb
@@ -190,6 +190,10 @@ QQ2
\tvvv
vvv
VVV
+ v3 = <<~VVV
+ v v v
+ vvv
+ VVV
w = %W( 1 #{<<WWW} 3
www
@@ -232,6 +236,7 @@ ZZZ
assert_equal ["u1u\n", "u2u\n", "u\#{3}u\n"], u
assert_equal "\nvvv\nvvv\n", v1
assert_equal "\tvvv\n vvv\n", v2
+ assert_equal "v v v\n vvv\n", v3
assert_equal ["1", "www\n", "3", "4", "5"], w
assert_equal [1, "foo 222 333\n 444\n5\n bar\n6\n", 9], x
assert_equal "", z