diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-01-02 20:28:13 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-01-02 20:28:13 +0900 |
| commit | 15e7b3e8fef33f3b5cf657580f5b410053b2d31e (patch) | |
| tree | f519e340162ece9de13b05b7557256da70515f3c | |
| parent | 12cb7207ecb7c67bc0c63e61b8726f1f98957b27 (diff) | |
| parent | 1099050377f82732d5e716e23aeb511b364d41e7 (diff) | |
| download | mruby-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.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 50 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/y.tab.c | 50 | ||||
| -rw-r--r-- | test/t/literals.rb | 5 |
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 |
