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