From c733ee9bb6dfee3e64bb8e1e4be0f88e558aacf4 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Fri, 9 Jun 2023 21:18:11 +0000 Subject: [PATCH] follow-up to printing context of diagnostics [r5074] cobc/error.c: * (print_error, diagnostics_show_caret): fix for C89 compat * (diagnostics_show_caret): * trim trailing whitespace * removed printing empty lines before/after, * print EOF * changed format --- cobc/ChangeLog | 8 +- cobc/error.c | 112 ++++++++++++++------------- tests/testsuite.src/used_binaries.at | 112 +++++++++++++++++---------- 3 files changed, 136 insertions(+), 96 deletions(-) diff --git a/cobc/ChangeLog b/cobc/ChangeLog index e0690fd37..6383882f7 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,10 @@ +2023-06-09 Simon Sobisch + + * error.c (print_error, diagnostics_show_caret): fix for C89 compat + * error.c (diagnostics_show_caret): trim trailing whitespace, + remove printing empty lines before/after, print EOF, changed format + 2023-06-02 Simon Sobisch * tree.h (cb_file), parser.y: organization and access_mode as enums @@ -41,7 +47,7 @@ 2023-05-28 Simon Sobisch * parser.y: allow expressions for screen related clauses - COL, LINE, LINES, SIZE, COLOR + COL, LINE, LINES, SIZE, COLOR, implementing FR #414 2023-05-26 Simon Sobisch diff --git a/cobc/error.c b/cobc/error.c index 941ab6f67..61421b95d 100644 --- a/cobc/error.c +++ b/cobc/error.c @@ -70,61 +70,60 @@ print_error_prefix (const char *file, int line, const char *prefix) } } -/* Display a context around the location of the error/warning, only if - * cb_diagnostics_show_caret is true +/* Display a context around the location of the error/warning, + only used if cb_diagnostics_show_caret is true Only display two lines before and after. No caret yet for the column as we only have the line. Since we directly use the file, source is printed - before any REPLACE. - */ - -#define CARET_MAX_COLS 73 + before any REPLACE. */ static void -diagnostics_show_caret (const char *file, int line) +diagnostics_show_caret (FILE *fd, const int line) { - FILE* fd = fopen(file, "r"); - if (fd == NULL) return; - char buffer[ CARET_MAX_COLS+1 ]; + #define CARET_MAX_COLS 73 + 5 + #define CARET_CONTEXT_LINES 2 + const int line_start = line > CARET_CONTEXT_LINES ? line - CARET_CONTEXT_LINES : 1; + const int line_end = line + CARET_CONTEXT_LINES; + const int max_pos = cb_diagnostics_show_line_numbers ? CARET_MAX_COLS - 5 : CARET_MAX_COLS; + char buffer[ CARET_MAX_COLS + 1 ]; int line_pos = 1; int char_pos = 0; - int printed = 0; /* nothing printed */ - while(1){ - int c = fgetc (fd); - if ( c == EOF ){ - if (printed){ - fprintf(stderr, "\n"); - } - fclose(fd); - return ; - } - buffer[char_pos] = c ; - if (c == '\n' || char_pos == CARET_MAX_COLS){ - buffer[char_pos] = 0; - if (line_pos > line-3 && line_pos < line+3){ - if (line_pos == line-2) fprintf(stderr, "\n"); - printed = 1; - fprintf (stderr, " "); - if (cb_diagnostics_show_line_numbers){ - fprintf (stderr, "%04d ", - line_pos); + int c = 0; + while (c != EOF) { + buffer[char_pos] = c = fgetc (fd);; + if (c == '\n' || c == EOF || char_pos == max_pos) { + if (line_pos >= line_start) { + /* prefix */ + if (cb_diagnostics_show_line_numbers) { + fprintf (stderr, "%5d %c ", line_pos, + line == line_pos ? '>' : '|'); + } else { + fprintf (stderr, " %c ", + line == line_pos ? '>' : ' '); } - fprintf (stderr, "%c %s%s\n", - line == line_pos ? '>' : ' ', - c == '\n' ? "" : ".." , - buffer); - if (line_pos == line+2){ - fprintf(stderr, "\n"); - fclose(fd); - return; + /* drop trailing whitespace from buffer */ + while (char_pos >= 0 + && (buffer[char_pos] == ' ' + || buffer[char_pos] == '\t' + || buffer[char_pos] == '\r' + || buffer[char_pos] == '\n' + || buffer[char_pos] == EOF + || char_pos == max_pos)) { + buffer[char_pos--] = 0; } + /* print it */ + fprintf (stderr, "%s%s\n", + buffer, + c == '\n' ? "" : + c == EOF ? "" : ".."); + } + if (line_pos++ >= line_end) { + break; } - while (c != '\n'){ - /* skip end of line too long */ + /* skip end of line too long */ + while (c != '\n' && c != EOF) { c = fgetc (fd); - if( c == EOF ) { fclose(fd); return ; } } - line_pos++; - char_pos=0; + char_pos = buffer[0] = 0; } else { char_pos++; } @@ -197,18 +196,23 @@ print_error (const char *file, int line, enum cb_error_kind kind, cb_add_error_to_listing (file, line, prefix, errmsg); } - static const char* last_caret_file = NULL ; - static int last_caret_line = -1 ; if (cb_diagnostics_show_caret - && file != NULL - && strcmp (file, COB_DASH) != 0 - && line - && (last_caret_file != file || last_caret_line != line) - ){ - /* remember last printed location to avoid reprinting it */ - last_caret_file = file; - last_caret_line = line; - diagnostics_show_caret (file, line); + && file != NULL + && strcmp (file, COB_DASH) != 0 + && line != 0) { + static const char *last_caret_file = NULL ; + static int last_caret_line = -1 ; + if (last_caret_file != file + || last_caret_line != line) { + FILE *fd = fopen (file, "r"); + if (fd) { + diagnostics_show_caret (fd, line); + fclose (fd); + } + /* remember last printed location to avoid reprinting it */ + last_caret_file = file; + last_caret_line = line; + } } } diff --git a/tests/testsuite.src/used_binaries.at b/tests/testsuite.src/used_binaries.at index 83fa09b07..abdce6f60 100644 --- a/tests/testsuite.src/used_binaries.at +++ b/tests/testsuite.src/used_binaries.at @@ -921,8 +921,7 @@ AT_CLEANUP AT_SETUP([cobc diagnostics show caret]) -# promoted on 2023-06-01T09:57 -AT_KEYWORDS([cobc diagnostics]) +#AT_KEYWORDS([cobc diagnostics]) AT_DATA([prog.cob],[ IDENTIFICATION DIVISION. PROGRAM-ID. prog. @@ -936,47 +935,78 @@ AT_DATA([prog.cob],[ MOVE 12 TO TEST-VAR DISPLAY TEST-VAR NO ADVANCING END-DISPLAY - STOP RUN. -]) -AT_CHECK([$COBC -Wall -fsyntax-only prog.cob], [1], [], -[prog.cob:7: error: CRUD.CPY: No such file or directory -prog.cob:6: warning: numeric value is expected @<:@-Wothers@:>@ -]) -AT_CHECK([$COMPILE -fdiagnostics-show-caret -fdiagnostics-show-line-numbers -j prog.cob], [1], [], -[prog.cob:7: error: CRUD.CPY: No such file or directory - - 0005 WORKING-STORAGE SECTION. - 0006 01 TEST-VAR PIC 9(2) VALUE 'A'. - 0007 > COPY 'CRUD.CPY'. - 0008 PROCEDURE DIVISION. - 0009 DISPLAY TEST-VAR NO ADVANCING - -prog.cob:6: warning: numeric value is expected - - 0004 DATA DIVISION. - 0005 WORKING-STORAGE SECTION. - 0006 > 01 TEST-VAR PIC 9(2) VALUE 'A'. - 0007 COPY 'CRUD.CPY'. - 0008 PROCEDURE DIVISION. - + STOP RUN... ]) -AT_CHECK([$COMPILE -fdiagnostics-show-caret -j prog.cob],[1], [], -[prog.cob:7: error: CRUD.CPY: No such file or directory - - WORKING-STORAGE SECTION. - 01 TEST-VAR PIC 9(2) VALUE 'A'. - > COPY 'CRUD.CPY'. - PROCEDURE DIVISION. - DISPLAY TEST-VAR NO ADVANCING -prog.cob:6: warning: numeric value is expected - - DATA DIVISION. - WORKING-STORAGE SECTION. - > 01 TEST-VAR PIC 9(2) VALUE 'A'. - COPY 'CRUD.CPY'. - PROCEDURE DIVISION. +# note: $COBC has -fdiagnostics-plain-output +AT_CHECK([$COBC -Wall -fsyntax-only prog.cob], [1], [], +[[prog.cob:7: error: CRUD.CPY: No such file or directory +prog.cob:6: warning: numeric value is expected [-Wothers] +prog.cob:14: warning: ignoring redundant . [-Wothers] +]]) +AT_CHECK([$COBC -fdiagnostics-show-caret -fdiagnostics-show-line-numbers prog.cob], [1], [], +[[prog.cob:7: error: CRUD.CPY: No such file or directory + 5 | WORKING-STORAGE SECTION. + 6 | 01 TEST-VAR PIC 9(2) VALUE 'A'. + 7 > COPY 'CRUD.CPY'. + 8 | PROCEDURE DIVISION. + 9 | DISPLAY TEST-VAR NO ADVANCING +prog.cob:6: warning: numeric value is expected [-Wothers] + 4 | DATA DIVISION. + 5 | WORKING-STORAGE SECTION. + 6 > 01 TEST-VAR PIC 9(2) VALUE 'A'. + 7 | COPY 'CRUD.CPY'. + 8 | PROCEDURE DIVISION. +prog.cob:14: warning: ignoring redundant . [-Wothers] + 12 | DISPLAY TEST-VAR NO ADVANCING + 13 | END-DISPLAY + 14 > STOP RUN... + 15 | +]]) + +AT_CHECK([$COBC -fdiagnostics-show-caret prog.cob], [1], [], +[[prog.cob:7: error: CRUD.CPY: No such file or directory + WORKING-STORAGE SECTION. + 01 TEST-VAR PIC 9(2) VALUE 'A'. + > COPY 'CRUD.CPY'. + PROCEDURE DIVISION. + DISPLAY TEST-VAR NO ADVANCING +prog.cob:6: warning: numeric value is expected [-Wothers] + DATA DIVISION. + WORKING-STORAGE SECTION. + > 01 TEST-VAR PIC 9(2) VALUE 'A'. + COPY 'CRUD.CPY'. + PROCEDURE DIVISION. +prog.cob:14: warning: ignoring redundant . [-Wothers] + DISPLAY TEST-VAR NO ADVANCING + END-DISPLAY + > STOP RUN... + +]]) + +# Testcase for trailing whitespace +AT_CHECK([sed -e 's/DIVISION\./DIVISION \.\t \t /' prog.cob > progsp.cob]) + +AT_CHECK([$COBC -Wno-others -fdiagnostics-show-caret progsp.cob], [1], [], +[[progsp.cob:7: error: CRUD.CPY: No such file or directory + WORKING-STORAGE SECTION. + 01 TEST-VAR PIC 9(2) VALUE 'A'. + > COPY 'CRUD.CPY'. + PROCEDURE DIVISION . + DISPLAY TEST-VAR NO ADVANCING +]]) + +# Testcase for line too long and printing only one line +AT_DATA([longgy.cob],[ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd +]) + +# note: this is actually an error in the parser line number, +# but until that is solved, it is a nice edge case of "line not available" +AT_CHECK([$COBC -Wno-others -fdiagnostics-show-caret longgy.cob], [1], [], +[[longgy.cob:2: error: PROGRAM-ID header missing + dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.. + > +]]) -]) AT_CLEANUP