From e11c86f43e045462f4c0e2eaa2ddb4fdb6927ea7 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 12 Dec 2024 14:40:29 -0800 Subject: [PATCH] Fix error messages so we don't output an extra line Before this commit, when a file ended with a newline, the syntax error message would show an extra line after the file. For example, the error message would look like this: ``` [aaron@tc-lan-adapter ~/g/ruby (master)]$ echo "foo(" > test.rb [aaron@tc-lan-adapter ~/g/ruby (master)]$ od -c test.rb 0000000 f o o ( \n 0000005 [aaron@tc-lan-adapter ~/g/ruby (master)]$ wc -l test.rb 1 test.rb [aaron@tc-lan-adapter ~/g/ruby (master)]$ ./miniruby test.rb test.rb: test.rb:1: syntax error found (SyntaxError) > 1 | foo( | ^ unexpected end-of-input; expected a `)` to close the arguments 2 | ``` This commit fixes the "end of line" book keeping when printing an error so that there is no extra line output at the end of the file: ``` [aaron@tc-lan-adapter ~/g/ruby (fix-last-line-error)]$ echo "foo(" | ./miniruby -: -:1: syntax error found (SyntaxError) > 1 | foo( | ^ unexpected end-of-input; expected a `)` to close the arguments [aaron@tc-lan-adapter ~/g/ruby (fix-last-line-error)]$ echo -n "foo(" | ./miniruby -: -:1: syntax error found (SyntaxError) > 1 | foo( | ^ unexpected end-of-input; expected a `)` to close the arguments ``` Notice that in the above example, the error message only displays one line regardless of whether or not the file ended with a newline. [Bug #20918] [ruby-core:120035] --- prism_compile.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/prism_compile.c b/prism_compile.c index eff152bce7..62182c73bf 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -10444,7 +10444,20 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p // Here we determine how many lines of padding to display after the // error, depending on where the next error is in source. last_line = error->line; - int32_t next_line = (index == error_list->size - 1) ? (((int32_t) newline_list->size) + parser->start_line) : errors[index + 1].line; + int32_t next_line; + + if (index == error_list->size - 1) { + next_line = (((int32_t) newline_list->size) + parser->start_line); + + // If the file ends with a newline, subtract one from our "next_line" + // so that we don't output an extra line at the end of the file + if ((parser->start + newline_list->offsets[newline_list->size - 1]) == parser->end) { + next_line--; + } + } + else { + next_line = errors[index + 1].line; + } if (next_line - last_line > 1) { pm_buffer_append_string(buffer, " ", 2);