diff --git a/NEWS b/NEWS index bf704edeb..e2885637e 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,11 @@ NEWS - user visible changes -*- outline -*- to stop compiliation at first error use -Wfatal-errors ** default value for -fmax-errors was changed from 128 to 20 +** New option -fdiagnostics-absolute-paths to print the full path of + a file for diagnostics; this flag can be activated if your editor and + build system do not correctly work together to locate files from + diagnostic output + * More notable changes ** execution times were significantly reduced for the following: diff --git a/build_windows/config.h.in b/build_windows/config.h.in index 55a082451..e294ff951 100644 --- a/build_windows/config.h.in +++ b/build_windows/config.h.in @@ -788,7 +788,7 @@ #define PACKAGE_NAME "GnuCOBOL" /* Define to the version of this package. */ -#define PACKAGE_VERSION "3.2-dev" +#define PACKAGE_VERSION "3.3-dev" /* Define to the full name and version of this package. */ #define PACKAGE_STRING PACKAGE_NAME " " PACKAGE_VERSION diff --git a/cobc/ChangeLog b/cobc/ChangeLog index b4269bfe1..93a02ac96 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,10 @@ +2023-11-29 Fabrice Le Fessant + + * cobc.c (cobc_clean_up): when save-temps specifies a directory, + do not move object files and preprocess files when they were + specified as an explicit target on the command line (-E, -c) + 2023-10-17 David Declerck BUG #923: generated modules init/clear unused decimal constants @@ -22,6 +28,14 @@ * codegen.c (codegen_internal, codegen_finalize): move declaration of decimal constants from global storage to local storage +2023-10-02 Fabrice Le Fessant + + * error.c (print_error_prefix), flag.def: new flag + -fdiagnostics-absolute-paths to print the full path of + a file for diagnostics; this flag can be activated if + your editor and build system do not correctly work + together to locate files from diagnostic output + 2023-09-12 Simon Sobisch * codegen.c (literal_list): removed self-reference as tree @@ -45,6 +59,7 @@ 2023-09-01 Simon Sobisch + FR #443: error handling for non-cobol "sources" * pplex.l (ppopen_get_file): test for binary file and directly error out * cobc.c (cobc_terminate_exit), cobc.h: split cobc_terminate and make the new function available diff --git a/cobc/cobc.c b/cobc/cobc.c index 23a01bccf..57f254cfb 100644 --- a/cobc/cobc.c +++ b/cobc/cobc.c @@ -2180,7 +2180,8 @@ clean_up_intermediates (struct filename *fn, const int status) if (fn->need_preprocess && (status || cb_compile_level > CB_LEVEL_PREPROCESS - || (cb_compile_level == CB_LEVEL_PREPROCESS && save_temps))) { + || (cb_compile_level == CB_LEVEL_PREPROCESS + && save_temps && !save_temps_dir))) { cobc_check_action (fn->preprocess); } /* CHECKME: we had reports of unexpected intermediate @@ -2287,7 +2288,8 @@ cobc_clean_up (const int status) if (fn->need_assemble && (status || cb_compile_level > CB_LEVEL_ASSEMBLE - || (cb_compile_level == CB_LEVEL_ASSEMBLE && save_temps))) { + || (cb_compile_level == CB_LEVEL_ASSEMBLE + && save_temps && !save_temps_dir))) { cobc_check_action (fn->object); } clean_up_intermediates (fn, status); @@ -3575,6 +3577,8 @@ process_command_line (const int argc, char **argv) /* -fdiagnostics-plain-output */ cb_diagnostics_show_caret = 0 ; cb_diagnostics_show_line_numbers = 0; + /* in the future, may also disable urls, + colors, text art, flow paths */ break; case 'P': diff --git a/cobc/error.c b/cobc/error.c index 93fa84941..9c971d66e 100644 --- a/cobc/error.c +++ b/cobc/error.c @@ -28,10 +28,20 @@ #include #include #include +#ifdef HAVE_SYS_STAT_H +#include +#endif #include "cobc.h" #include "tree.h" +#ifdef _WIN32 +#if !defined(__BORLANDC__) && !defined(__WATCOMC__) && !defined(__ORANGEC__) +#include // _getcwd +#define getcwd _getcwd +#endif +#endif + enum cb_error_kind { CB_KIND_ERROR, CB_KIND_WARNING, @@ -57,6 +67,32 @@ static void print_error_prefix (const char *file, int line, const char *prefix) { if (file) { + char *absfile = NULL ; + if (cb_diagnostics_absolute_paths + && strcmp (file, COB_DASH) != 0 + && file[0] != '/' + && file[0] != '\\' + && file[1] != ':'){ + int filelen = strlen (file); + int dirlen = 256; + char *cwd ; + absfile = cobc_malloc( dirlen + 1 + filelen + 1 ); + cwd = getcwd (absfile, dirlen); + if (cwd != NULL ){ +#ifdef HAVE_SYS_STAT_H + struct stat st; +#endif + dirlen = strlen (cwd); + absfile[dirlen] = '/'; + memcpy (absfile+dirlen+1, file, filelen+1); +#ifdef HAVE_SYS_STAT_H + if (!stat (absfile,&st)) +#endif + { + file = absfile; + } + } + } if (line <= 0) { fprintf (stderr, "%s: ", file); } else if (cb_msg_style == CB_MSG_STYLE_MSC) { @@ -64,6 +100,7 @@ print_error_prefix (const char *file, int line, const char *prefix) } else { fprintf (stderr, "%s:%d: ", file, line); } + if (absfile) cobc_free (absfile); } if (prefix) { fprintf (stderr, "%s", prefix); diff --git a/cobc/flag.def b/cobc/flag.def index 5c14a7c3b..d362ee99b 100644 --- a/cobc/flag.def +++ b/cobc/flag.def @@ -255,3 +255,6 @@ CB_FLAG_ON (cb_diagnostics_show_caret, 1, "diagnostics-show-caret", CB_FLAG_ON (cb_diagnostics_show_line_numbers, 1, "diagnostics-show-line-numbers", _(" -fno-diagnostics-show-line-numbers\tsuppress display of line numbers in diagnostics")) + +CB_FLAG (cb_diagnostics_absolute_paths, 1, "diagnostics-absolute-paths", + _(" -fdiagnostics-absolute-paths\tprint absolute paths in diagnostics")) diff --git a/cobc/tree.c b/cobc/tree.c index 8aed921ad..0e945aeaf 100644 --- a/cobc/tree.c +++ b/cobc/tree.c @@ -5998,14 +5998,16 @@ cb_build_binary_op (cb_tree x, const enum cb_binary_op_op op, cb_tree y) && !(CB_FIELD_PTR (x)->usage == CB_USAGE_COMP_5 || CB_FIELD_PTR (x)->usage == CB_USAGE_COMP_X)) { cb_error_x (CB_TREE(current_statement), - _("%s should be COMP-X/COMP-5 for logical operator"), CB_FIELD_PTR (x)->name); + _("%s should be COMP-X/COMP-5 for logical operator"), + CB_FIELD_PTR (x)->name); return cb_error_node; } if ((CB_REF_OR_FIELD_P (y)) && !(CB_FIELD_PTR (y)->usage == CB_USAGE_COMP_5 || CB_FIELD_PTR (y)->usage == CB_USAGE_COMP_X)) { cb_error_x (CB_TREE(current_statement), - _("%s should be COMP-X/COMP-5 for logical operator"), CB_FIELD_PTR (y)->name); + _("%s should be COMP-X/COMP-5 for logical operator"), + CB_FIELD_PTR (y)->name); return cb_error_node; } if (cb_constant_folding @@ -6382,9 +6384,7 @@ cb_build_binary_op (cb_tree x, const enum cb_binary_op_op op, cb_tree y) cb_tree cb_build_binary_list (cb_tree l, const int op) { - cb_tree e; - - e = CB_VALUE (l); + cb_tree e = CB_VALUE (l); for (l = CB_CHAIN (l); l; l = CB_CHAIN (l)) { e = cb_build_binary_op (e, op, CB_VALUE (l)); } diff --git a/configure.ac b/configure.ac index 8a3e29d17..7d48ddf01 100644 --- a/configure.ac +++ b/configure.ac @@ -580,7 +580,7 @@ AC_CACHE_SAVE # Checks for header files. dnl entries only used from external includes -> likely no need to check here -dnl AC_CHECK_HEADERS([stdint.h whcar.h malloc.h]) +dnl AC_CHECK_HEADERS([whcar.h malloc.h]) # mandatory: AC_CHECK_HEADERS([sys/types.h signal.h stddef.h], [], [AC_MSG_ERROR([mandatory header could not be found or included])]) diff --git a/doc/gnucobol.texi b/doc/gnucobol.texi index a0ff783b6..0ed1f9f0a 100644 --- a/doc/gnucobol.texi +++ b/doc/gnucobol.texi @@ -116,6 +116,7 @@ Compiler options * Build target:: Build target * Source format:: Source format * Warning options:: Warning options +* Diagnostics options:: Diagnostics options * Configuration options:: Configuration options * Listing options:: Listing options * Debug switches:: Debug switches @@ -281,6 +282,7 @@ A complete list of options can be displayed by using the option @option{--help}. * Build target:: Build target * Source format:: Source format * Warning options:: Warning options +* Diagnostics options:: Diagnostics options * Configuration options:: Configuration options * Listing options:: Listing options * Debug switches:: Debug switches @@ -651,6 +653,34 @@ Warn if statements are likely unreachable. This is @emph{not} set with @option{- Enable warnings that don't have an own warning flag. @end table +@node Diagnostics options +@subsection Diagnostics options + +The compiler provides some options to tune the way errors and warnings +(diagnostics) are displayed to the user. + +@table @code + +@item -fdiagnostics-absolute-paths +Print absolute paths in diagnostics. This option can be useful if your editor is not able +to correctly locate relative paths in your project. + +@item -fdiagnostics-plain-output +Make diagnostic output as plain as possible. + +@item -fno-diagnostics-show-option +Suppress output of option that directly controls the diagnostic, on which +warnings should be displayed. + +@item -fno-diagnostics-show-caret +Do not display source context on warning/error diagnostic. By default, diagnostics +contain an excerpt with two lines before and after the location. + +@item -fno-diagnostics-show-line-numbers +Suppress display of line numbers in the source context in diagnostics + +@end table + @node Configuration options @subsection Configuration options diff --git a/libcob/ChangeLog b/libcob/ChangeLog index b2b420e5a..96e4e9ff7 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -2,15 +2,25 @@ 2023-12-14 David Declerck * common.c (cob_terminate_routines, cob_call_with_exception_check): - add a mechanism to postpone unloading of modules when using longjmp, - as this is not safe on Windows (its implementation of longjmp - performs stack-unwinding) + add a mechanism to postpone unloading of modules when using longjmp, + as this is not safe on Windows (its implementation of longjmp + performs stack-unwinding) + +2023-11-29 Fabrice Le Fessant + + * common.c (cob_get_strerror), coblocal.h: export as utility function + * common.c (cob_expand_env_string): fix potention buffer overflow 2023-10-17 David Declerck * common.h: use stdint.h and inttypes.h when available to define cob_s64_t, cob_u64_t and the various CB_FMT_ macros +2023-10-04 Simon Sobisch + + * fileio.c (lineseq_write, lineseq_rewrite): fix bug #918 partial broken + COB_LS_VALIDATE by incrementing pointer outside of macro IS_BAD_CHAR + 2023-09-15 Simon Sobisch Fixing Bug #914 CLOSE LOCK abends program on OPEN diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 835f972fe..27f8de170 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -487,6 +487,7 @@ COB_HIDDEN int cob_check_env_true (char*); COB_HIDDEN int cob_check_env_false (char*); COB_HIDDEN const char *cob_get_last_exception_name (void); COB_HIDDEN void cob_parameter_check (const char *, const int); +COB_HIDDEN char* cob_get_strerror (void); enum cob_case_modifier { CCM_NONE, diff --git a/libcob/common.c b/libcob/common.c index ca22d9f3b..9dacd1d94 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -922,7 +922,7 @@ cob_get_source_line () } /* reentrant version of strerror */ -static char * +char * cob_get_strerror (void) { size_t size; @@ -7802,9 +7802,10 @@ cob_expand_env_string (char *strval) } } if (penv != NULL) { - if ((strlen (penv) + j) > (envlen - 128)) { - env = cob_realloc (env, envlen, strlen (penv) + 256); - envlen = strlen (penv) + 256; + size_t copy_len = strlen (penv); + if (copy_len + j + 128 > envlen) { + env = cob_realloc (env, envlen, j + copy_len + 256); + envlen = j + copy_len + 256; } j += sprintf (&env[j], "%s", penv); penv = NULL; diff --git a/libcob/screenio.c b/libcob/screenio.c index a1e90a85e..8f743bbd8 100644 --- a/libcob/screenio.c +++ b/libcob/screenio.c @@ -3105,27 +3105,26 @@ extract_line_and_col_vals (cob_field *line, cob_field *column, *sline = 0; *scolumn = 0; return; + } + if (line->size < 4) { + /* this is used when only a LINE clause is specified, + not an AT clause */ + cobol_line = cob_get_int (line); + cobol_col = 1; } else { - if (line->size < 4) { - /* this is used when only a LINE clause is specified, - not an AT clause */ - cobol_line = cob_get_int (line); - cobol_col = 1; - } else { - /* common case: line actually contains both the - line and field numbers */ - int ret = get_line_and_col_from_field - (line, &cobol_line, &cobol_col); - /* LCOV_EXCL_START */ - if (unlikely (ret == 1)) { -#if 0 /* Throw an exception? EC-SCREEN-IMP-LINE-VAR-LENGTH? */ - cob_set_exception (COB_EC_SCREEN_IMP); + /* common case: line actually contains both the + line and field numbers */ + int ret = get_line_and_col_from_field + (line, &cobol_line, &cobol_col); + /* LCOV_EXCL_START */ + if (unlikely (ret == 1)) { +#if 0 /* Throw an exception? EC-SCREEN-IMP-LINE-VAR-LENGTH? */ + cob_set_exception (COB_EC_SCREEN_IMP); #else - cob_fatal_error (COB_FERROR_CODEGEN); + cob_fatal_error (COB_FERROR_CODEGEN); #endif - } - /* LCOV_EXCL_STOP */ } + /* LCOV_EXCL_STOP */ } } else { get_line_column (line, column, &cobol_line, &cobol_col); @@ -4188,7 +4187,7 @@ cob_display_field (cob_field *f, const cob_flags_t fattr, const char *parms, ... if (parms && *parms) { va_list args; - const char *p = parms; + const char *p = parms; va_start (args, parms); for (;;) { @@ -4828,10 +4827,12 @@ cob_sys_get_char (unsigned char *fld) return -1; } } + return 0; #else + /* this function is only valid for extended screenio! */ COB_UNUSED (fld); + return -2; #endif - return 0; } /* set CurSoR position on screen, diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index e65af5080..18b32583d 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -10795,14 +10795,7 @@ AT_CHECK([diff reference tstdump.sed], [0], [], []) -AT_CHECK([$COMPILE prog.cob sub2.cob], [0], [], []) - -# also checking that a dump file without anything to dump does not do anything -AT_CHECK([COB_STACKTRACE=1 COB_DUMP_FILE=tstdump.dump \ -$COBCRUN_DIRECT ./prog], [1], -[X is 000000001 -X is 000005441 -], +AT_DATA([reference_stderr], [libcob: cpyabrt:4: error: LINKAGE item 'TSPFL-RECORD' (accessed by 'CM-COMPANY') not passed by caller libcob: cpyabrt:4: warning: implicit CLOSE of FLATFILE ('RELFIX') @@ -10820,30 +10813,35 @@ libcob: cpyabrt:4: warning: implicit CLOSE of FLATFILE ('RELFIX') Started by ./prog ]) +AT_CAPTURE_FILE([stderr.txt]) + +AT_CHECK([$COMPILE prog.cob sub2.cob], [0], [], []) + +# also checking that a dump file without anything to dump does not do anything +AT_CHECK([COB_STACKTRACE=1 COB_DUMP_FILE=tstdump.dump \ +$COBCRUN_DIRECT ./prog 2>stderr.txt], [1], +[X is 000000001 +X is 000005441 +], []) + +AT_CHECK([$SED -e 's/Started by .*prog.exe/Started by .\/prog/g' \ +stderr.txt > stderr.sed], [0], [], []) + +AT_CHECK([diff reference_stderr stderr.sed], [0], [], []) + AT_CHECK([$COMPILE -fdump=ALL -fno-dump prog.cob sub2.cob], [0], [], []) # also checking that a dump file without anything to dump does not do anything AT_CHECK([COB_STACKTRACE=1 COB_DUMP_FILE=tstdump.dump \ -$COBCRUN_DIRECT ./prog], [1], +$COBCRUN_DIRECT ./prog 2>stderr.txt], [1], [X is 000000001 X is 000005441 -], -[libcob: cpyabrt:4: error: LINKAGE item 'TSPFL-RECORD' (accessed by 'CM-COMPANY') not passed by caller -libcob: cpyabrt:4: warning: implicit CLOSE of FLATFILE ('RELFIX') +], []) - Last statement of "sub1" was MOVE - MAIN-2 OF MAIN-1 at cpyabrt:4 - MAIN-1 at prog.cob:177 - ENTRY sub1 at prog.cob:159 - Last statement of "sub2" was CALL - DO-CALL OF SubwaY at sub2.cob:48 - ENTRY sub2 at sub2.cob:39 - Last statement of "prog" was CALL - CALL-IT-OMIT at prog.cob:118 - MAIN-100 at prog.cob:85 - ENTRY prog at prog.cob:77 - Started by ./prog -]) +AT_CHECK([$SED -e 's/Started by .*prog.exe/Started by .\/prog/g' \ +stderr.txt > stderr.sed], [0], [], []) + +AT_CHECK([diff reference_stderr stderr.sed], [0], [], []) AT_CHECK([$COMPILE -fdump=FD,LS prog.cob sub2.cob -o prog_fdls], [0], [], []) @@ -10921,7 +10919,8 @@ END OF DUMP - prog # AT_DATA workaround via sed: AT_CHECK([$SED -e 's/_$//' reference_fdls_tmpl > reference], [0], [], []) -AT_CHECK([$SED -e 's/compiled ... .. .... ..:..:../compiled MMM DD YYYY HH:MM:SS/g' \ +AT_CHECK([$SED -e 's/compiled ... .. .... ..:..:../compiled MMM DD YYYY HH:MM:SS/g; + s/Started by .*prog_fdls.exe/Started by .\/prog_fdls/g' \ tstdump_fdls.dump > tstdump.sed], [0], [], []) AT_CHECK([diff reference tstdump.sed], [0], [], []) @@ -10939,7 +10938,8 @@ libcob: cpyabrt:4: warning: implicit CLOSE of FLATFILE ('RELFIX') dump written to tstdump_allfdls.dump ]) -AT_CHECK([$SED -e 's/compiled ... .. .... ..:..:../compiled MMM DD YYYY HH:MM:SS/g' \ +AT_CHECK([$SED -e 's/compiled ... .. .... ..:..:../compiled MMM DD YYYY HH:MM:SS/g; + s/Started by .*prog_allfdls.exe/Started by .\/prog_allfdls/g' \ tstdump_allfdls.dump > tstdump.sed], [0], [], []) AT_CHECK([$SED -e 's/prog_fdls/prog_allfdls/' \ @@ -11272,7 +11272,8 @@ END OF DUMP - prog ]) # AT_DATA workaround via sed: -AT_CHECK([$SED -e 's/compiled ... .. .... ..:..:../compiled MMM DD YYYY HH:MM:SS/g' \ +AT_CHECK([$SED -e 's/compiled ... .. .... ..:..:../compiled MMM DD YYYY HH:MM:SS/g; + s/Started by .*prog.exe/Started by .\/prog/g' \ dumpall.txt > dumpall.sed], [0], [], []) AT_CHECK([test "$COB_HAS_64_BIT_POINTER" = "yes"], [0], [], [], diff --git a/tests/testsuite.src/used_binaries.at b/tests/testsuite.src/used_binaries.at index 2daeb9ffb..b99b7e6f4 100644 --- a/tests/testsuite.src/used_binaries.at +++ b/tests/testsuite.src/used_binaries.at @@ -433,6 +433,68 @@ AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [OK], []) AT_CLEANUP +AT_SETUP([save-temps in sub-directory]) +AT_KEYWORDS([runmisc]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + PROCEDURE DIVISION. + DISPLAY "OK" NO ADVANCING + END-DISPLAY. + EXIT PROGRAM. +]) + +AT_CHECK([mkdir debug]) + +AT_CHECK([$COMPILE -save-temps=debug -o prog.exe prog.cob]) +AT_CHECK([$COBCRUN_DIRECT ./prog.exe], [0], [OK]) +AT_CHECK([test -f debug/prog.$COB_OBJECT_EXT]) +AT_CHECK([test -f debug/prog.c]) +AT_CHECK([test -f debug/prog.s], [1]) +AT_CHECK([test -f debug/prog.i]) +AT_CHECK([test -f debug/prog.c.h]) +AT_CHECK([test -f debug/prog.c.l.h]) + +# Check with -c + +AT_CHECK([test -f prog.$COB_OBJECT_EXT], [1]) +AT_CHECK([$COMPILE -save-temps=debug -c prog.cob]) +AT_CHECK([test -f prog.$COB_OBJECT_EXT]) +AT_CHECK([$COMPILE -save-temps=debug -c -o program.$COB_OBJECT_EXT prog.cob]) +AT_CHECK([test -f program.$COB_OBJECT_EXT]) + +# Check with -S + +AT_CHECK([test -f prog.s], [1]) +AT_CHECK([$COMPILE -save-temps=debug -S prog.cob]) +AT_CHECK([test -f prog.s]) +AT_CHECK([$COMPILE -save-temps=debug -S -o program.s prog.cob]) +AT_CHECK([test -f program.s]) + +# Check with -C + +AT_CHECK([test -f prog.c], [1]) +AT_CHECK([$COMPILE -save-temps=debug -C prog.cob]) +AT_CHECK([test -f prog.c]) +AT_CHECK([test -f prog.c.h]) +AT_CHECK([test -f prog.c.l.h]) +AT_CHECK([$COMPILE -save-temps=debug -C -o program.c prog.cob]) +AT_CHECK([test -f program.c]) +AT_CHECK([test -f program.c.h]) +AT_CHECK([test -f program.c.l.h]) + +# Check with -E + +AT_CHECK([test -f prog.i], [1]) +AT_CHECK([$COMPILE -save-temps=debug -E -o prog.i prog.cob]) +AT_CHECK([test -f prog.i]) +AT_CHECK([$COMPILE -save-temps=debug -E -o program.i prog.cob]) +AT_CHECK([test -f program.i]) + +AT_CLEANUP + + AT_SETUP([C Compiler optimizations]) AT_KEYWORDS([runmisc cobc optimization]) @@ -1009,5 +1071,13 @@ AT_CHECK([$COBC -fdiagnostics-plain-output -fdiagnostics-show-caret -Wno-others > ]]) +AT_CHECK([$COMPILE -fdiagnostics-absolute-paths -Wall prog.cob 2> compiler.output], [1]) + +AT_CHECK([$SED -e "s|$PWD|HOME|" compiler.output], [0], +[HOME/prog.cob:7: error: CRUD.CPY: No such file or directory +HOME/prog.cob:6: warning: numeric value is expected +HOME/prog.cob:14: warning: ignoring redundant . +]) + AT_CLEANUP