From f87619312ef0a19f6d2b64dfb3fe00b7123ec619 Mon Sep 17 00:00:00 2001 From: "James K. Lowden" <jklowden@symas.com> Date: Fri, 24 Jan 2025 16:03:00 -0500 Subject: [PATCH] track copybook name location --- gcc/cobol/cbldiag.h | 39 ++++++++-- gcc/cobol/cdf-copy.cc | 26 +++---- gcc/cobol/cdf.y | 30 ++++---- gcc/cobol/copybook.h | 45 ++++++------ gcc/cobol/genapi.cc | 13 +--- gcc/cobol/genmath.cc | 8 --- gcc/cobol/genutil.cc | 8 --- gcc/cobol/lexio.cc | 33 +++++++-- gcc/cobol/lexio.h | 1 + gcc/cobol/parse.y | 19 +++-- gcc/cobol/parse_ante.h | 2 +- gcc/cobol/scan.l | 4 +- gcc/cobol/scan_ante.h | 5 ++ gcc/cobol/scan_post.h | 32 ++++++--- gcc/cobol/symbols.h | 34 +-------- gcc/cobol/util.cc | 160 +++++++++++------------------------------ 16 files changed, 189 insertions(+), 270 deletions(-) diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h index 608835035196..f228a0239ec8 100644 --- a/gcc/cobol/cbldiag.h +++ b/gcc/cobol/cbldiag.h @@ -28,7 +28,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _CBLDIAG_H +#ifdef _CBLDIAG_H +#pragma message __FILE__ " included twice" +#else #define _CBLDIAG_H const char * cobol_filename(); @@ -40,11 +42,34 @@ const char * cobol_filename(); void yyerror( const char fmt[], ... ); bool yywarn( const char fmt[], ... ); -#ifndef YYLTYPE -struct YYLTYPE; +/* Location type. Borrowed from parse.h as generated by Bison. */ +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE YYLTYPE; +struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +}; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 + +const YYLTYPE& cobol_location(); #endif -#ifndef YDFLTYPE -struct YDFLTYPE; + +#if ! defined YDFLTYPE && ! defined YDFLTYPE_IS_DECLARED +typedef struct YDFLTYPE YDFLTYPE; +struct YDFLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +}; +# define YDFLTYPE_IS_DECLARED 1 +# define YDFLTYPE_IS_TRIVIAL 1 + #endif // an error at a location, called from the parser for semantic errors @@ -71,7 +96,8 @@ void dbgmsg( const char fmt[], ... ); template <typename LOC> void gcc_location_set( const LOC& loc ); -#if defined(USE_LOCATION_DUMP) && !defined(LOCATION_DUMP_DEFINED) +// tree.h defines yy_flex_debug as a macro because options.h +#if ! defined(yy_flex_debug) template <typename LOC> static void location_dump( const char func[], int line, const char tag[], const LOC& loc) { @@ -82,7 +108,6 @@ location_dump( const char func[], int line, const char tag[], const LOC& loc) { func, line, tag, loc.first_line, loc.first_column, loc.last_line, loc.last_column); } -#define LOCATION_DUMP_DEFINED #endif #endif diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index 52096c641a01..d406e52f884f 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -272,15 +272,15 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { char *path = NULL; - if( directory || library ) { - if( directory && library ) { - path = xasprintf( "%s/%s/%s", directory, library, source ); + if( directory || library.name ) { + if( directory && library.name ) { + path = xasprintf( "%s/%s/%s", directory, library.name, source.name ); } else { - const char *dir = directory? directory : library; - path = xasprintf( "%s/%s", dir, source ); + const char *dir = directory? directory : library.name; + path = xasprintf( "%s/%s", dir, source.name ); } } else { - path = xasprintf( "%s", source ); + path = xasprintf( "%s", source.name ); } gcc_assert(path); @@ -289,12 +289,12 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { dbgmsg("copybook_elem_t::open_file: trying %s", path); if( (this->fd = open(path, O_RDONLY)) == -1 ) { - dbgmsg("could not open %s", path); + dbgmsg("could not open %s: %m", path); return fd; } - this->source = xstrdup(path); - if( ! cobol_filename(this->source, inode_of(fd)) ) { - yyerror("recursive copybook: '%s' includes itself", path); + this->source.name = path; + if( ! cobol_filename(this->source.name, inode_of(fd)) ) { + error_msg(source.loc, "recursive copybook: '%s' includes itself", path); (void)! close(fd); fd = -1; } @@ -336,9 +336,9 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { auto filename = globber.gl_pathv[i]; if( (this->fd = open(filename, O_RDONLY)) != -1 ) { dbgmsg("found copybook file %s", filename); - this->source = xstrdup(filename); - if( ! cobol_filename(this->source, inode_of(fd)) ) { - yyerror("recursive copybook: '%s' includes itself", this->source); + this->source.name = xstrdup(filename); + if( ! cobol_filename(this->source.name, inode_of(fd)) ) { + error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source); (void)! close(fd); fd = -1; } diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y index a3e90a520804..f961b05a17fb 100644 --- a/gcc/cobol/cdf.y +++ b/gcc/cobol/cdf.y @@ -29,8 +29,6 @@ */ %{ -#define USE_LOCATION_DUMP - #include "cobol-system.h" #include "ec.h" #include "common-defs.h" @@ -83,7 +81,7 @@ static YYLTYPE location_set( const YYLTYPE& loc ); (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - location_dump("parse.c", N, \ + location_dump("cdf.c", N, \ "rhs N ", YYRHSLOC (Rhs, N)); \ } \ else \ @@ -93,7 +91,7 @@ static YYLTYPE location_set( const YYLTYPE& loc ); (Current).first_column = \ (Current).last_column = YYRHSLOC (Rhs, 0).last_column; \ } \ - location_dump("parse.c", __LINE__, "current", (Current)); \ + location_dump("cdf.c", __LINE__, "current", (Current)); \ gcc_location_set( location_set(Current) ); \ } while (0) @@ -307,9 +305,9 @@ apply_cdf_turn( exception_turns_t& turns ) { top: partials { YYACCEPT; } | copy '.' { - const char *library = copybook.current()->library; + const char *library = copybook.library(); if( !library ) library = "SYSLIB"; - const char *source = copybook.current()->source; + const char *source = copybook.source(); dbgmsg("COPY %s from %s", source, library); YYACCEPT; } @@ -389,7 +387,7 @@ cdf_define: CDF_DEFINE cdf_constant NAME as cdf_expr[value] override | CDF_DEFINE cdf_constant NAME '=' cdf_expr[value] override { /* accept, but as error */ if( scanner_parsing() ) { - error_msg(@NAME, "CDF syntax error: %s = value invalid", $NAME); + error_msg(@NAME, "CDF error: %s = value invalid", $NAME); } } | CDF_DEFINE cdf_constant NAME as OFF @@ -607,7 +605,7 @@ cdf_factor: NAME { if( ! scanner_parsing() ) { yywarn("CDF skipping: no such variable '%s' (ignored)", $1); } else { - error_msg(@NAME, "CDF syntax error: no such variable '%s'", $1); + error_msg(@NAME, "CDF error: no such variable '%s'", $1); } $$ = cdfval_t(); } @@ -626,26 +624,22 @@ cdf_factor: NAME { ; copy: copy_impl - { - cbl_internal_error("valid COPY statement " - "should have been processed by the file-reader"); - } ; copy_impl: copybook_name suppress REPLACING replace_bys | copybook_name suppress ; -copybook_name: COPY name_one +copybook_name: COPY name_one[src] { - if( -1 == copybook.open($2.string) ) { - error_msg(@2, "could not open copybook file " - "for '%s'", $2.string); + if( -1 == copybook.open(@src, $src.string) ) { + error_msg(@src, "could not open copybook file " + "for '%s'", $src.string); YYERROR; } } | COPY name_one[src] IN name_one[lib] { - copybook.library($lib.string); - if( -1 == copybook.open($src.string) ) { + copybook.library(@lib, $lib.string); + if( -1 == copybook.open(@src, $src.string) ) { error_msg(@src, "could not open copybook file " "for '%s' in '%'s'", $src.string, $lib.string); YYERROR; diff --git a/gcc/cobol/copybook.h b/gcc/cobol/copybook.h index 93c7b7257421..8f02bc47ffca 100644 --- a/gcc/cobol/copybook.h +++ b/gcc/cobol/copybook.h @@ -28,7 +28,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _COPYBOOK_H +#ifdef _COPYBOOK_H +#pragma message __FILE__ " included twice" +#else #define _COPYBOOK_H FILE * copy_mode_start(); @@ -53,11 +55,18 @@ struct copybook_replace_t { replace_type_t type; const char *src, *tgt; }; - -struct copybook_elem_t { +class copybook_t; + +class copybook_elem_t { + friend copybook_t; + struct copybook_loc_t { + YYLTYPE loc; + const char *name; + copybook_loc_t() : name(NULL) {} + } source, library; bool suppress; - const char *source, *library; static const char *extensions; + public: struct { bool source, library; } literally; int fd; size_t nsubexpr; @@ -65,18 +74,6 @@ struct copybook_elem_t { copybook_elem_t() : suppress(false) - , source(NULL) - , library(NULL) - , fd(-1) - , nsubexpr(0) - , regex_text(NULL) - { - literally = {}; - } - explicit copybook_elem_t( char src[] ) - : suppress(false) - , source(src) - , library(NULL) , fd(-1) , nsubexpr(0) , regex_text(NULL) @@ -158,14 +155,16 @@ class copybook_t { void suppress( bool tf = true ) { book.suppress = tf; } bool suppressed() { return book.suppress; } - void source( const char name[] ) { + void source( const YYLTYPE& loc, const char name[] ) { + book.source.loc = loc; book.literally.source = copybook_elem_t::quoted(name); - book.source = book.literally.source? + book.source.name = book.literally.source? copybook_elem_t::dequote(name) : transform_name(name); } - void library( const char name[] ) { + void library( const YYLTYPE& loc, const char name[] ) { + book.library.loc = loc; book.literally.library = copybook_elem_t::quoted(name); - book.library = book.literally.library? + book.library.name = book.literally.library? copybook_elem_t::dequote(name) : transform_name(name); } void replacement( replace_type_t type, const char src[], const char tgt[] ) { @@ -174,11 +173,13 @@ class copybook_t { } copybook_elem_t *current() { return &book; } + const char *source() const { return book.source.name; } + const char *library() const { return book.library.name; } - int open(const char name[]) { + int open(YYLTYPE loc, const char name[]) { int fd = -1; book.clear(); - this->source(name); + this->source(loc, name); for( auto dir : directories ) { if( false ) { diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index e303639f99ea..b4d1d610f92c 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -44,27 +44,16 @@ #include "cbldiag.h" #include "symbols.h" #include "gengen.h" -#include "ec.h" -#include "common-defs.h" -#include "util.h" -#include "cbldiag.h" -#include "symbols.h" -#include "ec.h" -#include "common-defs.h" #include "inspect.h" #include "io.h" #include "genapi.h" #include "genutil.h" -#include "inspect.h" -#include "io.h" -#include "genapi.h" #include "genmath.h" #include "structs.h" #include "gcobolio.h" #include "libgcobol.h" #include "charmaps.h" #include "valconv.h" -#include "cbldiag.h" #include "show_parse.h" extern int yylineno; @@ -337,7 +326,7 @@ get_field_p(size_t index) if( !field->var_decl_node ) { - yyerror("%s (type: %s) improperly has a NULL var_decl_node", + dbgmsg("%s (type: %s) improperly has a NULL var_decl_node", field->name, cbl_field_type_str(field->type)); cbl_internal_error( diff --git a/gcc/cobol/genmath.cc b/gcc/cobol/genmath.cc index 72b17921f1bb..bd224da07a25 100644 --- a/gcc/cobol/genmath.cc +++ b/gcc/cobol/genmath.cc @@ -36,23 +36,15 @@ #include "util.h" #include "cbldiag.h" #include "symbols.h" -#include "ec.h" -#include "common-defs.h" #include "inspect.h" #include "io.h" #include "genapi.h" #include "genutil.h" #include "gengen.h" #include "structs.h" -#include "ec.h" -#include "common-defs.h" -#include "io.h" #include "gcobolio.h" -#include "symbols.h" #include "libgcobol.h" -#include "cbldiag.h" #include "show_parse.h" -#include "util.h" void set_up_on_exception_label(cbl_label_t *arithmetic_label) diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc index 87f683748a33..54f7a0b91e9c 100644 --- a/gcc/cobol/genutil.cc +++ b/gcc/cobol/genutil.cc @@ -37,13 +37,6 @@ #include "cbldiag.h" #include "symbols.h" #include "gengen.h" -#include "ec.h" -#include "common-defs.h" -#include "util.h" -#include "cbldiag.h" -#include "symbols.h" -#include "ec.h" -#include "common-defs.h" #include "inspect.h" #include "io.h" #include "genapi.h" @@ -52,7 +45,6 @@ #include "gcobolio.h" #include "libgcobol.h" #include "charmaps.h" -#include "cbldiag.h" #include "show_parse.h" #include "exceptl.h" #include "exceptg.h" diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc index 61c4216c3043..c3f17e525555 100644 --- a/gcc/cobol/lexio.cc +++ b/gcc/cobol/lexio.cc @@ -28,8 +28,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define USE_LOCATION_DUMP - #include <ext/stdio_filebuf.h> #include "cobol-system.h" #include "cbldiag.h" @@ -859,6 +857,24 @@ struct copy_descr_t { : parsed(false), fd(-1), nreplace(0), partial_line(line, eol) {} }; +static YYLTYPE +location_in( const filespan_t& mfile, const csub_match cm ) { + YYLTYPE loc { + int(mfile.lineno()), int(mfile.colno()), + int(mfile.lineno()), int(mfile.colno()) + }; + gcc_assert(mfile.cur <= cm.first && cm.second <= mfile.eodata); + auto nline = std::count(cm.first, cm.second, '\n'); + if( nline ) { + gcc_assert(loc.first_line < nline); + loc.first_line -= nline; + auto p = static_cast<const char*>(memrchr(cm.first, '\n', cm.length())); + loc.last_column = (cm.second) - p; + } + location_dump(__func__, __LINE__, "copy?", loc); + return loc; +} + static copy_descr_t parse_copy_directive( filespan_t& mfile ) { static const char *most_recent_buffer; @@ -929,11 +945,14 @@ parse_copy_directive( filespan_t& mfile ) { bool replacing = !cm[20].matched; if( library_name.matched ) { - copybook.library( xstrndup(library_name.first, library_name.length()) ); + YYLTYPE loc = location_in( mfile, library_name ); + copybook.library( loc, xstrndup(library_name.first, library_name.length()) ); } - outcome.fd = copybook.open( xstrndup(copybook_name.first, copybook_name.length()) ); - if( outcome.fd == -1 ) { // let parser report missing copybook - dbgmsg("%s: copybook '%s' not found", __func__, copybook.current()->source); + YYLTYPE loc = location_in( mfile, copybook_name ); + outcome.fd = copybook.open( loc, xstrndup(copybook_name.first, + copybook_name.length()) ); + if( outcome.fd == -1 ) { + error_msg(loc, "copybook '%s' not found", copybook.source()); return outcome; } @@ -1755,7 +1774,7 @@ cdftext::process_file( filespan_t mfile, int output, bool second_pass ) { struct { int in, out; filespan_t mfile; } copy; dbgmsg("%s:%d: line %zu, opening %s on fd %d", __func__, __LINE__, mfile.lineno(), - copybook.current()->source, copybook.current()->fd); + copybook.source(), copybook.current()->fd); copy.in = copybook.current()->fd; copy.mfile = free_form_reference_format( copy.in ); diff --git a/gcc/cobol/lexio.h b/gcc/cobol/lexio.h index d9890e049346..6c0bd0efcedc 100644 --- a/gcc/cobol/lexio.h +++ b/gcc/cobol/lexio.h @@ -144,6 +144,7 @@ struct filespan_t : public bytespan_t { {} size_t lineno() const { return iline; } + size_t colno() const { return icol; } void lineno_reset() { iline = 0; } size_t colno( size_t icol ) { return this->icol = icol; } diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 5996941340bc..d47c7e5cb9ba 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -284,7 +284,6 @@ #include <fstream> // Before cobol-system because it uses poisoned functions #include "cobol-system.h" #include "cdfval.h" -#define USE_LOCATION_DUMP #include "ec.h" #include "common-defs.h" #include "util.h" @@ -2436,16 +2435,16 @@ data_sections: data_section data_section: FILE_SECT '.' | FILE_SECT '.' { - current_data_section_set(file_datasect_e); + current_data_section_set(@1, file_datasect_e); } file_descrs | WORKING_STORAGE_SECT '.' { - current_data_section_set(working_storage_datasect_e); + current_data_section_set(@1, working_storage_datasect_e); } fields_maybe | LOCAL_STORAGE_SECT '.' { - current_data_section_set(local_storage_datasect_e); + current_data_section_set(@1, local_storage_datasect_e); } fields_maybe | LINKAGE_SECT '.' { - current_data_section_set(linkage_datasect_e); + current_data_section_set(@1, linkage_datasect_e); } fields_maybe | SCREEN SECTION '.' { cbl_unimplemented("SCREEN SECTION"); @@ -11560,13 +11559,13 @@ data_section_str( data_section_t section ) { return NULL; } -bool -current_data_section_set( data_section_t data_section ) { +static bool +current_data_section_set(const YYLTYPE& loc, data_section_t data_section ) { // order is mandatory if( data_section < current_data_section ) { - yyerror("%s SECTION must precede %s SECTION", - data_section_str(data_section), - data_section_str(current_data_section)); + error_msg(loc, "%s SECTION must precede %s SECTION", + data_section_str(data_section), + data_section_str(current_data_section)); return false; } diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index f0692b1f4b03..73efc8367208 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -149,7 +149,7 @@ enum data_section_t { // values reflect mandatory order linkage_datasect_e, } current_data_section; -bool current_data_section_set( enum data_section_t ); +static bool current_data_section_set( const YYLTYPE& loc, enum data_section_t ); enum data_clause_t { picture_clause_e = 0x0001, diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index 427c97e7bfa1..1760f4298cda 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -31,8 +31,6 @@ #include <fstream> // Before cobol-system because it uses poisoned functions #include "cobol-system.h" -#define USE_LOCATION_DUMP - #include "ec.h" #include "common-defs.h" #include "util.h" @@ -171,7 +169,7 @@ NAMTYP {NAME}|{VARTYPE} NL [[:blank:]]*\r?\n[[:blank:]]* -PUSH_FILE \f?[#]FILE{SPC}PUSH{SPC}.+\f +PUSH_FILE \f?[#]FILE{SPC}PUSH{SPC}[^\f]+\f POP_FILE \f?[#]FILE{SPC}POP\f LINE_DIRECTIVE [#]line{SPC}[[:alnum:]]+{SPC}[""''].+\n diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index 3dd44119b60d..5c02ffb56233 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -641,6 +641,11 @@ typed_name( const char name[] ) { return cbl_field_of(e)->level == 88? NAME88 : NAME; } +int +retype_name_token() { + return typed_name(ydflval.string); +} + static char * tmpstring_append( int len ) { char *s; diff --git a/gcc/cobol/scan_post.h b/gcc/cobol/scan_post.h index 071558ef320c..555c08f69549 100644 --- a/gcc/cobol/scan_post.h +++ b/gcc/cobol/scan_post.h @@ -207,7 +207,7 @@ run_cdf( int token ) { parsing.inject_token(token); // because it will be needed by CDF parser - if( yy_flex_debug ) yywarn("CDF parser start with '%s'", keyword_str(token)); + if( yy_flex_debug ) dbgmsg("CDF parser start with '%s'", keyword_str(token)); parsing.parser_save(ydfparse); @@ -218,7 +218,7 @@ run_cdf( int token ) { if( YY_START == cdf_state ) yy_pop_state(); if( yy_flex_debug ) { - yywarn("CDF parser done, scanner SC <%s>", start_condition_is()); + dbgmsg("CDF parser returned %d, scanner SC <%s>", erc, start_condition_is()); } return 0 == erc; @@ -272,9 +272,19 @@ prelex() { } if( yy_flex_debug ) { - yywarn("scanner SC <%s>", start_condition_is()); + dbgmsg("scanner SC <%s>", start_condition_is()); } - + + if( YY_START == copy_state || YY_START == cdf_state ) { + if( token == NAME ) { + auto tok = keyword_tok(ydflval.string); + if( tok ) token = tok; + } + yy_pop_state(); + dbgmsg("scanner SC <%s>, token now %s", + start_condition_is(), keyword_str(token)); + } + /* * The final, rejected CDF token might be a LEVEL number. */ @@ -306,10 +316,10 @@ prelex() { } } - if( yydebug ) yywarn( ">>CDF parser done, returning " - "%s (because final_token %s, lookhead %d) on line %d", - keyword_str(token), keyword_str(final_token), - ydfchar, yylineno ); + dbgmsg( ">>CDF parser done, %s returning " + "%s (because final_token %s, lookhead %d) on line %d", __func__, + keyword_str(token), keyword_str(final_token), + ydfchar, yylineno ); in_cdf = false; return token; } @@ -363,10 +373,10 @@ yylex(void) { token = prelex(); if( yy_flex_debug ) { if( parsing.in_cdf() ) { - yywarn( "%s:%d: %s routing %s to CDF parser", __func__, __LINE__, + dbgmsg( "%s:%d: %s routing %s to CDF parser", __func__, __LINE__, start_condition_is(), keyword_str(token) ); } else if( !parsing.on() ) { - yywarn( "eating %s because conditional compilation is FALSE", + dbgmsg( "eating %s because conditional compilation is FALSE", keyword_str(token) ); } } @@ -382,7 +392,7 @@ yylex(void) { } if( token == YYEOF && parsing.in_cdf() ) { - if( yy_flex_debug) yywarn("deflecting EOF"); + if( yy_flex_debug) dbgmsg("deflecting EOF"); parsing.at_eof(true); return NO_CONDITION; } diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index 16e6abc175f3..8a099569e5e3 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -27,7 +27,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _SYMBOLS_H_ +#ifdef _SYMBOLS_H_ +#pragma message __FILE__ " included twice" +#else #define _SYMBOLS_H_ #include <assert.h> @@ -67,36 +69,6 @@ strfromf128 (char *restrict string, size_t size, } #endif -/* Location type. Borrowed from parse.h as generated by Bison. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 - -const YYLTYPE& cobol_location(); -#endif - -#if ! defined YDFLTYPE && ! defined YDFLTYPE_IS_DECLARED -typedef struct YDFLTYPE YDFLTYPE; -struct YDFLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YDFLTYPE_IS_DECLARED 1 -# define YDFLTYPE_IS_TRIVIAL 1 - -#endif - extern const char *numed_message; enum cbl_dialect_t { diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc index 60001de7bd90..65330332877c 100644 --- a/gcc/cobol/util.cc +++ b/gcc/cobol/util.cc @@ -34,8 +34,6 @@ * header files. */ -#define USE_LOCATION_DUMP - #include "cobol-system.h" #include <langinfo.h> @@ -57,12 +55,9 @@ #include "cbldiag.h" #include "lexio.h" - #define HOWEVER_GCC_DEFINES_TREE #include "ec.h" #include "common-defs.h" -#include "util.h" -#include "cbldiag.h" #include "symbols.h" #include "inspect.h" #include "io.h" @@ -97,7 +92,7 @@ symbol_type_str( enum symbol_type_t type ) case SymDataSection: return "SymDataSection"; } - yywarn("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); return "???"; } @@ -146,7 +141,7 @@ cbl_field_type_str( enum cbl_field_type_t type ) case FldBlob: return "FldBlob"; } - yywarn("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); return "???"; } @@ -169,7 +164,7 @@ cbl_logop_str( enum logop_t op ) case false_op: return "false_op"; } - yywarn("%s:%d: invalid logop_t %d", __func__, __LINE__, op); + dbgmsg("%s:%d: invalid logop_t %d", __func__, __LINE__, op); return "???"; } @@ -239,7 +234,7 @@ is_alpha_edited( const char picture[] ) { if( symbol_currency(*p) ) continue; if( yydebug ) { - yywarn( "%s: bad character '%c' at %.*s<-- in '%s'", + dbgmsg( "%s: bad character '%c' at %.*s<-- in '%s'", __func__, *p, int(p - picture) + 1, picture, picture ); } return false; @@ -332,7 +327,7 @@ normalize_picture( char picture[] ) if( (erc = regcomp(preg, regex, cflags)) != 0 ) { regerror(erc, preg, regexmsg, sizeof(regexmsg)); - yywarn( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); + dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); return picture; } @@ -353,11 +348,11 @@ normalize_picture( char picture[] ) p = picture + pmatch[2].rm_so; len = 0; if( 1 != sscanf(p, "%zu", &len) ) { - yywarn("%s:%d: no number found in '%s'", __func__, __LINE__, p); + dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p); goto irregular; } if( len == 0 ) { - yywarn("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p); + dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p); goto irregular; } @@ -406,7 +401,7 @@ match( const char picture[], const char pattern[] ) if( (erc = regcomp(preg, pattern, cflags)) != 0 ) { regerror(erc, preg, regexmsg, sizeof(regexmsg)); - yywarn( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); + dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); return picture; } @@ -445,7 +440,7 @@ is_elementary( enum cbl_field_type_t type ) case FldFloat: return true; // takes up space } - yywarn("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); + dbgmsg("%s:%d: invalid symbol_type_t %d", __func__, __LINE__, type); return false; } @@ -466,12 +461,12 @@ integer_move_ok( const cbl_field_t *src, const cbl_field_t *tgt ) { if( is_numericish(src) && ! (tgt->type == FldInvalid || is_literal(tgt)) ) { if( src->data.rdigits > 0 ) { - yywarn("%s has %d rdigits", src->name, src->data.rdigits); + dbgmsg("%s has %d rdigits", src->name, src->data.rdigits); } - ////yywarn("%s:%d has %d rdigits", src->name, __LINE__, src->data.rdigits); + ////dbgmsg("%s:%d has %d rdigits", src->name, __LINE__, src->data.rdigits); return src->data.rdigits == 0; } - ////yywarn("%s:%d has %d rdigits", src->name, __LINE__, src->data.rdigits); + ////dbgmsg("%s:%d has %d rdigits", src->name, __LINE__, src->data.rdigits); return integer_move_ok( tgt, src ); } @@ -1020,9 +1015,9 @@ struct move_corresponding_field { tgt.field = cbl_field_of(symbol_at(elem.second)); if( yydebug ) { - yywarn("move_corresponding:%d: SRC: %3zu %s", __LINE__, + dbgmsg("move_corresponding:%d: SRC: %3zu %s", __LINE__, elem.first, src.str()); - yywarn("move_corresponding:%d: to %3zu %s", __LINE__, + dbgmsg("move_corresponding:%d: to %3zu %s", __LINE__, elem.second, tgt.str()); } @@ -1127,7 +1122,7 @@ valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ) if( yydebug && ! retval ) { auto bad = std::find_if( p, pend, []( char ch ) { return ! ISDIGIT(ch); } ); - yywarn("%s:%d: offending character '%c' at position %zu", + dbgmsg("%s:%d: offending character '%c' at position %zu", __func__, __LINE__, *bad, bad - p); } } @@ -1148,7 +1143,7 @@ valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ) retval = !src_alpha; break; default: - yywarn("%s:%d: matrix at %s, %s is %d", __func__, __LINE__, + dbgmsg("%s:%d: matrix at %s, %s is %d", __func__, __LINE__, cbl_field_type_str(src->type), cbl_field_type_str(tgt->type), matrix[src->type][tgt->type]); assert(false); @@ -1156,15 +1151,13 @@ valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src ) if( retval && src->has_attr(embiggened_e) ) { if( is_numeric(tgt) && tgt->data.capacity < src->data.capacity ) { - if( yydebug ) { - yywarn("error: source no longer fits in target"); - } + dbgmsg("error: source no longer fits in target"); return false; } } if( yydebug && getenv(__func__) ) { - yywarn("%s:%d: ok to move %s to %s (0x%02x)", __func__, __LINE__, + dbgmsg("%s:%d: ok to move %s to %s (0x%02x)", __func__, __LINE__, cbl_field_type_str(src->type), cbl_field_type_str(tgt->type), retval); } @@ -1190,7 +1183,7 @@ valid_picture( enum cbl_field_type_t type, const char picture[] ) case FldDisplay: case FldPointer: // These types don't take pictures; the grammar shouldn't call the function. - yywarn("%s:%d: no polaroid: %s", __func__, __LINE__, cbl_field_type_str(type)); + dbgmsg("%s:%d: no polaroid: %s", __func__, __LINE__, cbl_field_type_str(type)); return false; case FldNumericBinary: case FldFloat: @@ -1258,7 +1251,7 @@ type_capacity( enum cbl_field_type_t type, uint32_t digits ) return 16; } - yywarn( "%s:%d: invalid size %u for type %s", __func__, __LINE__, + dbgmsg( "%s:%d: invalid size %u for type %s", __func__, __LINE__, digits, cbl_field_type_str(type) ); return digits; @@ -1409,7 +1402,7 @@ public: (!key.has_paragraph() && 0 == strcasecmp(key.section(), ref.paragraph())) || 0 == strcasecmp(key.paragraph(), ref.paragraph()); if( false && hit ) { - yywarn("%s: key {%s of %s} matches ref {%s of %s} ", __func__, + dbgmsg("%s: key {%s of %s} matches ref {%s of %s} ", __func__, key.paragraph(), key.section(), ref.paragraph(), ref.section()); } @@ -1422,7 +1415,7 @@ globally_unique( size_t program, const procref_t& ref ) { const procedures_t& procedures = programs[program]; assert(!procedures.empty()); #if 0 - yywarn("%s: %zu matches for %s of '%s'", __func__, + dbgmsg("%s: %zu matches for %s of '%s'", __func__, count_if(procedures.begin(), procedures.end(), procedure_match(ref)), ref.paragraph(), ref.section()); #endif @@ -1437,7 +1430,7 @@ locally_unique( size_t program, const procdef_t& key, const procref_t& ref ) { procref_base_t full_ref(section_name, ref.paragraph()); if( getenv(__func__) ) { - yywarn("%s: %zu for ref %s of '%s' (line %d) " + dbgmsg("%s: %zu for ref %s of '%s' (line %d) " "in %s of '%s' (as %s of '%s')", __func__, procedures.count(full_ref), ref.paragraph(), ref.section(), ref.line_number(), @@ -1467,7 +1460,7 @@ procedure_definition_add( size_t program, const cbl_label_t *procedure ) { procdef_t key( section_name, paragraph_name, isym ); if( getenv(__func__) ) { - yywarn("%s: #%3zu %s of %s", __func__, isym, paragraph_name, section_name); + dbgmsg("%s: #%3zu %s of %s", __func__, isym, paragraph_name, section_name); } current_procedure = programs[program].insert( make_pair(key, procedures_t::mapped_type()) ); @@ -1479,7 +1472,7 @@ procedure_reference_add( const char *section, const char *paragraph, int line, size_t context ) { if( getenv(__func__) ) { - yywarn("%s: line %3d %s of %s", __func__, line, paragraph, section); + dbgmsg("%s: line %3d %s of %s", __func__, line, paragraph, section); } current_procedure->second.push_back( procref_t(section, paragraph, line, context) ); @@ -1497,10 +1490,10 @@ public: bool operator()( procedures_t::mapped_type::const_reference ref ) { #if 0 - yywarn("%s: %s of '%s' is %s locally unique", __func__, + dbgmsg("%s: %s of '%s' is %s locally unique", __func__, ref.paragraph(), ref.section(), locally_unique( program, key, ref )? "" : "not"); - yywarn("%s: %s of '%s' is %s globally unique", __func__, + dbgmsg("%s: %s of '%s' is %s globally unique", __func__, ref.paragraph(), ref.section(), globally_unique( program, ref )? "" : "not"); #endif @@ -1513,12 +1506,12 @@ public: #if 0 static void dump( procedures_t::const_reference elem ) { - yywarn( "%s: %s OF '%s' has %zu references:", __func__, + dbgmsg( "%s: %s OF '%s' has %zu references:", __func__, elem.first.paragraph(), elem.first.section(), elem.second.size() ); int i=0; for( auto p = elem.second.begin(); p != elem.second.end(); p++ ) { - yywarn("%s:\t%2d: %s OF '%s' at %d", __func__, ++i, + dbgmsg("%s:\t%2d: %s OF '%s' at %d", __func__, ++i, p->paragraph(), p->section(), p->line_number() ); } } @@ -1534,7 +1527,7 @@ ambiguous_reference( size_t program ) { is_unique(program, proc.first) ); if( proc.second.end() != ambiguous ) { if( yydebug || getenv("symbol_label_add")) { - yywarn("%s: %s of '%s' has %zu potential matches", __func__, + dbgmsg("%s: %s of '%s' has %zu potential matches", __func__, ambiguous->paragraph(), ambiguous->section(), procedures.count(*ambiguous)); } @@ -1600,7 +1593,7 @@ parent_names( const symbol_elem_t *elem, if( is_filler(cbl_field_of(elem)) ) return; - // yywarn("%s: asked about %s of %s (%zu away)", __func__, + // dbgmsg("%s: asked about %s of %s (%zu away)", __func__, // cbl_field_of(elem)->name, // cbl_field_of(group)->name, elem - group); @@ -1623,11 +1616,9 @@ public: symbol_elem_t *rgroup, type_t type ) : lgroup(lgroup), rgroup(rgroup), type(type) { - if( yydebug ) { - yywarn( "%s:%d: for #%zu %s and #%zu %s on line %d", __func__, __LINE__, + dbgmsg( "%s:%d: for #%zu %s and #%zu %s on line %d", __func__, __LINE__, symbol_index(lgroup), cbl_field_of(lgroup)->name, symbol_index(rgroup), cbl_field_of(rgroup)->name, yylineno ); - } } static bool @@ -1642,9 +1633,6 @@ public: corresponding_fields_t::value_type operator()( const symbol_elem_t& that ) { - // yywarn( "find_corresponding:%d: trying %s ", __LINE__, - // cbl_field_of(&that)->name ); - if( &that == lgroup ) return std::make_pair(0,0); if( that.type != SymField ) return std::make_pair(0,0); @@ -1691,9 +1679,6 @@ public: break; } - // yywarn( "find_corresponding:%d: %zu => %zu ", __LINE__, - // symbol_index(&that), symbol_index(e) ); - return std::make_pair( symbol_index(&that), symbol_index(e)); } }; @@ -1710,10 +1695,8 @@ corresponding_fields( cbl_field_t *lhs, cbl_field_t *rhs, lhsg.a = symbols_begin(field_index(lhs)); lhsg.z = std::find_if( lhsg.a, symbols_end(), next_group(lhsg.a) ); - if( yydebug ) { - yywarn("%s:%d: examining %zu symbols after %s", __func__, __LINE__, + dbgmsg("%s:%d: examining %zu symbols after %s", __func__, __LINE__, lhsg.z - lhsg.a, lhs->name); - } find_corresponding finder( symbol_at(field_index(lhs)), symbol_at(field_index(rhs)), type ); @@ -1721,10 +1704,8 @@ corresponding_fields( cbl_field_t *lhs, cbl_field_t *rhs, output.erase(0); - if( yydebug ) { - yywarn( "%s:%d: %s and %s have %zu corresponding fields", + dbgmsg( "%s:%d: %s and %s have %zu corresponding fields", __func__, __LINE__, lhs->name, rhs->name, output.size() ); - } return output; } @@ -1739,64 +1720,8 @@ corresponding_arith_fields( cbl_field_t *lhs, cbl_field_t *rhs ) { return corresponding_fields( lhs, rhs, find_corresponding::arith_op ); } - -static int file_of( cbl_file_t *file ) { - // return fileno from var_decl_node - yywarn("not implemented for %s", file->name); - return open("/dev/null", 0); // <-- not this -} -static size_t record_size( cbl_file_t *file ) { - // return record size of file - yywarn("not implemented for %s", file->name); - return 7; // <-- not this -} -static size_t record_count( cbl_file_t *file ) { - // return size of file - int fd = file_of(file); - size_t size = record_size(file); - struct stat sb; - - if( 0 != fstat(fd, &sb) ) { - return 0; - } - - if( 0 != sb.st_size % size ) { - yywarn("file %s is %zu bytes, not a multiple of record size %zu", - file->name, sb.st_size, size); - } - return sb.st_size / size; -} - typedef int (*file_sort_cmp_t)(const void *, const void *, void *); -/* - * mmap file, qsort, and unmap. - * File must be open. - * Returns FALSE only on OS error; errno is intact. - */ -bool -cbl_sort_file( cbl_file_t *file, file_sort_cmp_t cmp, void *arg ) { - static int offset = 0; - static int prot = PROT_READ | PROT_WRITE, flags = MAP_SHARED; - int fd = file_of(file); - size_t - size = record_size(file), - nelem = record_count(file); - - void *mem = mmap(NULL, size * nelem, prot, flags, fd, offset); - if( mem == MAP_FAILED ) { - return false; - } - - qsort_r( mem, nelem, size, cmp, arg ); - - if( 0 != munmap(mem, size * nelem) ) { - return false; - } - return true; - -} - /* * Concatenate files, appending src to tgt. Used by SORT. * Files must be open. @@ -1907,7 +1832,6 @@ date_time_fmt( const char input[] ) { if( ! compiled ) { for( auto& fmt : fmts ) { - ////yywarn( "%s: %c, %s", __func__, fmt.type, fmt.pattern ); if( (erc = regcomp(&fmt.reg, fmt.pattern, cflags)) != 0 ) { char msg[80]; regerror(erc, &fmt.reg, msg, sizeof(msg)); @@ -1917,7 +1841,6 @@ date_time_fmt( const char input[] ) { compiled = true; } - ////yywarn("%s: input '%s'", __func__, input); for( auto& fmt : fmts ) { if( 0 == regexec(&fmt.reg, input, COUNT_OF(m), m, eflags) ) { result = fmt.type; @@ -2023,7 +1946,7 @@ bool cobol_filename( const char *name, ino_t inode ) { auto p = old_filenames.find(name); if( p == old_filenames.end() ) { for( auto& elem : old_filenames ) { - yywarn("%6zu %-30s", elem.second, elem.first.c_str()); + dbgmsg("%6zu %-30s", elem.second, elem.first.c_str()); } cbl_errx( "logic error: missing inode for %s", name); } @@ -2034,7 +1957,7 @@ bool cobol_filename( const char *name, ino_t inode ) { bool pushed = input_filenames.push( input_file_t(name, inode, 1, lines) ); input_filenames.top().lineno = yylineno = 1; if( getenv(__func__) ) { - yywarn(" saving %s with lineno as %d", + dbgmsg(" saving %s with lineno as %d", input_filenames.top().name, input_filenames.top().lineno); } symbol_cobol_filename_begin(name); @@ -2047,7 +1970,7 @@ cobol_lineno_save() { auto& input( input_filenames.top() ); input.lineno = yylineno; if( getenv(__func__) ) { - yywarn(" setting %s with lineno as %d", input.name, input.lineno); + dbgmsg(" setting %s with lineno as %d", input.name, input.lineno); } return input.name; } @@ -2073,8 +1996,7 @@ cobol_filename_restore( bool scanning ) { yylineno = input.lineno; if( getenv("cobol_filename") ) { - yywarn("restoring %s with lineno to %d", - input_filenames.top().name, input.lineno); + dbgmsg("restoring %s with lineno to %d", input.name, input.lineno); } symbol_cobol_filename_begin(input.name); return input.name; @@ -2135,7 +2057,7 @@ ydferror( const char gmsgid[], ... ) { va_start (ap, gmsgid); rich_location richloc (line_table, token_location); bool ret = global_dc->diagnostic_impl (&richloc, nullptr, option_id, - gmsgid, &ap, DK_WARNING); + gmsgid, &ap, DK_ERROR); va_end (ap); } @@ -2274,7 +2196,7 @@ cobol_fileline_set( const char line[] ) { if( !preg ) { if( (erc = regcomp(&re, pattern, cflags)) != 0 ) { regerror(erc, &re, regexmsg, sizeof(regexmsg)); - yywarn( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); + dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); return line; } preg = &re; @@ -2282,7 +2204,7 @@ cobol_fileline_set( const char line[] ) { if( (erc = regexec(preg, line, COUNT_OF(pmatch), pmatch, 0)) != 0 ) { if( erc != REG_NOMATCH ) { regerror(erc, preg, regexmsg, sizeof(regexmsg)); - yywarn( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); + dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg ); return line; } yyerror("invalid #line directive: %s", line ); -- GitLab