diff options
| author | Seeker <[email protected]> | 2020-12-29 13:01:49 -0800 |
|---|---|---|
| committer | Seeker <[email protected]> | 2020-12-31 19:09:38 -0800 |
| commit | 1099050377f82732d5e716e23aeb511b364d41e7 (patch) | |
| tree | b5a1bbdd523e1cf596dc5f8a4e029287df84362d | |
| parent | 4683a196d9cdcee84024ce6fb8bb73082c76eee8 (diff) | |
| download | mruby-1099050377f82732d5e716e23aeb511b364d41e7.tar.gz mruby-1099050377f82732d5e716e23aeb511b364d41e7.zip | |
Treat tabs as 8 spaces in squiggly heredocs
| -rw-r--r-- | include/mruby/compile.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 46 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/y.tab.c | 46 |
3 files changed, 56 insertions, 37 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 ebb18767a..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)); + 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 && empty) { - if (ISSPACE(c)) { - if (hinf->indent_char == -1) - hinf->indent_char = c; - if (c == hinf->indent_char) - ++spaces; - } + 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 2305c2bb6..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)); + 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 && empty) { - if (ISSPACE(c)) { - if (hinf->indent_char == -1) - hinf->indent_char = c; - if (c == hinf->indent_char) - ++spaces; - } + 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; |
