]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cobol: Some 1000 small changes in answer to cppcheck diagnostics.
authorJames K. Lowden <jklowden@cobolworx.com>
Mon, 16 Jun 2025 15:43:35 +0000 (11:43 -0400)
committerJames K. Lowden <jklowden@cobolworx.com>
Mon, 16 Jun 2025 19:47:12 +0000 (15:47 -0400)
constification per cppcheck. Use STRICT_WARN and fix reported
diagnostics.  Ignore [shadowVariable] in general. Use std::vector to
avoid exposing arrays as raw pointers.

PR cobol/120621

gcc/cobol/ChangeLog:

* Make-lang.in: Use STRICT_WARN.
* cbldiag.h (location_dump): suppress shadowVariable.
* cdf-copy.cc (esc): Fix shadowVariable.
(copybook_elem_t::open_file): Do not use %m.
* cdf.y: suppress invalidPrintfArgType for target format.
* cdfval.h (struct cdfval_t): Suppress noExplicitConstructor.
* cobol1.cc (cobol_name_mangler): Use C++ cast.
* copybook.h (class copybook_elem_t): Same.
* dts.h: Fixes and suppressions due to cppcheck.
* except.cc (cbl_enabled_exceptions_t::status): Suppress useStlAlgorithm.
(cbl_enabled_exceptions_t::turn_on_off): Const parameter.
(class choose_declarative): Removed.
* genapi.cc (struct called_tree_t): Explicit constructor.
(parser_compile_ecs): Cast to void * for %p.
(parser_compile_dcls): Same.
(parser_statement_begin): Same.
(initialize_variable_internal): Use std::vector for subscripts.
(parser_initialize): Constification.
(get_string_from): Same.
(combined_name): Same.
(parser_perform): Same.
(psa_FldLiteralN): Same.
(is_figconst): Const parameter.
(is_figconst_t): Same.
(parser_exit): Same.
(parser_division): Const pointer.
(parser_perform_conditional): Whitespace.
(parser_set_conditional88): Const parameter.
(inspect_tally): Use std::vector.
(inspect_replacing): Same.
(parser_inspect): Same.
(parser_intrinsic_subst): Use std::vector (constuct elements).
(parser_intrinsic_call_1): Use std::vector for subscripts.
(is_ascending_key): Const pointer.
(parser_sort): Use std::vector.
(parser_file_sort): Same.
(parser_file_merge): Same.
(parser_unstring): Same.
(parser_string): Same.
(parser_call): Const pointer.
(parser_program_hierarchy): Use std::vector.
(conditional_abs): Const paraemeter.
(float_type_of): Same.
(initial_from_initial): Set value, quoted or not.
(parser_symbol_add): Remove redundant nested test.
* genapi.h (parser_add): Const parameters.
(parser_subtract): Same.
(parser_multiply): Same.
(parser_divide): Same.
(parser_perform): Same.
(parser_exit): Same.
(parser_initialize): Same.
(parser_set_conditional88): Same.
(parser_sort): Same.
(parser_file_sort): Same.
(parser_file_merge): Same.
(parser_string): Same.
(is_ascending_key): Same.
* genmath.cc (arithmetic_operation): Use std::vector.
(is_somebody_float): Const parameter.
(all_results_binary): Const parameter.
(fast_multiply): Remove redundant nested test.
(parser_add): Const parameter.
(parser_multiply): Remove redundant nested test.
(parser_divide): Const parameter.
(parser_subtract): Same.
* genutil.cc (get_depending_on_value): Use std::vector.
(get_data_offset): Same.
(tree_type_from_field): Const parameter.
(refer_has_depends): Const pointers.
(get_literal_string): RAII.
(refer_is_clean): Use std::vector.
(get_time_nanoseconds): Newline at EOF.
* genutil.h (tree_type_from_field): Remove declaration.
* inspect.h (struct cbx_inspect_qual_t): Use std::vector.
(struct cbl_inspect_qual_t): Same.
(struct cbx_inspect_match_t): Same.
(class cbl_inspect_match_t): Same.
(struct cbx_inspect_replace_t): Same.
(struct cbl_inspect_replace_t): Same.
(struct cbx_inspect_oper_t): Same.
(struct cbl_inspect_oper_t): Same.
(struct cbx_inspect_t): Same.
(struct cbl_inspect_t): Same.
(parser_inspect): Same.
* lexio.cc (indicated): Const pointer.
(remove_inline_comment): Scope reduction.
(maybe_add_space): Const pointer.
(recognize_replacements): C++ cast.
(check_source_format_directive): Same.
(struct replacing_term_t): Explicit constructor.
(parse_replace_pairs): Const reference.
(location_in): Const reference.
(parse_copy_directive): C++ cast.
(parse_replace_last_off): Const parameter.
(parse_replace_text): Const reference.
(parse_replace_directive): C++ cast.
(cdftext::lex_open): Const reference.
(cdftext::open_output): Scope reduction.
(cdftext::free_form_reference_format): Remove unused variable.
(cdftext::process_file): Simplify.
* lexio.h (struct bytespan_t): Use nullptr.
(struct filespan_t): Initialize icol in constructor.
(struct span_t): Suppress confused operatorEqRetRefThis.
(struct replace_t): Eliminate single-value constructor.
* parse.y: Many const cppcheck reports, and portable bit-shift.
* parse_ante.h (reject_refmod): Const parameter.
(require_pointer): Same.
(require_integer): Same.
(struct evaluate_elem_t): Explicit constructor.
(struct arith_t): Use std::vector.
(class eval_subject_t): Const parameter.
(dump_inspect_match): Declare.
(struct perform_t): Explicit constructor.
(list_add):  Const parameter.
(class tokenset_t): Avoid negative array index.
(struct file_list_t): Explicit constructor.
(struct field_list_t): Same.
(struct refer_list_t): Same.
(struct refer_marked_list_t): Const parameter.
(struct refer_collection_t): Explicit constructor.
(struct ast_inspect_oper_t): Remove class.
(ast_inspect_oper_t): Same.
(struct ast_inspect_t): Same.
(struct ast_inspect_list_t): Same.
(ast_inspect): Add location.
(struct elem_list_t): Explicit constructor.
(struct unstring_tgt_t): Same.
(struct unstring_tgt_list_t): Same.
(struct unstring_into_t): Same.
(struct ffi_args_t): Same.
(struct file_sort_io_t): Same.
(merge_t): Same.
(struct vargs_t): Same.
(class prog_descr_t): Eliminate single-value constructor.
(class program_stack_t): Suppress useStlAlgorithm.
(struct rel_part_t): Eliminate single-value constructor.
(class log_expr_t): Explicit constructor.
(add_debugging_declarative): Rename local variable.
(intrinsic_call_2): Const parameter.
(invalid_key): Use std::find_if.
(parser_add2): Const parameter.
(parser_subtract2): Same.
(stringify): Same.
(unstringify): Same.
(anybody_redefines): Same.
(ast_call): Same.
* parse_util.h (class cname_cmp): Explicit constructor.
(intrinsic_inconsistent_parameter): Same.
* scan_ante.h (struct cdf_status_t): Eliminate single-value constructor.
(class enter_leave_t): Explicit constructor.
(update_location): Const pointer, explicit constructor.
(symbol_function_token): Const pointer.
(typed_name): Same.
* scan_post.h (datetime_format_of): Scope reduction.
* show_parse.h (class ANALYZE): Use std::vector, explicit consstructor.
* symbols.cc (symbol_table_extend): Scope reduction.
(cbl_ffi_arg_t::cbl_ffi_arg_t): Define default constructor.
(end_of_group): Const pointer.
(symbol_find_odo): Const parameter.
(rename_not_ok): Same.
(field_str): Use %u instead of %d.
(struct capacity_of): Const pointer.
(symbols_update): Same.
(symbol_field_parent_set): Same.
(symbol_file_add): Same.
(symbol_typedef_add): Same.
(symbol_field_add): Use new operator=().
(symbol_field): Suppress CastIntegerToAddressAtReturn.
(symbol_register): Same.
(symbol_file): Suppress knownConditionTrueFalse.
(next_program): Const parameter.
(symbol_file_record): Same.
(class is_section): Explicit constructor.
(cbl_file_t::no_key): Remove.
(cbl_prog_hier_t::cbl_prog_hier_t): Use std::vector.
(symbol_label_add): Assert pointer is not NULL.
(symbol_label_section_exists): Const reference in lambda.
(expand_picture): Use C++ cast.
(symbol_program_callables): Const pointer.
(symbol_currency_add): Suppress nullPointerRedundantCheck.
(cbl_key_t): Use std::vector.
(cbl_occurs_t::field_add): Const parameter.
(cbl_occurs_t::index_add): Explicit constructor.
(class is_field_at): Same.
(cbl_file_key_t::deforward): Scope reduction.
(cbl_file_t::keys_str): Use allocated memory only.
(file_status_status_of): Const pointer.
(is_register_field): Const parameter.
* symbols.h (struct cbl_field_data_t): Eliminate single-value constructor.
(struct cbl_occurs_bounds_t): Same.
(struct cbl_refer_t): Use std::vector.
(valid_move): Const parameter.
(is_register_field): Same.
(struct cbl_key_t): Use std::vector.
(struct cbl_substitute_t): Eliminate single-value constructor.
(refer_of): Return const reference
(struct cbl_ffi_arg_t): Eliminate single-value constructor.
(class temporaries_t): Same.
(struct cbl_file_key_t): Define default constructor.
(struct cbl_file_lock_t): Define copy constructor and operator=().
(struct cbl_file_t): Complete default constructor.
(struct symbol_elem_t): Explicit constructor.
(symbol_elem_of): Suppress cstyleCast.
(symbol_redefines): Const parameter.
(struct cbl_field_t): Same.
(cbl_section_of): Test for NULL pointer.
(cbl_field_of): Same.
(cbl_label_of): Same.
(cbl_special_name_of): Same.
(cbl_alphabet_of): Same.
(cbl_file_of): Same.
(is_figconst): Delete extra "struct" keyword.
(is_figconst_low): Same.
(is_figconst_zero): Same.
(is_figconst_space): Same.
(is_figconst_quote): Same.
(is_figconst_high): Same.
(is_space_value): Same.
(is_quoted): Same.
(symbol_index): Const parameter.
(struct cbl_prog_hier_t): Suppress noExplicitConstructor.
(struct cbl_perform_vary_t): Eliminate single-value constructor.
(is_signable): Const parameter.
(is_temporary): Same.
(rename_not_ok): Same.
(field_at): Test for NULL pointer.
(class procref_base_t): Eliminate single-value constructor.
* symfind.cc (is_data_field): Const pointer.
(finalize_symbol_map2): Same.
(class in_scope): Same.
(symbol_match2): Same.
* token_names.h: Suppress useInitializationList.
* util.cc (normalize_picture): Whitespace and remove extra "continue".
(redefine_field): Const pointer.
(cbl_field_t::report_invalid_initial_value): Same.
(literal_subscript_oob): Rename shadow variable.
(cbl_refer_t::subscripts_set): Use std::vector.
(cbl_refer_t::str): Same.
(cbl_refer_t::deref_str): Same.
(locally_unique): Use explicit constructor.
(ambiguous_reference): Same.
(class unique_stack): Use const reference.
(cobol_filename): Const pointer.
(verify_format): Scope reduction.
(class temp_loc_t): Do not derive from YYLTYPE.
(cobol_parse_files): Const pointer.
* util.h (as_voidp): Define convenient converter.

libgcobol/ChangeLog:

* common-defs.h (class cbl_enabled_exceptions_t): Const parameter.

30 files changed:
gcc/cobol/Make-lang.in
gcc/cobol/cbldiag.h
gcc/cobol/cdf-copy.cc
gcc/cobol/cdf.y
gcc/cobol/cdfval.h
gcc/cobol/cobol1.cc
gcc/cobol/copybook.h
gcc/cobol/dts.h
gcc/cobol/except.cc
gcc/cobol/genapi.cc
gcc/cobol/genapi.h
gcc/cobol/genmath.cc
gcc/cobol/genutil.cc
gcc/cobol/genutil.h
gcc/cobol/inspect.h
gcc/cobol/lexio.cc
gcc/cobol/lexio.h
gcc/cobol/parse.y
gcc/cobol/parse_ante.h
gcc/cobol/parse_util.h
gcc/cobol/scan_ante.h
gcc/cobol/scan_post.h
gcc/cobol/show_parse.h
gcc/cobol/symbols.cc
gcc/cobol/symbols.h
gcc/cobol/symfind.cc
gcc/cobol/token_names.h
gcc/cobol/util.cc
gcc/cobol/util.h
libgcobol/common-defs.h

index 5f293e1f9874a440c5067f0e995bc6c693e13c4e..bec81a6acc0092ef2181e3e806c3c24d65d70a02 100644 (file)
@@ -34,6 +34,9 @@
 # - the compiler proper (eg: cc1plus)
 # - define the names for selecting the language in LANGUAGES.
 
+# Use strict warnings for this front end.
+cobol-warn = $(STRICT_WARN)
+
 GCOBOL_INSTALL_NAME := $(shell echo gcobol|sed '$(program_transform_name)')
 GCOBOLIO_INSTALL_NAME := $(shell echo gcobol-io|sed '$(program_transform_name)')
 GCOBOL_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcobol|sed '$(program_transform_name)')
index 2d2ff4c05f9120122e7308afd0b0005c20fea432..6b371eb08174d0cf87c468cd4948e069345a34bb 100644 (file)
@@ -106,7 +106,7 @@ void gcc_location_set( const YYLTYPE& loc );
 template <typename LOC>
 static void
 location_dump( const char func[], int line, const char tag[], const LOC& loc) {
-  extern int yy_flex_debug;
+  extern int yy_flex_debug; // cppcheck-suppress shadowVariable
   if( yy_flex_debug && gcobol_getenv("update_location") )
     fprintf(stderr, "%s:%d: %s location (%d,%d) to (%d,%d)\n",
             func, line, tag,
index 3f5ae30a61c361c586304fdbc09c5a1c2cce9c2b..f45c4669372df6548f9ed5aa7b38e79481ddfec9 100644 (file)
@@ -124,13 +124,13 @@ verify_bounds( size_t pos, size_t size, const char input[] ) {
  */
 const char *
 esc( size_t len, const char input[] ) {
-  static char spaces[] = "([,;]?[[:space:]])+";
-  static char spaceD[] = "(\n {6}D" "|" "[,;]?[[:space:]])+";
+  static const char space[]  = "([,;]?[[:space:]])+";
+  static const char spaceD[] = "(\n {6}D" "|" "[,;]?[[:space:]])+";
   static char buffer[64 * 1024];
   char *p = buffer;
   const char *eoinput = input + len;
 
-  const char *spacex = is_reference_format()? spaceD : spaces;
+  const char *spacex = is_reference_format()? spaceD : space;
 
   for( const char *s=input; *s && s < eoinput; s++ ) {
     *p = '\0';
@@ -279,7 +279,7 @@ 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: %m", path);
+      dbgmsg("could not open %s: %s", path, xstrerror(errno));
       return fd;
     }
     this->source.name = path;
index e4d2feaaf52eb266f322497bdf9fbfc80fdd13eb..7e7d226b53f117ca15134e83aa66f81a05c1426c 100644 (file)
@@ -185,6 +185,7 @@ apply_cdf_turn( const exception_turn_t& turn ) {
 %printer { fprintf(yyo, "%s '%s'",
                   keyword_str($$.token),
                   $$.string? $$.string : "<nil>" ); } <cdfarg>
+/* cppcheck-suppress invalidPrintfArgType_sint */
 %printer { fprintf(yyo, HOST_SIZE_T_PRINT_DEC " '%s'",
                   (fmt_size_t)$$.number, $$.string? $$.string : "" ); } <cdfval>
 
@@ -891,9 +892,9 @@ verify_integer( const YDFLTYPE& loc, const cdfval_base_t& val ) {
   return true;
 }
 
-// cppcheck-suppress returnTempReference
 const cdfval_base_t&
 cdfval_base_t::operator()( const YDFLTYPE& loc ) {
   static cdfval_t zero(0);
+  // cppcheck-suppress returnTempReference
   return verify_integer(loc, *this) ? *this : zero;
 }
index c4387b08066161324763b4a101fd76da270d3db9..465bdbb4d1a9ad1896bbac2f4c257cdacf957f64 100644 (file)
@@ -73,28 +73,28 @@ struct cdfval_t : public cdfval_base_t {
     cdfval_base_t::string = NULL;
     cdfval_base_t::number = 0;
   }
-  cdfval_t( const char value[] )
+  cdfval_t( const char value[] ) // cppcheck-suppress noExplicitConstructor
     : lineno(yylineno), filename(cobol_filename())
   {
     cdfval_base_t::off  = false;
     cdfval_base_t::string = value;
     cdfval_base_t::number = 0;
   }
-  cdfval_t( long long value )
+  cdfval_t( long long value ) // cppcheck-suppress noExplicitConstructor
     : lineno(yylineno), filename(cobol_filename())
   {
     cdfval_base_t::off  = false;
     cdfval_base_t::string = NULL;
     cdfval_base_t::number = value;
   }
-  cdfval_t( long value )
+  cdfval_t( long value ) // cppcheck-suppress noExplicitConstructor
     : lineno(yylineno), filename(cobol_filename())
   {
     cdfval_base_t::off  = false;
     cdfval_base_t::string = NULL;
     cdfval_base_t::number = value;
   }
-  cdfval_t( int value )
+  cdfval_t( int value ) // cppcheck-suppress noExplicitConstructor
     : lineno(yylineno), filename(cobol_filename())
   {
     cdfval_base_t::off  = false;
@@ -109,7 +109,7 @@ struct cdfval_t : public cdfval_base_t {
     HOST_WIDE_INT value = real_to_integer(&r);
     cdfval_base_t::number = value;
   }
-  cdfval_t( const cdfval_base_t& value )
+  cdfval_t( const cdfval_base_t& value ) // cppcheck-suppress noExplicitConstructor
     : lineno(yylineno), filename(cobol_filename())
   {
     cdfval_base_t *self(this);
index 63f2b37816d1a29e58fea9f32fc49adf40518163..4bd79f1f605732f2acc453edad317dda24ea04ad 100644 (file)
@@ -571,7 +571,7 @@ cobol_name_mangler(const char *cobol_name_)
       }
 
     // Allocate enough space for a prepended underscore and a final '\0'
-    char *cobol_name = (char *)xmalloc(strlen(cobol_name_)+2);
+    char *cobol_name = static_cast<char *>(xmalloc(strlen(cobol_name_)+2));
     size_t n = 0;
     if( cobol_name_[0] >= '0' && cobol_name_[0] <= '9' )
       {
index fa91fe5660033cdda6c63ecdec6465c4790dd949..ff8c6d0ca27618872ae98b7dc0ad9ed62ec0f894 100644 (file)
@@ -100,7 +100,7 @@ class copybook_elem_t {
   }
   static char * dequote( const char orig[] ) {
     gcc_assert(quoted(orig));
-    auto name = (char*)xcalloc(1, strlen(orig));
+    auto name = static_cast<char*>(xcalloc(1, strlen(orig)));
     gcc_assert(name);
     char *tgt = name;
 
index dfd7c4c24f71bbdfe1476c63b993ddb0778aae87..aa3fa5850969714b526c571708a55f878efcaeeb 100644 (file)
@@ -35,13 +35,13 @@ namespace dts {
     {
       static regmatch_t empty;
       empty.rm_so = empty.rm_eo = -1;
-      regmatch_t& self(*this);
+      regmatch_t& self(*this); // cppcheck-suppress constVariableReference
       self = empty;
     }
     csub_match( const char input[], const regmatch_t& m )
       : input(input)
     {
-      regmatch_t& self(*this);
+      regmatch_t& self(*this); // cppcheck-suppress constVariableReference
       self = m;
       matched = rm_so != -1;
       first =   rm_so == -1? NULL : input + rm_so;
@@ -68,7 +68,6 @@ namespace dts {
 #if __cpp_exceptions
         throw std::logic_error(msg);
 #else
-        pattern = NULL;
         cbl_errx("%s", msg);
 #endif
       }
@@ -78,7 +77,7 @@ namespace dts {
     size_t size() const { return nsubexpr; }
     bool ready() const { return pattern != NULL; }
   private:
-    regex( const regex& ) {}
+    regex( const regex& ) = default;
   };
 
   inline bool regex_search( const char input[], const char *eoinput,
@@ -88,10 +87,10 @@ namespace dts {
       static const char msg[] = "input not NUL-terminated";
       throw std::domain_error( msg );
 #else
-      eoinput = strchr(input, '\0');
+      // eoinput terminates input
+      eoinput = strchr(input, '\0'); // cppcheck-suppress uselessAssignmentPtrArg
 #endif
     }
-    if( eoinput == NULL ) eoinput = strchr(input, '\0');
     auto ncm = re.size();
     cm.resize(ncm);
     std::vector <regmatch_t> cms(ncm);
index d2bc24a6cff92c647193379445a0b1a7337244b5..e50fa618f4a8402235db42a21b3121bc14b39eb1 100644 (file)
@@ -108,14 +108,16 @@ cbl_enabled_exceptions_t::dump() const {
   std::swap(debug, yydebug);
 }
 
+// cppcheck-suppress-begin [useStlAlgorithm] because why?
 uint32_t 
 cbl_enabled_exceptions_t::status() const {
   uint32_t status_word = 0;
   for( const auto& ena : *this ) {
     status_word |= (EC_ALL_E & ena.ec );
-  }
+  } 
   return status_word;
 }
+// cppcheck-suppress-end useStlAlgorithm
 
 std::vector<uint64_t>
 cbl_enabled_exceptions_t::encode() const {
@@ -133,13 +135,13 @@ void
 cbl_enabled_exceptions_t::turn_on_off( bool enabled,
                                        bool location,
                                        ec_type_t type,
-                                       std::set<size_t> files )
+                                       const std::set<size_t>& files )
 {
   // Update current enabled ECs tree on leaving this function. 
   class update_parser_t {
     const cbl_enabled_exceptions_t& ecs;
   public:
-    update_parser_t(const cbl_enabled_exceptions_t& ecs) : ecs(ecs) {}
+    explicit update_parser_t(const cbl_enabled_exceptions_t& ecs) : ecs(ecs) {}
     ~update_parser_t() {
       tree ena = parser_compile_ecs(ecs.encode());
       current_enabled_ecs(ena);
@@ -244,16 +246,6 @@ cbl_enabled_exceptions_t::match( ec_type_t type, size_t file ) const {
   return output != end()? &*output : NULL;
 }
 
-class choose_declarative {
-  size_t program;
- public:
-  choose_declarative( size_t program ) : program(program) {}
-
-  bool operator()( const cbl_declarative_t& dcl ) {
-    return dcl.global || program == symbol_at(dcl.section)->program;
-  }
-};
-
 bool
 sort_supers_last( const cbl_declarative_t& a, const cbl_declarative_t& b ) {
   if( symbol_at(a.section)->program == symbol_at(b.section)->program ) {
index 595aa61e25e81e7dcbfa1f241e7f2593051b3d8a..f2a5d0ea438774cd0fdb83071edfbf27f71e09c7 100644 (file)
@@ -694,7 +694,7 @@ struct called_tree_t {
     tree node;
 
    public:
-    match_tree( tree node ) : node(node) {}
+    explicit match_tree( tree node ) : node(node) {}
     bool operator()( const called_tree_t& that ) const {
       return this->node == that.node;
     }
@@ -957,7 +957,8 @@ parser_compile_ecs( const std::vector<uint64_t>& ecs )
     {
     SHOW_PARSE_HEADER
     char ach[64];
-    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", ecs.size(), retval);
+    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p",
+             ecs.size(), as_voidp(retval));
     SHOW_PARSE_TEXT(ach)
     SHOW_PARSE_END
     }
@@ -965,7 +966,8 @@ parser_compile_ecs( const std::vector<uint64_t>& ecs )
     {
     TRACE1_HEADER
     char ach[64];
-    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", ecs.size(), retval);
+    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p",
+             ecs.size(), as_voidp(retval));
     TRACE1_TEXT_ABC("", ach, "");
     TRACE1_END
     }
@@ -1004,7 +1006,8 @@ parser_compile_dcls( const std::vector<uint64_t>& dcls )
     {
     SHOW_PARSE_HEADER
     char ach[64];
-    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", dcls.size(), retval);
+    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p",
+             dcls.size(), as_voidp(retval));
     SHOW_PARSE_TEXT(ach);
     SHOW_PARSE_END
     }
@@ -1012,7 +1015,8 @@ parser_compile_dcls( const std::vector<uint64_t>& dcls )
     {
     TRACE1_HEADER
     char ach[64];
-    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p", dcls.size(), retval);
+    snprintf(ach, sizeof(ach), " Size is %ld; retval is %p",
+             dcls.size(), as_voidp(retval));
     TRACE1_TEXT_ABC("", ach, "");
     TRACE1_END
     }
@@ -1091,7 +1095,7 @@ parser_statement_begin( const cbl_name_t statement_name,
       {
       SHOW_PARSE_INDENT
       snprintf( ach, sizeof(ach),
-                "Sending ecs/dcls %p / %p", ecs, dcls);
+                "Sending ecs/dcls %p / %p", as_voidp(ecs), as_voidp(dcls));
       SHOW_PARSE_TEXT(ach);
       }
     SHOW_PARSE_END
@@ -1100,7 +1104,7 @@ parser_statement_begin( const cbl_name_t statement_name,
     {
     TRACE1_HEADER
     char ach[64];
-    snprintf(ach, sizeof(ach), " ecs/dcls %p / %p", ecs, dcls);
+    snprintf(ach, sizeof(ach), " ecs/dcls %p / %p", as_voidp(ecs), as_voidp(dcls));
     TRACE1_TEXT_ABC("", ach, "");
     TRACE1_END
     }
@@ -1315,7 +1319,7 @@ initialize_variable_internal( cbl_refer_t refer,
 
   bool is_redefined = false;
 
-  cbl_field_t *family_tree = parsed_var;
+  const cbl_field_t *family_tree = parsed_var;
   while(family_tree)
     {
     if( symbol_redefines(family_tree) )
@@ -1336,7 +1340,7 @@ initialize_variable_internal( cbl_refer_t refer,
   if( parsed_var->data.initial )
     {
     bool a_parent_initialized = false;
-    cbl_field_t *parent = parent_of(parsed_var);
+    const cbl_field_t *parent = parent_of(parsed_var);
     while( parent )
       {
       if( parent->attr & has_value_e )
@@ -1366,7 +1370,7 @@ initialize_variable_internal( cbl_refer_t refer,
   flag_bits     |=  wsclear()
                     ? DEFAULTBYTE_BIT + (*wsclear() & DEFAULT_BYTE_MASK)
                     : 0;
-  flag_bits     |= (refer.nsubscript << NSUBSCRIPT_SHIFT) & NSUBSCRIPT_MASK;
+  flag_bits     |= (refer.nsubscript() << NSUBSCRIPT_SHIFT) & NSUBSCRIPT_MASK;
   flag_bits     |= just_once ? JUST_ONCE_BIT : 0 ;
 
   suppress_dest_depends = false;  // Set this to false so that refer_is_clean is valid
@@ -1531,7 +1535,7 @@ initialize_variable_internal( cbl_refer_t refer,
 //  }
 
 void
-parser_initialize(cbl_refer_t refer, bool like_parser_symbol_add)
+parser_initialize(const cbl_refer_t& refer, bool like_parser_symbol_add)
   {
   //gg_printf("parser_initialize %s\n", gg_string_literal(refer.field->name), NULL_TREE);
   if( like_parser_symbol_add )
@@ -2475,7 +2479,7 @@ get_string_from(cbl_field_t *field)
                   gg_cast(CHAR_P,
                           gg_malloc(build_int_cst_type(SIZE_T,
                                                      field->data.capacity+1))));
-        char *litstring = get_literal_string(field);
+        const char *litstring = get_literal_string(field);
         gg_memcpy(psz,
                   gg_string_literal(litstring),
                   build_int_cst_type(SIZE_T, field->data.capacity+1));
@@ -2527,8 +2531,8 @@ combined_name(cbl_label_t *label)
   {
   // This routine returns a pointer to a static, so make sure you use the result
   // before calling the routine again
-  char *para_name     = nullptr;
-  char *sect_name     = nullptr;
+  const char *para_name     = nullptr;
+  const char *sect_name     = nullptr;
   const char *program_name  = current_function->our_unmangled_name;
 
   if( label->type == LblParagraph )
@@ -2551,7 +2555,7 @@ combined_name(cbl_label_t *label)
   static char *retval= (char *)xmalloc(retval_size);
 
   char *paragraph             = cobol_name_mangler(para_name);
-  char *section               = cobol_name_mangler(sect_name);
+  char *section         = cobol_name_mangler(sect_name);
   char *mangled_program_name  = cobol_name_mangler(program_name);
 
   while( retval_size < (paragraph ? strlen(paragraph) : 0 )
@@ -3267,8 +3271,8 @@ parser_perform(cbl_label_t *label, bool suppress_nexting)
   // pairs were created, the locations of the goto instruction and the label
   // were not known.
 
-  char *para_name     = nullptr;
-  char *sect_name     = nullptr;
+  const char *para_name     = nullptr;
+  const char *sect_name     = nullptr;
   const char *program_name  = current_function->our_unmangled_name;
   size_t deconflictor = symbol_label_id(label);
 
@@ -4095,7 +4099,7 @@ psa_FldLiteralN(struct cbl_field_t *field )
     int rdigit_delta = 0;
     int exponent = 0;
 
-    char *exp = strchr(p, 'E');
+    const char *exp = strchr(p, 'E');
     if( !exp )
       {
       exp = strchr(p, 'e');
@@ -5659,16 +5663,16 @@ parser_assign( size_t nC, cbl_num_result_t *C,
   }
 
 static cbl_figconst_t
-is_figconst(cbl_field_t *field)
+is_figconst_t(const cbl_field_t *field)
   {
   cbl_figconst_t figconst = (cbl_figconst_t)(field->attr & FIGCONST_MASK);
   return figconst;
   }
 
 static cbl_figconst_t
-is_figconst(cbl_refer_t &sourceref)
+is_figconst(const cbl_refer_t &sourceref)
   {
-  return is_figconst(sourceref.field);
+  return is_figconst_t(sourceref.field);
   }
 
 void
@@ -6213,7 +6217,7 @@ pe_stuff(cbl_refer_t refer, ec_type_t ec)
   }
 
 void
-parser_exit( cbl_refer_t refer, ec_type_t ec )
+parser_exit( const cbl_refer_t& refer, ec_type_t ec )
   {
   Analyze();
   SHOW_PARSE
@@ -6777,7 +6781,7 @@ parser_division(cbl_division_t division,
       // gg_printf("Somebody wants to cancel %s\n",
                 // gg_string_literal(current_function->our_unmangled_name),
                 // NULL_TREE);
-      cbl_label_t *prog = cbl_label_of(symbol_at(current_program_index()));
+      const cbl_label_t *prog = cbl_label_of(symbol_at(current_program_index()));
       size_t initializer_index = prog->initial_section;
       cbl_label_t *initializer = cbl_label_of(symbol_at(initializer_index));
       parser_perform(initializer, true);  // true means suppress nexting
@@ -7770,9 +7774,9 @@ parser_classify(    cbl_field_t *tgt,
   }
 
 void
-parser_perform(struct cbl_perform_tgt_t *tgt, struct cbl_refer_t how_many)
+parser_perform(const cbl_perform_tgt_t *tgt, cbl_refer_t how_many)
   {
-  cbl_field_t *N = how_many.field;
+  const cbl_field_t *N = how_many.field;
   // No SHOW_PARSE here; we want to fall through:
   if( !tgt->to() )
     {
@@ -7914,8 +7918,8 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt )
   if( !(i < MAXIMUM_UNTILS) )
     {
     cbl_internal_error("%s:%d: %u exceeds MAXIMUM_UNTILS of %d, line %d",
-                      __func__, __LINE__,
-                      i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER);
+                       __func__, __LINE__,
+                       i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER);
     }
   gcc_assert(i < MAXIMUM_UNTILS);
 
@@ -9035,7 +9039,7 @@ parser_perform_inline_times(struct cbl_perform_tgt_t *tgt,
   }
 
 void
-parser_set_conditional88( struct cbl_refer_t refer, bool which_way )
+parser_set_conditional88( const cbl_refer_t& refer, bool which_way )
   {
   Analyze();
   struct cbl_field_t *tgt = refer.field;
@@ -9917,14 +9921,51 @@ parser_file_start(struct cbl_file_t *file,
 static void
 inspect_tally(bool backward,
               cbl_refer_t identifier_1,
-              unsigned long n_identifier_2,
-              cbx_inspect_t<cbl_refer_t>* identifier_2)
+              cbl_inspect_opers_t& identifier_2)
   {
   Analyze();
   // This is an INSPECT FORMAT 1
   SHOW_PARSE
     {
     SHOW_PARSE_HEADER
+    char ach[128];
+    sprintf(ach, "There are %lu identifier_2", identifier_2.size());
+    SHOW_PARSE_TEXT(ach);
+    for(size_t i=0; i<identifier_2.size(); i++)
+      {
+      SHOW_PARSE_INDENT
+      sprintf(ach, "%lu: bounds: %lu", i, identifier_2[i].nbound());
+      SHOW_PARSE_TEXT(ach);
+      for(size_t j=0; j<identifier_2[i].nbound(); j++)
+        {
+        SHOW_PARSE_INDENT
+        sprintf(ach, "    %lu: matches: %lu", j, identifier_2[i][j].matches.size());
+        SHOW_PARSE_TEXT(ach);
+
+        SHOW_PARSE_INDENT
+        if(  identifier_2[i][j].bound == bound_characters_e )
+          {
+          SHOW_PARSE_TEXT("       bound_characters");
+          }
+        else
+          {
+          SHOW_PARSE_TEXT("       bound_leading/all");
+          }
+
+        if( identifier_2[i][j].matches.size() )
+          {
+          SHOW_PARSE_INDENT
+          sprintf(ach, "       before %p",
+                  as_voidp(identifier_2.at(i).at(j).matches.at(0).before.identifier_4.field));
+          SHOW_PARSE_TEXT(ach);
+          SHOW_PARSE_INDENT
+          sprintf(ach, "       after  %p",
+                  as_voidp(identifier_2.at(i).at(j).matches.at(0).after.identifier_4.field));
+          SHOW_PARSE_TEXT(ach);
+          }
+        }
+      }
+
     SHOW_PARSE_END
     }
 
@@ -9934,6 +9975,7 @@ inspect_tally(bool backward,
 
   size_t int_index  = 0;
   size_t pcbl_index = 0;
+  unsigned long n_identifier_2 = identifier_2.size();
 
   // The first integer is the all-important controlling count:
   int_index++;
@@ -9947,12 +9989,11 @@ inspect_tally(bool backward,
     pcbl_index++;
     // For each FOR there is a count of the loops after the FOR
     int_index++;
-    for(size_t j=0; j<identifier_2[i].nbound; j++)
+    for(size_t j=0; j<identifier_2[i].nbound(); j++)
       {
-
       // After each identifier-2, there is a cbl_inspect_bound_t value:
       int_index++;
-      if( identifier_2[i].opers[j].bound == bound_characters_e)
+      if( identifier_2[i][j].bound == bound_characters_e)
         {
         // This is a FOR CHARACTERS PHRASE1, so we will need before/after
         // for each:
@@ -9963,7 +10004,7 @@ inspect_tally(bool backward,
         {
         // This is ALL or LEADING.  Each has some number of identifier-3
         int_index++;
-        for(size_t k=0; k<identifier_2[i].opers[j].n_identifier_3; k++)
+        for(size_t k=0; k<identifier_2[i][j].n_identifier_3(); k++)
           {
           // Put identifier-3 into the array:
           pcbl_index++;
@@ -9999,8 +10040,8 @@ inspect_tally(bool backward,
     }
   ENDIF
 
-  size_t n_resolveds = pcbl_index;
-  cbl_refer_t *pcbl_refers = (cbl_refer_t *)xmalloc(n_resolveds * sizeof(cbl_refer_t));
+  const size_t n_resolveds = pcbl_index;
+  std::vector<cbl_refer_t> pcbl_refers(n_resolveds);
 
   // Now we make a second pass, populating those arrays:
   int_index  = 0;
@@ -10019,34 +10060,42 @@ inspect_tally(bool backward,
     pcbl_refers[pcbl_index++] = identifier_2[i].tally;
     // For each FOR there is a count of the loops after the FOR
     gg_assign(  gg_array_value(integers, int_index++),
-                build_int_cst_type(SIZE_T, identifier_2[i].nbound) );
-    for(size_t j=0; j<identifier_2[i].nbound; j++)
+                build_int_cst_type(SIZE_T, identifier_2[i].nbound()) );
+    for(size_t j=0; j<identifier_2[i].nbound(); j++)
       {
 
       // After each identifier-2, there is a cbl_inspect_bound_t value:
       gg_assign(  gg_array_value(integers, int_index++),
-                  build_int_cst_type(SIZE_T, identifier_2[i].opers[j].bound));
-      if( identifier_2[i].opers[j].bound == bound_characters_e)
+                  build_int_cst_type(SIZE_T, identifier_2[i][j].bound));
+      if( identifier_2[i][j].bound == bound_characters_e)
         {
         // This is a FOR CHARACTERS PHRASE1, so we will need before/after
         // for each:
-        pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[0].before.identifier_4;
-        pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[0].after.identifier_4;
+        const auto& m( identifier_2[i][j].matches );
+        if( m.empty() )
+          {
+            pcbl_index += 2;
+          }
+        else
+          {
+          pcbl_refers[pcbl_index++] = m[0].before.identifier_4;
+          pcbl_refers[pcbl_index++] = m[0].after.identifier_4;
+          }
         }
       else
         {
         // This is ALL or LEADING.  Each has some number of identifier-3
         gg_assign(  gg_array_value(integers, int_index++),
-                    build_int_cst_type(SIZE_T, identifier_2[i].opers[j].n_identifier_3));
-        for(size_t k=0; k<identifier_2[i].opers[j].n_identifier_3; k++)
+                    build_int_cst_type(SIZE_T, identifier_2[i][j].n_identifier_3()));
+        for(size_t k=0; k<identifier_2[i][j].n_identifier_3(); k++)
           {
           // Put identifier-3 into the array:
-          pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[k].matching;
+          pcbl_refers[pcbl_index++] = identifier_2[i][j].matches[k].matching();
 
           // We need the PHRASE1 for that identifier-3
-          pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[k].before.identifier_4;
+          pcbl_refers[pcbl_index++] = identifier_2[i][j].matches[k].before.identifier_4;
 
-          pcbl_refers[pcbl_index++] = identifier_2[i].opers[j].matches[k].after.identifier_4;
+          pcbl_refers[pcbl_index++] = identifier_2[i][j].matches[k].after.identifier_4;
           }
         }
       }
@@ -10058,7 +10107,7 @@ inspect_tally(bool backward,
   gcc_assert(pcbl_index == n_resolveds);
 
   // We have built up an array of integers, and an array of cbl_refer_t.
-  build_array_of_treeplets(1, pcbl_index, pcbl_refers);
+  build_array_of_treeplets(1, pcbl_index, pcbl_refers.data());
 
   // Do the actual call:
   gg_call(VOID,
@@ -10066,16 +10115,12 @@ inspect_tally(bool backward,
           backward ? integer_one_node : integer_zero_node,
           integers,
           NULL_TREE);
-
-  // And free up the memory we allocated
-  free(pcbl_refers);
   }
 
 static void
 inspect_replacing(int backward,
                   cbl_refer_t identifier_1,
-                  unsigned long n_ops,
-                  cbx_inspect_t<cbl_refer_t>* operations)
+                  cbl_inspect_opers_t& operations)
   {
   Analyze();
   // This is an INSPECT FORMAT 2
@@ -10086,6 +10131,7 @@ inspect_replacing(int backward,
     }
 
   // For REPLACING, unlike TALLY, there can be but one operation
+  unsigned long n_ops = operations.size();
   gcc_assert(n_ops == 1);
 
   size_t n_id_3 = 0;
@@ -10096,9 +10142,9 @@ inspect_replacing(int backward,
   // Make one pass through the inputs to count up the sizes of the arrays
   // we will be passing to the library routines:
 
-  for( size_t j=0; j<operations[0].nbound; j++)
+  for( size_t j=0; j<operations[0].nbound(); j++)
     {
-    if( operations[0].opers[j].bound == bound_characters_e)
+    if( operations[0][j].bound == bound_characters_e)
       {
       // This is a FOR CHARACTERS phrase
 
@@ -10117,13 +10163,13 @@ inspect_replacing(int backward,
 
       // The n_identifier-3 values will go into the resolved values; we have to
       // leave room for them
-      n_id_3 += operations[0].opers[j].n_identifier_3;
+      n_id_3 += operations[0][j].n_identifier_3();
 
       // Likewise identifier-5 values:
-      n_id_5 += operations[0].opers[j].n_identifier_3;
+      n_id_5 += operations[0][j].n_identifier_3();
 
       // And each identifier-3 / identifier-5 pair has BEFORE and AFTER phrases:
-      n_id_4 += 2 * operations[0].opers[j].n_identifier_3;
+      n_id_4 += 2 * operations[0][j].n_identifier_3();
       }
     }
 
@@ -10131,8 +10177,8 @@ inspect_replacing(int backward,
   // all the integers and cbl_inspect_bound_t values, in a strict sequence so
   // that the library routine can peel them off.
 
-  size_t n_integers =   1                     // Room for operations[0].nbound
-                        + operations[0].nbound  // Room for all the cbl_inspect_bound_t values
+  size_t n_integers =   1                     // Room for operations[0].nbound()
+                        + operations[0].nbound()  // Room for all the cbl_inspect_bound_t values
                         + n_all_leading_first;  // Room for all of the n_identifier_3 counts
 
   static tree int_size = gg_define_variable(INT,      "..pir_size", vs_file_static, 0);
@@ -10152,12 +10198,12 @@ inspect_replacing(int backward,
     }
   ENDIF
 
-  size_t n_resolveds =      1                 // Room for identifier-1
+  const size_t n_resolveds =  1                 // Room for identifier-1
                             + n_id_3            // Room for the identifier-3 variables
                             + n_id_4            // Room for the identifier-4 variables
                             + n_id_5;           // Room for the identifier-5 variables
 
-  cbl_refer_t *pcbl_refers = (cbl_refer_t *)xmalloc(n_resolveds * sizeof(cbl_refer_t));
+  std::vector<cbl_refer_t> pcbl_refers(n_resolveds);
 
   // Now we make a second pass, populating those arrays:
   size_t int_index  = 0;
@@ -10165,28 +10211,28 @@ inspect_replacing(int backward,
 
   // The first integer is the all-important controlling count:
   gg_assign(  gg_array_value(integers, int_index++),
-              build_int_cst_type(SIZE_T, operations[0].nbound) );
+              build_int_cst_type(SIZE_T, operations[0].nbound()) );
 
   // The first refer is for identifier-1
   pcbl_refers[pcbl_index++] = identifier_1;
 
-  for( size_t j=0; j<operations[0].nbound; j++)
+  for( size_t j=0; j<operations[0].nbound(); j++)
     {
     // For each FOR there is a count of the loops after the FOR
 
     // For each operation, there is a cbl_inspect_bound_t value:
     gg_assign(  gg_array_value(integers, int_index++),
-                build_int_cst_type(SIZE_T, operations[0].opers[j].bound));
-    if( operations[0].opers[j].bound == bound_characters_e)
+                build_int_cst_type(SIZE_T, operations[0][j].bound));
+    if( operations[0][j].bound == bound_characters_e)
       {
       // This is a FOR CHARACTERS PHRASE1
 
       // Put in the identifier-5 replacement value:
-      pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[0].replacement;
+      pcbl_refers[pcbl_index++] = operations[0][j].replaces[0].replacement;
 
       // Each identifier-5 gets a PHRASE1:
-      pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[0].before.identifier_4;
-      pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[0].after.identifier_4;
+      pcbl_refers[pcbl_index++] = operations[0][j].replaces[0].before.identifier_4;
+      pcbl_refers[pcbl_index++] = operations[0][j].replaces[0].after.identifier_4;
 
       SHOW_PARSE
         {
@@ -10194,14 +10240,14 @@ inspect_replacing(int backward,
           {
           SHOW_PARSE_INDENT
           }
-        SHOW_PARSE_FIELD("ID-5 ", operations[0].opers[j].replaces[0].replacement.field)
-        if(operations[0].opers[j].replaces[0].before.identifier_4.field)
+        SHOW_PARSE_FIELD("ID-5 ", operations[0][j].replaces[0].replacement.field)
+        if(operations[0][j].replaces[0].before.identifier_4.field)
           {
-          SHOW_PARSE_FIELD(" before ", operations[0].opers[j].replaces[0].before.identifier_4.field)
+          SHOW_PARSE_FIELD(" before ", operations[0][j].replaces[0].before.identifier_4.field)
           }
-        if(operations[0].opers[j].replaces[0].after.identifier_4.field)
+        if(operations[0][j].replaces[0].after.identifier_4.field)
           {
-          SHOW_PARSE_FIELD(" after ", operations[0].opers[j].replaces[0].after.identifier_4.field)
+          SHOW_PARSE_FIELD(" after ", operations[0][j].replaces[0].after.identifier_4.field)
           }
         SHOW_PARSE_END
         }
@@ -10210,19 +10256,19 @@ inspect_replacing(int backward,
       {
       // This is ALL or LEADING.  Each has some number of identifier-3/identifier-5 pairs
       gg_assign(  gg_array_value(integers, int_index++),
-                  build_int_cst_type(SIZE_T, operations[0].opers[j].n_identifier_3));
-      for(size_t k=0; k<operations[0].opers[j].n_identifier_3; k++)
+                  build_int_cst_type(SIZE_T, operations[0][j].n_identifier_3()));
+      for(size_t k=0; k<operations[0][j].n_identifier_3(); k++)
         {
         // Put identifier-3 into the array:
-        pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].matching;
+        pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].matching();
 
         // Put in the identifier-5 replacement value:
-        pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].replacement;
+        pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].replacement;
 
         // We need the PHRASE1 for that identifier-3/identifier-5 pair:
-        pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].before.identifier_4;
+        pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].before.identifier_4;
 
-        pcbl_refers[pcbl_index++] = operations[0].opers[j].replaces[k].after.identifier_4;
+        pcbl_refers[pcbl_index++] = operations[0][j].replaces[k].after.identifier_4;
 
         SHOW_PARSE
           {
@@ -10230,15 +10276,15 @@ inspect_replacing(int backward,
             {
             SHOW_PARSE_INDENT
             }
-          SHOW_PARSE_FIELD("ID-3 ", operations[0].opers[j].replaces[k].matching.field)
-          SHOW_PARSE_FIELD(" ID-5 ", operations[0].opers[j].replaces[k].replacement.field)
-          if( operations[0].opers[j].replaces[k].before.identifier_4.field )
+          SHOW_PARSE_FIELD("ID-3 ", operations[0][j].replaces[k].matching().field)
+          SHOW_PARSE_FIELD(" ID-5 ", operations[0][j].replaces[k].replacement.field)
+          if( operations[0][j].replaces[k].before.identifier_4.field )
             {
-            SHOW_PARSE_FIELD("before ", operations[0].opers[j].replaces[k].before.identifier_4.field)
+            SHOW_PARSE_FIELD("before ", operations[0][j].replaces[k].before.identifier_4.field)
             }
-          if(operations[0].opers[j].replaces[k].after.identifier_4.field)
+          if(operations[0][j].replaces[k].after.identifier_4.field)
             {
-            SHOW_PARSE_FIELD("after ", operations[0].opers[j].replaces[k].after.identifier_4.field)
+            SHOW_PARSE_FIELD("after ", operations[0][j].replaces[k].after.identifier_4.field)
             }
           SHOW_PARSE_END
           }
@@ -10263,7 +10309,7 @@ inspect_replacing(int backward,
       }
     }
 
-  build_array_of_treeplets(1, pcbl_index, pcbl_refers);
+  build_array_of_treeplets(1, pcbl_index, pcbl_refers.data());
 
   // Do the actual call:
   gg_call(VOID,
@@ -10274,13 +10320,12 @@ inspect_replacing(int backward,
   }
 
 void
-parser_inspect(cbl_refer_t identifier_1,
+parser_inspect(const cbl_refer_t& identifier_1,
                bool backward,
-               size_t n_operations,
-               cbx_inspect_t<cbl_refer_t>* operations)
+               cbl_inspect_opers_t& operations)
   {
   Analyze();
-  gcc_assert(n_operations);
+  gcc_assert(! operations.empty());
 
   /*  Operating philosophy:  We are going to minimize the amount of
       GENERIC tag creation here at compile time, mainly by eliminating
@@ -10290,12 +10335,12 @@ parser_inspect(cbl_refer_t identifier_1,
   if( operations[0].tally.field )
     {
     // This is a FORMAT 1 "TALLYING"
-    inspect_tally(backward, identifier_1, n_operations, operations);
+    inspect_tally(backward, identifier_1, operations);
     }
   else
     {
     // This is a FORMAT 2 "REPLACING"
-    inspect_replacing(backward, identifier_1, n_operations, operations);
+    inspect_replacing(backward, identifier_1, operations);
     }
   }
 
@@ -10441,8 +10486,8 @@ parser_intrinsic_subst( cbl_field_t *f,
   sv_is_i_o = true;
   store_location_stuff("SUBSTITUTE");
   unsigned char *control_bytes = (unsigned char *)xmalloc(argc * sizeof(unsigned char));
-  cbl_refer_t *arg1 = (cbl_refer_t *)xmalloc(argc * sizeof(cbl_refer_t));
-  cbl_refer_t *arg2 = (cbl_refer_t *)xmalloc(argc * sizeof(cbl_refer_t));
+  std::vector<cbl_refer_t> arg1(argc);
+  std::vector<cbl_refer_t> arg2(argc);
 
   for(size_t i=0; i<argc; i++)
     {
@@ -10458,8 +10503,8 @@ parser_intrinsic_subst( cbl_field_t *f,
 
   tree control = gg_array_of_bytes(argc, control_bytes);
 
-  build_array_of_treeplets(1, argc, arg1);
-  build_array_of_treeplets(2, argc, arg2);
+  build_array_of_treeplets(1, argc, arg1.data());
+  build_array_of_treeplets(2, argc, arg2.data());
 
   gg_call(VOID,
           "__gg__substitute",
@@ -10473,8 +10518,6 @@ parser_intrinsic_subst( cbl_field_t *f,
 
   gg_free(control);
 
-  free(arg2);
-  free(arg1);
   free(control_bytes);
   }
 
@@ -10625,12 +10668,12 @@ parser_intrinsic_call_1( cbl_field_t *tgt,
       }
     size_t upper = ref1.field->occurs.bounds.upper
                                     ? ref1.field->occurs.bounds.upper : 1;
-    if( ref1.nsubscript )
+    if( ref1.nsubscript() )
       {
       upper = 1;
       }
 
-    if( is_table(ref1.field) && !ref1.nsubscript )
+    if( is_table(ref1.field) && !ref1.nsubscript() )
       {
       static tree depending_on = gg_define_variable(LONG, "..pic1_dep");
       depending_on_value(depending_on, ref1.field);
@@ -11269,7 +11312,7 @@ parser_bsearch_conditional( cbl_label_t* name )
   }
 
 bool
-is_ascending_key(cbl_refer_t key)
+is_ascending_key(const cbl_refer_t& key)
   {
   bool retval = true;
 
@@ -11290,7 +11333,7 @@ is_ascending_key(cbl_refer_t key)
       {
       size_t index_of_field
         = family_tree->occurs.keys[i].field_list.fields[j];
-      cbl_field_t *key_field = cbl_field_of(symbol_at(index_of_field));
+      const cbl_field_t *key_field = cbl_field_of(symbol_at(index_of_field));
 
       if( strcmp( key_field->name,
                   key.field->name ) == 0 )
@@ -11416,8 +11459,7 @@ void
 parser_sort(cbl_refer_t tableref,
             bool duplicates,
             cbl_alphabet_t *alphabet,
-            size_t nkeys,
-            cbl_key_t *keys )
+            const std::vector<cbl_key_t>& keys )
   {
   Analyze();
   SHOW_PARSE
@@ -11439,18 +11481,18 @@ parser_sort(cbl_refer_t tableref,
             __func__,
             tableref.field->name);
     }
-  size_t total_keys = 0;
-  for( size_t i=0; i<nkeys; i++ )
-    {
-    total_keys += keys[i].nfield;
-    }
-  cbl_field_t **flattened_fields = (cbl_field_t **)xmalloc(total_keys * sizeof(cbl_field_t *));
+  size_t total_keys = std::accumulate( keys.begin(), keys.end(), 0,
+                                       [](size_t n, const cbl_key_t& key ) {
+                                         return n + key.fields.size();
+                                       } );
+  typedef const cbl_field_t * const_field_t;
+  const_field_t *flattened_fields = (const_field_t *)xmalloc(total_keys * sizeof(cbl_field_t *));
   size_t *flattened_ascending       = (size_t *)xmalloc(total_keys * sizeof(size_t));
 
   size_t key_index = 0;
-  for( size_t i=0; i<nkeys; i++ )
+  for( size_t i=0; i<keys.size(); i++ )
     {
-    for( size_t j=0; j<keys[i].nfield; j++ )
+    for( size_t j=0; j<keys[i].fields.size(); j++ )
       {
       flattened_fields[key_index]    = keys[i].fields[j];
       flattened_ascending[key_index] = keys[i].ascending ? 1 : 0;
@@ -11459,7 +11501,8 @@ parser_sort(cbl_refer_t tableref,
     }
 
   // Create the array of cbl_field_t pointers for the keys
-  tree all_keys = gg_array_of_field_pointers( total_keys, flattened_fields);
+  tree all_keys = gg_array_of_field_pointers( total_keys,
+                                              const_cast<cbl_field_t**>(flattened_fields));
 
   // Create the array of integers that are the flags for ASCENDING:
   tree ascending = gg_array_of_size_t( total_keys, flattened_ascending );
@@ -11498,8 +11541,7 @@ void
 parser_file_sort(   cbl_file_t *workfile,
                     bool duplicates,
                     cbl_alphabet_t *alphabet,
-                    size_t nkeys,
-                    cbl_key_t *keys,
+                    const std::vector<cbl_key_t>& keys,
                     size_t ninput,
                     cbl_file_t **inputs,
                     size_t noutput,
@@ -11576,18 +11618,18 @@ parser_file_sort(   cbl_file_t *workfile,
   // clone of the code for handling multiple keys, each of which can have
   // multiple fields.
 
-  size_t total_keys = 0;
-  for( size_t i=0; i<nkeys; i++ )
-    {
-    total_keys += keys[i].nfield;
-    }
-  cbl_field_t **flattened_fields = (cbl_field_t **)xmalloc(total_keys * sizeof(cbl_field_t *));
+  size_t total_keys = std::accumulate( keys.begin(), keys.end(), 0,
+                                       []( size_t n, const cbl_key_t& key ) {
+                                         return n + key.fields.size();
+                                       } );
+  typedef const cbl_field_t * const_field_t;
+  auto flattened_fields = (const_field_t *)xmalloc(total_keys * sizeof(cbl_field_t *));
   size_t *flattened_ascending    = (size_t *)      xmalloc(total_keys * sizeof(size_t));
 
   size_t key_index = 0;
-  for( size_t i=0; i<nkeys; i++ )
+  for( size_t i=0; i<keys.size(); i++ )
     {
-    for( size_t j=0; j<keys[i].nfield; j++ )
+    for( size_t j=0; j<keys[i].fields.size(); j++ )
       {
       flattened_fields[key_index]    = keys[i].fields[j];
       flattened_ascending[key_index] = keys[i].ascending ? 1 : 0;
@@ -11596,7 +11638,8 @@ parser_file_sort(   cbl_file_t *workfile,
     }
 
   // Create the array of cbl_field_t pointers for the keys
-  tree all_keys = gg_array_of_field_pointers( total_keys, flattened_fields);
+  tree all_keys = gg_array_of_field_pointers( total_keys,
+                                              const_cast<cbl_field_t**>(flattened_fields));
 
   // Create the array of integers that are the flags for ASCENDING:
   tree ascending = gg_array_of_size_t( total_keys, flattened_ascending );
@@ -11898,8 +11941,7 @@ gg_array_of_file_pointers(  size_t N,
 void
 parser_file_merge(  cbl_file_t *workfile,
                     cbl_alphabet_t *alphabet,
-                    size_t nkeys,
-                    cbl_key_t *keys,
+                    const std::vector<cbl_key_t>& keys,
                     size_t ninputs,
                     cbl_file_t **inputs,
                     size_t noutputs,
@@ -11922,20 +11964,19 @@ parser_file_merge(  cbl_file_t *workfile,
                 build_int_cst_type(INT, file_sequential_e));
     }
 
-  size_t total_keys = 0;
-  for( size_t i=0; i<nkeys; i++ )
-    {
-    total_keys += keys[i].nfield;
-    }
-  cbl_field_t **flattened_fields
-            = (cbl_field_t **)xmalloc(total_keys * sizeof(cbl_field_t *));
+  size_t total_keys = std::accumulate( keys.begin(), keys.end(), 0,
+                                       []( size_t i, const cbl_key_t& key ) {
+                                         return i + key.fields.size();
+                                       } );
+  typedef const cbl_field_t * const_field_t;
+  const_field_t *flattened_fields = (const_field_t *)xmalloc(total_keys * sizeof(cbl_field_t *));
   size_t *flattened_ascending
             = (size_t *)xmalloc(total_keys * sizeof(size_t));
 
   size_t key_index = 0;
-  for( size_t i=0; i<nkeys; i++ )
+  for( size_t i=0; i<keys.size(); i++ )
     {
-    for( size_t j=0; j<keys[i].nfield; j++ )
+    for( size_t j=0; j<keys[i].fields.size(); j++ )
       {
       flattened_fields[key_index]    = keys[i].fields[j];
       flattened_ascending[key_index] = keys[i].ascending ? 1 : 0;
@@ -11944,7 +11985,8 @@ parser_file_merge(  cbl_file_t *workfile,
     }
 
   // Create the array of cbl_field_t pointers for the keys
-  tree all_keys = gg_array_of_field_pointers(total_keys, flattened_fields);
+  tree all_keys = gg_array_of_field_pointers(total_keys,
+                                             const_cast<cbl_field_t**>(flattened_fields));
 
   // Create the array of integers that are the flags for ASCENDING:
   tree ascending = gg_array_of_size_t(total_keys, flattened_ascending);
@@ -12011,7 +12053,7 @@ parser_file_merge(  cbl_file_t *workfile,
   gg_call(VOID,
           "__gg__merge_files",
           gg_get_address_of(workfile->var_decl_node),
-          build_int_cst_type(SIZE_T, nkeys),
+          build_int_cst_type(SIZE_T, keys.size()),
           all_keys,
           ascending,
           build_int_cst_type(SIZE_T, ninputs),
@@ -12183,7 +12225,7 @@ parser_unstring(cbl_refer_t src,
     gg_append_statement(not_overflow->structs.unstring->over.label);
     }
 
-  cbl_refer_t *delims = (cbl_refer_t *)xmalloc(ndelimited * sizeof(cbl_refer_t));
+  std::vector<cbl_refer_t> delims(ndelimited);
   char *alls = (char *)xmalloc(ndelimited+1);
 
   for(size_t i=0; i<ndelimited; i++)
@@ -12195,7 +12237,7 @@ parser_unstring(cbl_refer_t src,
 
   tree t_alls         = build_string_literal(ndelimited+1, alls);
 
-  build_array_of_treeplets(1, ndelimited, delims);
+  build_array_of_treeplets(1, ndelimited, delims.data());
   build_array_of_treeplets(2, noutputs,   outputs);
   build_array_of_treeplets(3, noutputs,   delimiters);
   build_array_of_treeplets(4, noutputs,   counts);
@@ -12219,7 +12261,6 @@ parser_unstring(cbl_refer_t src,
                           NULL_TREE)
                           );
   free(alls);
-  free(delims);
 
   if( overflow )
     {
@@ -12255,12 +12296,12 @@ parser_unstring(cbl_refer_t src,
   }
 
 void
-parser_string(  cbl_refer_t tgt,
-                cbl_refer_t pointer,
-                size_t nsource,
-                cbl_string_src_t *sources,
-                cbl_label_t *overflow,
-                cbl_label_t *not_overflow )
+parser_string(const cbl_refer_t& tgt,
+              const cbl_refer_t& pointer,
+              size_t nsource,
+              cbl_string_src_t *sources,
+              cbl_label_t *overflow,
+              cbl_label_t *not_overflow )
   {
   SHOW_PARSE
     {
@@ -12286,7 +12327,7 @@ parser_string(  cbl_refer_t tgt,
     cblc_count += 1 + sources[i].ninput; // 1 for identifier_2 + ninput identifier_1 values;
     }
 
-  cbl_refer_t *refers = (cbl_refer_t *)xmalloc(cblc_count * sizeof(cbl_refer_t));
+  std::vector<cbl_refer_t> refers(cblc_count);
 
   size_t index_int = 0;
   size_t index_cblc = 0;
@@ -12311,7 +12352,7 @@ parser_string(  cbl_refer_t tgt,
 
   tree pintegers = build_array_of_size_t( index_int, integers);
 
-  build_array_of_treeplets(1, index_cblc, refers);
+  build_array_of_treeplets(1, index_cblc, refers.data());
 
   tree t_overflow = gg_define_int();
   gg_assign(t_overflow, gg_call_expr( INT,
@@ -12321,7 +12362,6 @@ parser_string(  cbl_refer_t tgt,
   gg_free(pintegers);
 
   free(integers);
-  free(refers);
 
   if( overflow )
     {
@@ -12813,7 +12853,7 @@ parser_call(   cbl_refer_t name,
     SHOW_PARSE_TEXT(" (")
     for(size_t i=0; i<narg; i++)
       {
-      cbl_field_t *p = args[i].refer.field;
+      const cbl_field_t *p = args[i].refer.field;
       SHOW_PARSE_FIELD( " ",  p)
       }
     SHOW_PARSE_TEXT(" )")
@@ -13203,7 +13243,8 @@ typedef struct hier_node
   hier_node() :
     our_index(0),
     common(false),
-    parent_node(NULL)
+    parent_node(nullptr),
+    name(nullptr)
     {}
   } hier_node;
 
@@ -13247,7 +13288,7 @@ find_uncles(const hier_node *node, std::vector<const hier_node *> &uncles)
   }
 
 void
-parser_program_hierarchy( const struct cbl_prog_hier_t& hier )
+parser_program_hierarchy( const cbl_prog_hier_t& hier )
   {
   Analyze();
   /*  This routine gets called near the end of every program-id.  It keeps
@@ -13265,7 +13306,7 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier )
       }
     else
       {
-      for( size_t i=0; i<hier.nlabel; i++ )
+      for( size_t i=0; i<hier.labels.size(); i++ )
         {
         if( i )
           {
@@ -13320,9 +13361,9 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier )
   node_map[0] = nodes.back();
 
   // Pass 1: Create a node for every program:
-  for( size_t i=0; i<hier.nlabel; i++ )
+  for( size_t i=0; i<hier.labels.size(); i++ )
     {
-    hier_node *existing_node = find_hier_node(node_map, hier.labels[i].ordinal);
+    const hier_node *existing_node = find_hier_node(node_map, hier.labels[i].ordinal);
     gcc_assert( existing_node == NULL );
 
     hier_node *new_node = new hier_node;
@@ -13334,7 +13375,7 @@ parser_program_hierarchy( const struct cbl_prog_hier_t& hier )
     }
 
   // Pass 2: populate each node with their parent and children:
-  for( size_t i=0; i<hier.nlabel; i++ )
+  for( size_t i=0; i<hier.labels.size(); i++ )
     {
     hier_node *child_node = find_hier_node(node_map, hier.labels[i].ordinal);
     gcc_assert(child_node);
@@ -13726,7 +13767,7 @@ hijack_for_development(const char *funcname)
   }
 
 static void
-conditional_abs(tree source, cbl_field_t *field)
+conditional_abs(tree source, const cbl_field_t *field)
   {
   Analyze();
   if( !(field->attr & signable_e) )
@@ -14071,7 +14112,7 @@ tree float_type_of(int n)
   }
 
 static tree
-float_type_of(cbl_field_t *field)
+float_type_of(const cbl_field_t *field)
   {
   gcc_assert(field->type == FldFloat);
   return float_type_of(field->data.capacity);
@@ -15554,7 +15595,7 @@ initial_from_initial(cbl_field_t *field)
 
       digits_from_float128(ach, field, field->data.digits, rdigits, value);
 
-      char *digits = ach;
+      const char *digits = ach;
       if(    (field->attr & signable_e)
           && (field->attr & separate_e)
           && (field->attr & leading_e ) )
@@ -15643,7 +15684,7 @@ initial_from_initial(cbl_field_t *field)
                        : field->data.capacity * 2 - 1;
       digits_from_float128(ach, field, ndigits, rdigits, value);
 
-      char *digits = ach;
+      const char *digits = ach;
       for(size_t i=0; i<ndigits; i++)
         {
         if( !(i & 0x01) )
@@ -15711,22 +15752,19 @@ initial_from_initial(cbl_field_t *field)
       retval = (char *)xmalloc(field->data.capacity+1);
       if( field->data.initial && field->attr & quoted_e )
         {
-        if( field->attr & quoted_e )
+        // What the programmer says the value is, the value becomes, no
+        // matter how wrong it might be.
+        size_t length = std::min( (size_t)field->data.capacity,
+                                  strlen(field->data.initial));
+        for(size_t i=0; i<length; i++)
           {
-          // What the programmer says the value is, the value becomes, no
-          // matter how wrong it might be.
-          size_t length = std::min( (size_t)field->data.capacity,
-                                    strlen(field->data.initial));
-          for(size_t i=0; i<length; i++)
-            {
-            retval[i] = ascii_to_internal(field->data.initial[i]);
-            }
-          if( length < (size_t)field->data.capacity )
-            {
-            memset( retval+length,
-                    internal_space,
-                    (size_t)field->data.capacity - length);
-            }
+          retval[i] = ascii_to_internal(field->data.initial[i]);
+          }
+        if( length < (size_t)field->data.capacity )
+          {
+          memset( retval+length,
+                  internal_space,
+                  (size_t)field->data.capacity - length);
           }
         }
       else
@@ -16333,7 +16371,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
       fprintf(stderr," OCCURS:" HOST_SIZE_T_PRINT_DEC,
               (fmt_size_t)new_var->occurs.ntimes());
       }
-    cbl_field_t *parent = parent_of(new_var);
+    const cbl_field_t *parent = parent_of(new_var);
     if( parent )
       {
       fprintf(stderr,
@@ -16347,7 +16385,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
       size_t parent_index = new_var->parent;
       if( parent_index )
         {
-        symbol_elem_t *e = symbol_at(parent_index);
+        const symbol_elem_t *e = symbol_at(parent_index);
         if( e->type == SymFile )
           {
           fprintf(stderr,
@@ -16747,10 +16785,7 @@ parser_symbol_add(struct cbl_field_t *new_var )
     if( *external_record_base )
       {
       char achDataName[256];
-      if( *external_record_base )
-        {
-        sprintf(achDataName, "__%s_vardata", external_record_base);
-        }
+      sprintf(achDataName, "__%s_vardata", external_record_base);
       tree array_type = build_array_type_nelts(UCHAR, new_var->data.capacity);
       new_var->data_decl_node = gg_define_variable(
                           array_type,
index 26944572d629df1cae7d4faf93ba16372eed2de2..0c2887dc9301083d3d34c4499c37ee45c44cc78e 100644 (file)
@@ -119,26 +119,26 @@ parser_divide(size_t nC, cbl_num_result_t *C,
               void *compute_error = NULL);  // This has to be cast to a tree pointer to int
 
 void
-parser_add( struct cbl_refer_t tgt,
-            struct cbl_refer_t a, struct cbl_refer_t b,
+parser_add( const cbl_refer_t& tgt,
+            const cbl_refer_t& a,  const cbl_refer_t& b,
             enum cbl_round_t = truncation_e );
 
 void
-parser_subtract( struct cbl_refer_t tgt,
-                 struct cbl_refer_t a, struct cbl_refer_t b,
+parser_subtract( const cbl_refer_t& tgt,
+                 const cbl_refer_t& a,  const cbl_refer_t& b,
                  enum cbl_round_t = truncation_e );
 
 void
-parser_multiply( struct cbl_refer_t tgt,
-                 struct cbl_refer_t a, struct cbl_refer_t b,
+parser_multiply( const cbl_refer_t& tgt,
+                 const cbl_refer_t& a,  const cbl_refer_t& b,
                  enum cbl_round_t = truncation_e );
 
 void
-parser_divide( struct cbl_refer_t quotient,
-               struct cbl_refer_t divisor,
-               struct cbl_refer_t dividend,
+parser_divide( const cbl_refer_t& quotient,
+               const cbl_refer_t& divisor,
+               const cbl_refer_t& dividend,
                enum cbl_round_t = truncation_e,
-               struct cbl_refer_t remainder = cbl_refer_t());
+               const cbl_refer_t& remainder = cbl_refer_t());
 
 // void
 // parser_exponentiation(  cbl_refer_t cref,
@@ -225,7 +225,7 @@ parser_perform_conditional_end( struct cbl_perform_tgt_t *tgt );
  * For an in-line loop body, tgt->from.type == LblLoop, and tgt->to is NULL.
  */
 void
-parser_perform( struct cbl_perform_tgt_t *tgt, struct cbl_refer_t N );
+parser_perform( const cbl_perform_tgt_t *tgt, cbl_refer_t N );
 
 /*
  * A simple UNTIL loop uses 1 varys element.  For VARY loops, the
@@ -255,7 +255,7 @@ parser_end_program(const char *name=NULL);
 
 void parser_sleep(cbl_refer_t seconds);
 
-void parser_exit( cbl_refer_t refer, ec_type_t = ec_none_e );
+void parser_exit( const cbl_refer_t& refer, ec_type_t = ec_none_e );
 void parser_exit_section(void);
 void parser_exit_paragraph(void);
 void parser_exit_perform( struct cbl_perform_tgt_t *tgt, bool cycle );
@@ -297,7 +297,7 @@ void
 parser_symbol_add(struct cbl_field_t *field);
 
 void
-parser_initialize(struct cbl_refer_t refer, bool like_parser_symbol_add=false);
+parser_initialize(const cbl_refer_t& refer, bool like_parser_symbol_add=false);
 
 void
 parser_initialize_programs(size_t nprog, struct cbl_refer_t *progs);
@@ -315,7 +315,7 @@ void
 parser_alter( cbl_perform_tgt_t *tgt );
 
 void
-parser_set_conditional88( struct cbl_refer_t tgt, bool which_way );
+parser_set_conditional88( const cbl_refer_t& tgt, bool which_way );
 void
 parser_set_numeric(struct cbl_field_t *tgt, ssize_t value);
 
@@ -406,14 +406,12 @@ void
 parser_sort(cbl_refer_t table,
             bool duplicates,
             cbl_alphabet_t *alphabet,
-            size_t nkey,
-            cbl_key_t *keys );
+            const std::vector<cbl_key_t>& keys );
 void
 parser_file_sort(   cbl_file_t *file,
                     bool duplicates,
                     cbl_alphabet_t *alphabet,
-                    size_t nkey,
-                    cbl_key_t *keys,
+                    const std::vector<cbl_key_t>& keys,
                     size_t ninput,
                     cbl_file_t **inputs,
                     size_t noutput,
@@ -423,8 +421,7 @@ parser_file_sort(   cbl_file_t *file,
 void
 parser_file_merge(  cbl_file_t *file,
                     cbl_alphabet_t *alphabet,
-                    size_t nkey,
-                    cbl_key_t *keys,
+                    const std::vector<cbl_key_t>& keys,
                     size_t ninput,
                     cbl_file_t **inputs,
                     size_t noutput,
@@ -492,12 +489,12 @@ void
 parser_string_overflow_end( cbl_label_t *name );
 
 void
-parser_string(  cbl_refer_t tgt,
-                cbl_refer_t pointer,
-                size_t nsource,
-                cbl_string_src_t *sources,
-                cbl_label_t *overflow,
-                cbl_label_t *not_overflow );
+parser_string(const cbl_refer_t& tgt,
+              const cbl_refer_t& pointer,
+              size_t nsource,
+              cbl_string_src_t *sources,
+              cbl_label_t *overflow,
+              cbl_label_t *not_overflow );
 
 void
 parser_unstring( cbl_refer_t src,
@@ -552,7 +549,7 @@ void parser_entry_activate( size_t iprog, const cbl_label_t *declarative );
 void parser_entry( cbl_field_t *name,
                    size_t narg = 0, cbl_ffi_arg_t args[] = NULL);
 
-bool is_ascending_key(cbl_refer_t key);
+bool is_ascending_key(const cbl_refer_t& key);
 
 void register_main_switch(const char *main_string);
 
index edf3f22f68ebc07b3f615f21b97aebaee924d6d8..bf3885bcf6dff039710c0981f536d960ae0aee68 100644 (file)
@@ -95,8 +95,8 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C,
                       size_t nA, cbl_refer_t *A,
                       size_t nB, cbl_refer_t *B,
                       cbl_arith_format_t format,
-                      cbl_label_t *error,
-                      cbl_label_t *not_error,
+                      const cbl_label_t *error,
+                      const cbl_label_t *not_error,
                       tree compute_error, // Pointer to int
                       const char *operation,
                       cbl_refer_t *remainder = NULL)
@@ -137,7 +137,7 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C,
 
   // Allocate nC+1 in case this is a divide with a REMAINDER
 
-  cbl_refer_t *results = (cbl_refer_t *)xmalloc((nC+1) * sizeof( cbl_refer_t ));
+  std::vector<cbl_refer_t> results(nC + 1);
   int ncount = 0;
 
   if( nC+1 <= MIN_FIELD_BLOCK_SIZE )
@@ -207,7 +207,7 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C,
 
   build_array_of_treeplets(1, nA, A);
   build_array_of_treeplets(2, nB, B);
-  build_array_of_treeplets(3, ncount, results);
+  build_array_of_treeplets(3, ncount, results.data());
 
   gg_call(VOID,
           operation,
@@ -253,9 +253,6 @@ arithmetic_operation(size_t nC, cbl_num_result_t *C,
     {
     SHOW_PARSE_END
     }
-
-  // We need to release all of the refers we allocated:
-  free(results);
   }
 
 static void
@@ -307,7 +304,7 @@ arithmetic_error_handler( cbl_label_t *error,
   }
 
 static bool
-is_somebody_float(size_t nA, cbl_refer_t *A)
+is_somebody_float(size_t nA, const cbl_refer_t *A)
   {
   bool retval = false;
   for(size_t i=0; i<nA; i++)
@@ -322,7 +319,7 @@ is_somebody_float(size_t nA, cbl_refer_t *A)
   }
 
 static bool
-is_somebody_float(size_t nC, cbl_num_result_t *C)
+is_somebody_float(size_t nC, const cbl_num_result_t *C)
   {
   bool retval = false;
   for(size_t i=0; i<nC; i++)
@@ -337,7 +334,7 @@ is_somebody_float(size_t nC, cbl_num_result_t *C)
   }
 
 static bool
-all_results_binary(size_t nC, cbl_num_result_t *C)
+all_results_binary(size_t nC, const cbl_num_result_t *C)
   {
   bool retval = true;
 
@@ -581,10 +578,6 @@ fast_multiply(size_t nC, cbl_num_result_t *C,
         {
         // This is a MULTIPLY Format 2
         get_binary_value(valB, NULL, B[0].field, refer_offset(B[0]));
-        }
-
-      if(nB)
-        {
         gg_assign(valA, gg_multiply(valA, valB));
         }
 
@@ -993,9 +986,9 @@ parser_add( size_t nC, cbl_num_result_t *C,
   }
 
 void
-parser_add( cbl_refer_t cref,
-            cbl_refer_t aref,
-            cbl_refer_t bref,
+parser_add( const cbl_refer_t& cref,
+            const cbl_refer_t& aref,
+            const cbl_refer_t& bref,
             cbl_round_t rounded)
   {
   // This is the simple and innocent C = A + B
@@ -1215,9 +1208,9 @@ parser_divide(  size_t nC, cbl_num_result_t *C,  // C = A / B
   }
 
 void
-parser_multiply(cbl_refer_t cref,
-                cbl_refer_t aref,
-                cbl_refer_t bref,
+parser_multiply(const cbl_refer_t& cref,
+                const cbl_refer_t& aref,
+                const cbl_refer_t& bref,
                 cbl_round_t rounded )
   {
   cbl_num_result_t C[1];
@@ -1238,11 +1231,11 @@ parser_multiply(cbl_refer_t cref,
   }
 
 void
-parser_divide(  cbl_refer_t cref,
-                cbl_refer_t aref,
-                cbl_refer_t bref,
+parser_divide(  const cbl_refer_t& cref,
+                const cbl_refer_t& aref,
+                const cbl_refer_t& bref,
                 cbl_round_t rounded,
-                cbl_refer_t remainder_ref )
+                const cbl_refer_t& remainder_ref )
   {
   cbl_num_result_t C[1];
   C[0].rounded = rounded;
@@ -1704,9 +1697,9 @@ parser_subtract(size_t nC, cbl_num_result_t *C, // C = B - A
   }
 
 void
-parser_subtract(cbl_refer_t cref, // cref = aref - bref
-                cbl_refer_t aref,
-                cbl_refer_t bref,
+parser_subtract(const cbl_refer_t& cref, // cref = aref - bref
+                const cbl_refer_t& aref,
+                const cbl_refer_t& bref,
                 cbl_round_t rounded )
   {
   cbl_num_result_t C[1];
index f1098f02768e220af97d023e2f6e05289b47945a..8ec7a7834faad221405b4969c34f8c977ca162dc 100644 (file)
@@ -515,7 +515,7 @@ get_depending_on_value_from_odo(tree retval, cbl_field_t *odo)
 
 static
 void
-get_depending_on_value(tree retval, cbl_refer_t &refer)
+get_depending_on_value(tree retval, const cbl_refer_t &refer)
   {
   /*  This routine, called only when we know there is an OCCURS DEPENDING ON
       clause, returns the current value of the DEPENDING ON variable.  When
@@ -550,7 +550,7 @@ get_data_offset(cbl_refer_t &refer,
   int all_flags = 0;
   int all_flag_bit = 1;
 
-  if( refer.nsubscript )
+  if( refer.nsubscript() )
     {
     REFER("subscript");
     // We have at least one subscript:
@@ -569,7 +569,7 @@ get_data_offset(cbl_refer_t &refer,
     cbl_field_t *parent = refer.field;
 
     // Note the backwards test, because refer->nsubscript is an unsigned value
-    for(size_t i=refer.nsubscript-1; i<refer.nsubscript; i-- )
+    for(size_t i=refer.nsubscript()-1; i<refer.nsubscript(); i-- )
       {
       // We need to search upward for an ancestor with occurs_max:
       while(parent)
@@ -698,6 +698,8 @@ get_data_offset(cbl_refer_t &refer,
   return retval;
   }
 
+static tree tree_type_from_field(const cbl_field_t *field);
+
 void
 get_binary_value( tree value,
                   tree rdigits,
@@ -1265,8 +1267,8 @@ get_binary_value( tree value,
     }
   }
 
-tree
-tree_type_from_field(cbl_field_t *field)
+static tree
+tree_type_from_field(const cbl_field_t *field)
   {
   gcc_assert(field);
   return tree_type_from_size(field->data.capacity, field->attr & signable_e);
@@ -1559,7 +1561,7 @@ tree_type_from_size(size_t bytes, int signable)
 
 static
 bool
-refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type)
+refer_has_depends(const cbl_refer_t &refer, refer_type_t refer_type)
   {
   if( suppress_dest_depends )
     {
@@ -1577,7 +1579,7 @@ refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type)
 
   // Check if there there is an occurs with a depending_on in the hierarchy
   bool proceed = false;
-  cbl_field_t *odo = symbol_find_odo(refer.field);
+  const cbl_field_t *odo = symbol_find_odo(refer.field);
   cbl_field_t *depending_on;
   if( odo && odo != refer.field )
     {
@@ -1603,7 +1605,7 @@ refer_has_depends(cbl_refer_t &refer, refer_type_t refer_type)
           {
           parent1 = p;
           }
-        cbl_field_t *parent2 = depending_on;
+        const cbl_field_t *parent2 = depending_on;
         while( (p = parent_of(parent2)) )
           {
           parent2 = p;
@@ -1912,18 +1914,14 @@ char *
 get_literal_string(cbl_field_t *field)
   {
   assert(field->type == FldLiteralA);
-  char *buffer = NULL;
-  size_t buffer_length = 0;
-  if( buffer_length < field->data.capacity+1 )
-    {
-    buffer_length = field->data.capacity+1;
-    buffer = (char *)xrealloc(buffer, buffer_length);
-    }
+  size_t buffer_length = field->data.capacity+1;
+  char *buffer = static_cast<char *>(xcalloc(1, buffer_length));
+
   for(size_t i=0; i<field->data.capacity; i++)
     {
     buffer[i] = ascii_to_internal(field->data.initial[i]);
     }
-  buffer[field->data.capacity] = '\0';
+
   return buffer;
   }
 
@@ -1943,7 +1941,7 @@ refer_is_clean(cbl_refer_t &refer)
 
   return     !refer.all
           && !refer.addr_of
-          && !refer.nsubscript
+          && !refer.nsubscript()
           && !refer.refmod.from
           && !refer.refmod.len
           && !refer_has_depends(refer, refer_source)
@@ -2141,4 +2139,4 @@ get_time_nanoseconds()
   return retval;
 #endif
   return retval;
-}
\ No newline at end of file
+}
index fb582e5a493fbd148abe90abef6dc6a90a333a49..0d9028e035c8cac98d805a1c2480f8ad36389ee0 100644 (file)
@@ -92,7 +92,7 @@ int       get_scaled_rdigits(cbl_field_t *field);
 int       get_scaled_digits(cbl_field_t *field);
 tree      tree_type_from_digits(size_t digits, int signable);
 tree      tree_type_from_size(size_t bytes, int signable);
-tree      tree_type_from_field(cbl_field_t *field);
+
 void      get_binary_value( tree value,
                             tree rdigits,
                             cbl_field_t *field,
index fb8fda421634f26abdd74af2a04713786eabc191..96399f5dc0103e313cb681e84f542e143b8625ee 100644 (file)
 static inline bool
 is_active( const cbl_refer_t& refer ) { return NULL != refer.field; }
 
-template <typename DATA>
-struct cbx_inspect_qual_t {
+struct cbl_inspect_qual_t {
   bool initial;
-  DATA identifier_4;
+  cbl_refer_t identifier_4;
 
-  cbx_inspect_qual_t() : initial(false), identifier_4(DATA()) {}
-  cbx_inspect_qual_t( bool initial, const DATA& identifier_4 )
+  cbl_inspect_qual_t() : initial(false), identifier_4(cbl_refer_t()) {}
+  cbl_inspect_qual_t( bool initial, const cbl_refer_t& identifier_4 )
     : initial(initial), identifier_4(identifier_4)
-    {
-      //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name);
-    }
-  cbx_inspect_qual_t( const cbx_inspect_qual_t& that )
+    {}
+  cbl_inspect_qual_t( const cbl_inspect_qual_t& that )
     : initial(that.initial)
     , identifier_4(that.identifier_4)
-    {
-      //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name);
-    }
+    {}
 
-  cbx_inspect_qual_t& operator=( const cbx_inspect_qual_t& that ) {
+  cbl_inspect_qual_t& operator=( const cbl_inspect_qual_t& that ) {
     initial = that.initial;
     identifier_4 = that.identifier_4;
-    //if( identifier_4.field ) yywarn("%s:qualifying field is '%s'", __func__, identifier_4.field->name);
     return *this;
   }
 
   bool active() const { return is_active(identifier_4); }
-
-  void clear() {
-    initial = false;
-    identifier_4.clear();
-  }
 };
 
-typedef cbx_inspect_qual_t<cbl_refer_t> cbl_inspect_qual_t;
-
 /*
  * Data for INSPECT X TALLYING Y FOR.  Captures information for operands of
  * CHARACTERS/ALL/LEADING.  The CHARACTERS/ALL/LEADING control is kept at the
  * next higher level, and may be repeated for each tally.
  *
- * cbx_inspect_match_t::matching is not used with CHARACTERS
+ * cbl_inspect_match_t::matching is not used with CHARACTERS
  */
-template <typename DATA>
-struct cbx_inspect_match_t {
-  DATA matching;                          // identifier-3/5 or literal-1/3
-  cbx_inspect_qual_t<DATA> before, after; // phrase 1
-
-  cbx_inspect_match_t(
-    const DATA& matching = DATA(),
-    const cbx_inspect_qual_t<DATA>& before = cbx_inspect_qual_t<DATA>(),
-    const cbx_inspect_qual_t<DATA>& after  = cbx_inspect_qual_t<DATA>()
-    )
-    : matching(matching)
+
+class cbl_inspect_match_t {
+  friend void dump_inspect_match( const cbl_inspect_match_t& M );
+  cbl_refer_t match;  // identifier-3/5 or literal-1/3
+  cbl_refer_t tally;  // collected too soon, belongs to next phrase 
+ public:
+  cbl_inspect_qual_t before, after; // phrase 1
+
+  cbl_inspect_match_t() {}
+  explicit 
+  cbl_inspect_match_t( const cbl_refer_t& matching,
+                       const cbl_inspect_qual_t& before = cbl_inspect_qual_t(),
+                       const cbl_inspect_qual_t& after  = cbl_inspect_qual_t() )
+    : match(matching)
     , before(before)
     , after(after)
   {}
   // match all characters
   bool match_any() const { return !(before.active() || after.active()); }
-};
 
-typedef cbx_inspect_match_t<cbl_refer_t> cbl_inspect_match_t;
+  void save_premature_tally( const cbl_refer_t& tally ) {
+    this->tally = tally; // put it here temporarily
+  }
+  cbl_refer_t premature_tally() {
+    if( !tally.field ) { std::swap(match, tally); }
+    return tally;
+  }
+  
+  const cbl_refer_t& matching( const cbl_refer_t& match ) {
+    return this->match = match;
+  }
+  const cbl_refer_t& matching() const { return match; }
+
+  bool empty() const {
+    return !is_active(match) && !before.active() && !after.active();
+  }
+};
 
 /*
  * Data for INSPECT X REPLACING.  The CHARACTERS/ALL/LEADING/FIRST control is
  * kept at the next higher level, and may be repeated.
  */
-template <typename DATA>
-struct cbx_inspect_replace_t : public cbx_inspect_match_t<DATA> {
-  DATA replacement;
-
-  cbx_inspect_replace_t( const DATA& matching = DATA(),
-                         const DATA& replacement = DATA() )
-    : cbx_inspect_match_t<DATA>(matching)
-    , replacement(replacement)
-  {}
-  cbx_inspect_replace_t( const DATA& matching,
-                         const DATA& replacement,
-                         const cbx_inspect_qual_t<DATA>& before,
-                         const cbx_inspect_qual_t<DATA>& after )
-    : cbx_inspect_match_t<DATA>(matching, before, after)
+struct cbl_inspect_replace_t : public cbl_inspect_match_t {
+  cbl_refer_t replacement;
+
+  cbl_inspect_replace_t() {}
+  cbl_inspect_replace_t( const cbl_refer_t& matching,
+                         const cbl_refer_t& replacement,
+                         const cbl_inspect_qual_t& before,
+                         const cbl_inspect_qual_t& after )
+    : cbl_inspect_match_t(matching, before, after)
     , replacement(replacement)
   {}
 };
 
-typedef cbx_inspect_replace_t<cbl_refer_t> cbl_inspect_replace_t;
-
 // One partial tally or substitution.
-template <typename DATA>
-struct cbx_inspect_oper_t {
+struct cbl_inspect_oper_t {
   cbl_inspect_bound_t bound;  // CHARACTERS/ALL/LEADING/FIRST
-  size_t n_identifier_3;      // N matches/replaces
-  // either tallies or replaces is NULL
-  cbx_inspect_match_t<DATA> *matches;
-  cbx_inspect_replace_t<DATA> *replaces;
+  // either tallies or replaces is empty
+  std::vector<cbl_inspect_match_t> matches;
+  std::vector<cbl_inspect_replace_t> replaces;
 
-  cbx_inspect_oper_t( cbl_inspect_bound_t bound,
-                      std::list<cbx_inspect_match_t<DATA>> matches )
+  cbl_inspect_oper_t() : bound(bound_characters_e) {}
+
+  explicit cbl_inspect_oper_t( const cbl_inspect_match_t& match,
+                               cbl_inspect_bound_t bound = bound_characters_e )
     : bound(bound)
-    , n_identifier_3( matches.size())
-    , matches(NULL)
-    , replaces(NULL)
-    {
-      this->matches = new cbx_inspect_match_t<DATA>[n_identifier_3];
-      std::copy( matches.begin(), matches.end(), this->matches );
-    }
-
-  cbx_inspect_oper_t( cbl_inspect_bound_t bound,
-                      std::list<cbx_inspect_replace_t<DATA>> replaces )
+  {
+    matches.push_back(match);
+  }
+  explicit cbl_inspect_oper_t( const cbl_inspect_replace_t& replace,
+                               cbl_inspect_bound_t bound = bound_characters_e )
     : bound(bound)
-    , n_identifier_3( replaces.size() )
-    , matches(NULL)
-    , replaces(NULL)
-    {
-      this->replaces = new cbx_inspect_replace_t<DATA>[n_identifier_3];
-      std::copy( replaces.begin(), replaces.end(), this->replaces );
-    }
-
-  cbx_inspect_oper_t()
-    : bound(bound_characters_e)
-    , n_identifier_3(0)
-    , matches(NULL)
-    , replaces(NULL)
-    {
-      assert( is_valid() );
-    }
-
-  bool is_valid() const {
-    if( matches && replaces ) return false;
-    if( matches || replaces ) return n_identifier_3 > 0;
-    return n_identifier_3 == 0;
+  {
+    replaces.push_back(replace);
   }
-};
 
-typedef cbx_inspect_oper_t<cbl_refer_t> cbl_inspect_oper_t;
+  cbl_inspect_oper_t( cbl_inspect_bound_t bound,
+                      const std::vector<cbl_inspect_match_t>& matches )
+    : bound(bound)
+    , matches(matches)
+    {}
 
-// One whole tally or substitution.  For REPLACING, nbound == 1
-template <typename DATA>
-struct cbx_inspect_t {
-  DATA tally;                 // identifier-2: NULL without a tally
-  size_t nbound;              // FOR and REPLACING start with a cbl_inspect_bound_t
-  cbx_inspect_oper_t<DATA> *opers;
-
-  cbx_inspect_t( const DATA& tally = DATA() )
-    : tally(tally)
-    , nbound(0)
-    , opers(NULL)
+  cbl_inspect_oper_t( cbl_inspect_bound_t bound,
+                      const std::vector<cbl_inspect_replace_t>& replaces )
+    : bound(bound)
+    , replaces(replaces)
     {}
-  cbx_inspect_t( const DATA& tally, const cbx_inspect_oper_t<DATA>& oper )
-    : tally(tally)
-    , nbound(1)
-    , opers(NULL)
-    {
-      this->opers = new cbx_inspect_oper_t<DATA>[1];
-      this->opers[0] = oper;
-    }
-  cbx_inspect_t( const DATA& tally,
-                 const std::list<cbx_inspect_oper_t<DATA>>& opers )
-    : tally(tally)
-    , nbound( opers.size() )
-    , opers(NULL)
-    {
-      this->opers = new cbx_inspect_oper_t<DATA>[nbound];
-      std::copy( opers.begin(), opers.end(), this->opers );
-    }
+
+  // N matches/replaces
+  size_t n_identifier_3() const {
+    return std::max( matches.size(), replaces.size() );
+  } 
+
+  bool is_valid() const { // only one or the other, never both
+    bool invalid = !matches.empty() && !replaces.empty();
+    return ! invalid;
+  }
 };
 
-typedef cbx_inspect_t<cbl_refer_t> cbl_inspect_t;
+// One whole tally or substitution.  For REPLACING, nbound == 1
+// FOR and REPLACING start with a cbl_inspect_bound_t
+struct cbl_inspect_t : public std::vector<cbl_inspect_oper_t> {
+  cbl_refer_t tally; // field is NULL for REPLACING
+  cbl_inspect_t() {}
+  cbl_inspect_t( size_t n, const cbl_inspect_oper_t& oper )
+    : std::vector<cbl_inspect_oper_t>(n, oper)
+  {}
+  cbl_inspect_t( const cbl_refer_t& tally,
+                 const std::vector<cbl_inspect_oper_t>& opers )
+    : std::vector<cbl_inspect_oper_t>(opers)
+    , tally(tally)
+    {}
+
+  size_t nbound() const { return size(); }
+};
 
+typedef std::vector<cbl_inspect_t> cbl_inspect_opers_t;
 
 /*
  * Runtime
  */
 
-void parser_inspect( cbl_refer_t input, bool backward,
-                     size_t ninspect, cbl_inspect_t *inspects );
+void parser_inspect( const cbl_refer_t& input,
+                     bool backward,
+                     cbl_inspect_opers_t& inspects );
+
 void parser_inspect_conv( cbl_refer_t input, bool backward,
                           cbl_refer_t original,
                           cbl_refer_t replacement,
index 13de5b6b6c241f82501c44024c3c4cd16d24b443..888cce159c448d4e3e694e3b270f6ffb41a5b25b 100644 (file)
@@ -123,7 +123,7 @@ continues_at( char *bol, char *eol ) {
 // Return pointer to indicator column. Test ch if provided.
 // NULL means no indicator column or tested value not present.
 static inline char *
-indicated( char *bol, char *eol, char ch = '\0' ) {
+indicated( char *bol, const char *eol, char ch = '\0' ) {
   if( indicator.column == 0 && *bol != '*' ) {
     return NULL;  // no indicator column in free format, except for comments
   }
@@ -140,10 +140,10 @@ indicated( char *bol, char *eol, char ch = '\0' ) {
 
 static char *
 remove_inline_comment( char *bol, char *eol ) {
-  static char ends = '\0';
   char *nl = std::find(bol, eol, '\n');
 
   if( bol < nl ) {
+    static char ends = '\0';
     std::swap(*nl, ends);
     char *comment = strstr(bol, "*>");
     if( comment ) {
@@ -208,10 +208,10 @@ maybe_add_space(const span_t& pattern, replace_t& recognized) {
   }
 
   if( befter[0] == blank || befter[1] == blank ) {
-    char *s = xasprintf( "%s%.*s%s",
-                         befter[0],
-                         recognized.after.size(), recognized.after.p,
-                         befter[1] );
+    const char *s = xasprintf( "%s%.*s%s",
+                               befter[0],
+                               recognized.after.size(), recognized.after.p,
+                               befter[1] );
     recognized.after = span_t(s, s + strlen(s));
   }
 }
@@ -266,7 +266,9 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem
 
       span_t found(mfile.eodata, mfile.eodata);
 
-      if( regex_search( mfile.ccur(), (const char *)mfile.eodata, cm, re) ) {
+      if( regex_search( mfile.ccur(),
+                        const_cast<const char *>(mfile.eodata),
+                        cm, re) ) {
         gcc_assert(cm[1].matched);
         found = span_t( cm[1].first, cm[1].second );
         if( yy_flex_debug ) {
@@ -301,7 +303,8 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem
     bol = next.found.pend;
 
     if( yy_flex_debug ) {
-      size_t n = std::count((const char *)mfile.data, recognized.before.p, '\n');
+      size_t n = std::count(const_cast<const char *>(mfile.data),
+                            recognized.before.p, '\n');
       dbgmsg( "%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED
               " @ " HOST_SIZE_T_PRINT_UNSIGNED ": '%s'\n/%.*s/%.*s/",
               __func__, __LINE__,
@@ -317,10 +320,11 @@ recognize_replacements( filespan_t mfile, std::list<replace_t>& pending_replacem
     next.found = span_t(mfile.eodata, mfile.eodata);
 
     regex re(next.directive.before.p, extended_icase);
-    if( regex_search(bol, (const char *)mfile.eodata, cm, re) ) {
+    if( regex_search(bol, const_cast<const char *>(mfile.eodata), cm, re) ) {
       gcc_assert(cm[1].matched);
       next.found = span_t( cm[1].first, cm[1].second );
-      size_t n = std::count((const char *)mfile.data, next.found.p, '\n');
+      size_t n = std::count(const_cast<const char *>(mfile.data),
+                            next.found.p, '\n');
       if( false )
         dbgmsg("%s:%d next '%.*s' will be on line " HOST_SIZE_T_PRINT_UNSIGNED
                " (offset " HOST_SIZE_T_PRINT_UNSIGNED ")", __func__, __LINE__,
@@ -345,7 +349,7 @@ check_source_format_directive( filespan_t& mfile ) {
 
   // show contents of marked subexpressions within each match
   cmatch cm;
-  if( regex_search(p, (const char *)mfile.eol, cm, re) ) {
+  if( regex_search(p, const_cast<const char *>(mfile.eol), cm, re) ) {
     gcc_assert(cm.size() > 1);
     switch( cm[3].length() ) {
     case 4:
@@ -459,9 +463,9 @@ struct replacing_term_t {
   bool matched, done;
   span_t leading_trailing, term, stmt;
 
-  replacing_term_t(const char input[]) : matched(false), done(false) {
-    stmt = span_t(input, input);
-  }
+  explicit replacing_term_t(const char input[])
+    : matched(false), done(false), stmt(span_t(input, input))
+    {}
 };
 
 extern YYLTYPE yylloc;
@@ -809,7 +813,7 @@ parse_replace_pairs( const char *stmt, const char *estmt, bool is_copy_stmt ) {
     }
 
     span_t& before(parsed.replace.before);
-    span_t& after(parsed.replace.after);
+    const span_t& after(parsed.replace.after);
 
     const char *befter[2] = { nonword_ch, nonword_ch };
     gcc_assert(before.p < before.pend);
@@ -877,7 +881,7 @@ struct copy_descr_t {
 };
 
 static YYLTYPE
-location_in( const filespan_t& mfile, const csub_match cm ) {
+location_in( const filespan_t& mfile, const csub_match& cm ) {
   YYLTYPE loc {
     int(mfile.lineno() + 1), int(mfile.colno() + 1),
     int(mfile.lineno() + 1), int(mfile.colno() + 1)
@@ -928,7 +932,7 @@ parse_copy_directive( filespan_t& mfile ) {
     copy_stmt.p = mfile.eodata;
 
     if( regex_search(mfile.ccur(),
-                          (const char *)mfile.eodata, cm, re) ) {
+                     const_cast<const char *>(mfile.eodata), cm, re) ) {
       copy_stmt = span_t( cm[0].first, cm[0].second );
       if( yy_flex_debug ) {
         size_t nnl = 1 + count_newlines(mfile.data, copy_stmt.p);
@@ -981,7 +985,7 @@ parse_copy_directive( filespan_t& mfile ) {
       std::pair<std::list<replace_t>, char*>
         result = parse_replace_pairs( cm[0].second, mfile.eodata, true );
 
-      std::list<replace_t>& replacements(result.first);
+      const std::list<replace_t>& replacements(result.first);
       outcome.parsed = (outcome.nreplace = replacements.size()) > 0;
       if( outcome.parsed ) {
         replace_directives.push(replacements);
@@ -1008,7 +1012,7 @@ parse_copy_directive( filespan_t& mfile ) {
 }
 
 static char *
-parse_replace_last_off( filespan_t& mfile ) {
+parse_replace_last_off( const filespan_t& mfile ) {
   static const char pattern[] =
     "REPLACE" "[[:space:]]+"
     "(LAST[[:space:]]+)?OFF[[:space:]]*[.]"
@@ -1018,7 +1022,7 @@ parse_replace_last_off( filespan_t& mfile ) {
 
   // REPLACE [LAST] OFF?
   bool found = regex_search(mfile.ccur(),
-                                 (const char *)mfile.eodata, cm, re);
+                            const_cast<const char *>(mfile.eodata), cm, re);
   gcc_assert(found); // caller ensures
 
   gcc_assert(cm.size() == 2);
@@ -1073,7 +1077,7 @@ parse_replace_text( filespan_t& mfile ) {
            (fmt_size_t)current_lineno, len, mfile.cur);
   }
 
-  if( ! regex_search(mfile.ccur(), (const char *)mfile.eodata, cm, re) ) {
+  if( ! regex_search(mfile.ccur(), mfile.eodata, cm, re) ) {
     dbgmsg( "%s:%d: line " HOST_SIZE_T_PRINT_UNSIGNED
             ": not a REPLACE statement:\n'%.*s'",
             __func__, __LINE__, (fmt_size_t)current_lineno,
@@ -1109,7 +1113,7 @@ parse_replace_text( filespan_t& mfile ) {
 
   std::pair<std::list<replace_t>, char*>
         result = parse_replace_pairs(replace_stmt.p, replace_stmt.pend, false);
-  std::list<replace_t>& replacements(result.first);
+  const std::list<replace_t>& replacements(result.first);
   replace_directives.push( replacements );
 
   if( yy_flex_debug ) {
@@ -1147,7 +1151,7 @@ parse_replace_directive( filespan_t& mfile ) {
     next_directive = mfile.eodata;
 
     if( regex_search(mfile.ccur(),
-                          (const char *)mfile.eodata, cm, re) ) {
+                     const_cast<const char *>(mfile.eodata), cm, re) ) {
       gcc_assert(cm[1].matched);
       next_directive = cm[0].first;
 
@@ -1491,7 +1495,7 @@ cdftext::lex_open( const char filename[] ) {
     argv[0] = filter;
 
     auto last_argv = std::transform( options.begin(), options.end(), argv.begin() + 1,
-                                     []( std::string& opt ) {
+                                     []( const std::string& opt ) {
                                        return xstrdup(opt.c_str());
                                      } );
     *last_argv = NULL;
@@ -1556,9 +1560,9 @@ cdftext::open_input( const char filename[] ) {
 int
 cdftext::open_output() {
   char *name = getenv("GCOBOL_TEMPDIR");
-  int fd;
 
   if( name && 0 != strcmp(name, "/") ) {
+    int fd;
     char * stem = xasprintf("%sXXXXXX", name);
     if( -1 == (fd = mkstemp(stem)) ) {
       cbl_err( "could not open temporary file '%s' (%s)",
@@ -1685,7 +1689,7 @@ cdftext::free_form_reference_format( int input ) {
     size_t lineno;
     bytespan_t line;
     // construct with length zero
-    current_line_t( char data[] ) : lineno(0), line(data, data) {}
+    explicit current_line_t( char data[] ) : lineno(0), line(data, data) {}
   } current( mfile.data );
 
   /*
@@ -1825,7 +1829,6 @@ cdftext::free_form_reference_format( int input ) {
 void
 cdftext::process_file( filespan_t mfile, int output, bool second_pass ) {
   static size_t nfiles = 0;
-  std::list<replace_t> replacements;
 
   __gnu_cxx::stdio_filebuf<char> outbuf(fdopen(output, "w"), std::ios::out);
   std::ostream out(&outbuf);
@@ -1890,34 +1893,12 @@ cdftext::process_file( filespan_t mfile, int output, bool second_pass ) {
       continue; // No active REPLACE directive.
     }
 
-    std::list<span_t> segments = segment_line(mfile); // no replace yields
-    //                                                // 1 segment
+    // 1 segment for COPY, 2 for REPLACE
+    std::list<span_t> segments = segment_line(mfile);
 
     for( const auto& segment : segments ) {
       std::copy(segment.p, segment.pend, ofs);
     }
-
-    if( segments.size() == 2 ) {
-      struct {
-        size_t before, after;
-        int delta() const { return before - after; } } nlines;
-      nlines.before = std::count(segments.front().p,
-                                 segments.front().pend, '\n');
-      nlines.after  = std::count(segments.back().p, segments.back().pend, '\n');
-      if( nlines.delta() < 0 ) {
-        yywarn("line %lu: REPLACED %lu lines with %lu lines, "
-              "line count off by %d",
-              gb4(mfile.lineno()),
-              gb4(nlines.before),
-              gb4(nlines.after),
-              nlines.delta());
-      }
-      int nnl = nlines.delta();
-      while( nnl-- > 0 ) {
-        static const char nl[] = "\n";
-        std::copy(nl, nl + 1, ofs);
-      }
-    }
     out.flush();
   }
   // end of file
index a7d2b7283cc1d0e1f223210b99c1042e93e8903a..96b365491ceaaf3e6f991003038c707123879875 100644 (file)
@@ -69,7 +69,9 @@ erase_source( char *src, char *esrc ) {
 struct bytespan_t {
   char *data, *eodata;
 
-  bytespan_t( char *data = NULL, char *eodata = NULL )
+  bytespan_t() : data( nullptr), eodata(nullptr) {}
+  
+  bytespan_t( char *data, char *eodata )
     : data(data), eodata(eodata)
   {
     if( eodata < data ) {
@@ -124,7 +126,7 @@ struct filespan_t : public bytespan_t {
   {}
   filespan_t(void *p, size_t len)
     : bytespan_t( static_cast<char*>(p), static_cast<char*>(p) + len )
-    , cur(data), eol(data), quote(NULL), iline(0), line_quote72(0)
+    , cur(data), eol(data), quote(NULL), iline(0), icol(0), line_quote72(0)
   {}
 
   size_t lineno() const { return iline; }
@@ -224,6 +226,7 @@ struct span_t {
   span_t( const char *data, const char *eodata ) : p(data), pend(eodata) {
     verify();
   }
+  // cppcheck-suppress operatorEqRetRefThis
   span_t& operator=( const csub_match& cm ) {
     p = cm.first;
     pend = cm.second;
@@ -246,8 +249,8 @@ struct span_t {
 
 struct replace_t {
   struct span_t before, after;
-  replace_t( span_t before = span_t(),
-             span_t after  = span_t() )
+  replace_t() : before(span_t()), after(span_t()) {}
+  replace_t( span_t before, span_t after )
     : before(before), after(after)
   {}
   replace_t& reset() {
index 719b94dbdc7c9fffa1c842a9b4561c2a2b98293d..3afa20ff5fdc4e030c459441c5f30342fc2ec269 100644 (file)
     data_category_t category;
     category_map_t replacement;
 
-    init_statement_t( category_map_t replacement )
+    explicit init_statement_t( const category_map_t& replacement )
       : to_value(false)
       , category(data_category_none)
       , replacement(replacement)
 
     {}
 
-    init_statement_t( bool to_value = false )
+    explicit init_statement_t( bool to_value = false )
       : to_value(to_value)
       , category(data_category_none)
       , replacement(category_map_t())
   struct Elem_list_t {
     std::list<E> elems;
     Elem_list_t() {}
-    Elem_list_t( E elem ) {
+    explicit Elem_list_t( E elem ) {
       elems.push_back(elem);
     }
     Elem_list_t * push_back( E elem ) {
 
 %type   <refer>         inspected
 %type   <insp_qual>     insp_qual
-%type   <insp_match>    insp_quals insp_mtquals tally_match
+%type   <insp_match>    insp_quals insp_mtqual tally_match
 %type   <insp_replace>  x_by_y
 %type   <insp_oper>     replace_oper x_by_ys
 %type   <insp_oper>     tally_forth tally_matches
     struct arith_t *arith;
     struct { size_t ntgt; cbl_num_result_t *tgts;
              cbl_refer_t *expr; } compute_body_t;
-    struct ast_inspect_t *insp_one;
-    struct ast_inspect_list_t *insp_all;
-    struct ast_inspect_oper_t *insp_oper;
+    struct cbl_inspect_t *insp_one;
+           cbl_inspect_opers_t *insp_all;
+    struct cbl_inspect_oper_t *insp_oper;
     struct { bool before; cbl_inspect_qual_t *qual; } insp_qual;
            cbl_inspect_t *inspect;
            cbl_inspect_match_t *insp_match;
     return ok;
   }
 
-  static void initialize_allocated( cbl_refer_t input );
+  static void initialize_allocated( const cbl_refer_t& input );
   static void
   initialize_statement( std::list<cbl_num_result_t>& tgts,
                         bool with_filler,
@@ -1949,7 +1949,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; }
                     if( $$.file->nkey++ == 0 ) {
                       // If no key yet exists, create room for it and the
                       // present alternate.
-                      assert($$.file->keys == &cbl_file_t::no_key);
+                      assert($$.file->keys == nullptr);
                       $$.file->keys = new cbl_file_key_t[++$$.file->nkey];
                     }
                     {
@@ -1961,8 +1961,7 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; }
                       // Assign the alternate key to the last element,
                       // and update the pointer.
                       *alt = $part.file->keys[0];
-                      delete[] $$.file->keys;
-                      $$.file->keys = keys;
+                      $$.file->keys_update(keys);
                     }
                     break;
                   case assign_clause_e:
@@ -2031,11 +2030,11 @@ select_clauses: select_clause { $$.clauses = $1.clause; $$.file = $1.file; }
                       YYERROR;
                     }
                     if( $$.file->nkey == 0 ) {
+                      assert( 1 == $part.file->nkey );
                       $$.file->nkey = $part.file->nkey;
-                      $$.file->keys = $part.file->keys;
-                    } else {
-                      $$.file->keys[0] = $part.file->keys[0];
-                    }
+                      $$.file->keys = new cbl_file_key_t[1];
+                    } 
+                    $$.file->keys[0] = $part.file->keys[0];
                     break;
                   /* case password_clause_e: */
                   case file_status_clause_e:
@@ -2391,7 +2390,7 @@ repo_program:   PROGRAM_kw NAME repo_as
                     assert(program);
                     prog.data.initial = program->name;
                   }
-                  auto e = symbol_field_add(PROGRAM, &prog);
+                  const auto e = symbol_field_add(PROGRAM, &prog);
                   symbol_field_location(symbol_index(e), @NAME);
                 }
                 ;
@@ -2593,7 +2592,8 @@ alphabet_seqs:  alphabet_seq[seq]
                     YYERROR;
                   }
                   $$->add_sequence(@seq, $seq.low);
-                  size_t len = $seq.low == nul_string()? 1 : strlen((const char*)$seq.low);
+                  size_t len = $seq.low == nul_string()?
+                    1 : strlen((const char*)$seq.low);
                   assert(len > 0);
                   $$->add_interval(@seq, $seq.low[--len], $seq.high[0]);
                   $$->add_sequence(@seq, $seq.high);
@@ -2652,11 +2652,13 @@ alphabet_etc:   alphabet_lit
                   $$ = (unsigned char)$1.data[0];
                 }
         |       spaces_etc {
-                  // For figurative constants, pass the synmbol table index,
+                  // For figurative constants, pass the symbol table index,
                   // marked with the high bit.
                   static const auto bits = sizeof($$) * 8 - 1;
-                  $$ = 1;
-                  $$ = $$ << bits;
+                  unsigned int high_bit = 1L << bits;
+                  static_assert(sizeof($$) == sizeof(high_bit),
+                                "adjust high_bit to match size of nonterminal target");
+                  memcpy(&$$, &high_bit, sizeof($$));
                   $$ |= constant_index($1);
                 }
                 ;
@@ -2830,7 +2832,7 @@ domain:         all LITERAL[a]
                   if( ! string_of($value) ) {
                     yywarn("'%s' has embedded NUL", $value.data);
                   }
-                  char *dom = $value.data;
+                  const char *dom = $value.data;
                   $$ = new cbl_domain_t(@value, false, $value.len, dom);
                 }
         |       when_set_to FALSE_kw is reserved_value
@@ -3290,9 +3292,9 @@ index_field1:   ctx_name[name]
 
                   auto symbol = symbol_field(PROGRAM, field.parent, $name);
                   if( symbol ) {
-                    auto field( cbl_field_of(symbol) );
+                    auto f( cbl_field_of(symbol) );
                     error_msg(@name,  "'%s' already defined on line %d",
-                              field->name, field->line );
+                              f->name, f->line );
                     YYERROR;
                   }
 
@@ -3385,7 +3387,7 @@ value78:        literalism
                 }
         |       reserved_value[value]
                 {
-                 auto field = constant_of(constant_index($value));
+                 const auto field = constant_of(constant_index($value));
                   $$ = new cbl_field_data_t(field->data);
                 }
 
@@ -3756,7 +3758,7 @@ data_descr1:    level_name
                   $field->report_invalid_initial_value(@data_clauses);
 
                   // verify REDEFINES
-                  auto parent = parent_of($field);
+                  const auto parent = parent_of($field);
                   if( parent && $field->level == parent->level ) {
                     valid_redefine(@field, $field, parent); // calls yyerror
                   }
@@ -4698,7 +4700,7 @@ same_clause:    SAME AS name
                     YYERROR;
                   }
 
-                  auto e = symbol_field_same_as( field, other );
+                  const auto e = symbol_field_same_as( field, other );
                   symbol_field_location( symbol_index(e), @name );
                 }
                 ;
@@ -4747,7 +4749,7 @@ type_clause: TYPE to typename
                 {
                   cbl_field_t *field = current_field();
                   if( $typename ) {
-                    auto e = symbol_field_same_as(field, $typename);
+                    const auto e = symbol_field_same_as(field, $typename);
                    symbol_field_location( symbol_index(e), @typename );
                   }
                 }
@@ -4759,7 +4761,7 @@ type_clause: TYPE to typename
                   }
                   cbl_field_t *field = current_field();
                   if( $typename ) {
-                    auto e = symbol_field_same_as(field, $typename);
+                    const auto e = symbol_field_same_as(field, $typename);
                    symbol_field_location( symbol_index(e), @typename );
                   }
                 }
@@ -5401,16 +5403,13 @@ name88:         NAME88 {
 
 scalar88:      name88 subscripts[subs] refmod[ref]
                 {
-                  size_t n = $subs->size();
-                  auto subscripts = new cbl_refer_t[n];
-                  $subs->use_list(subscripts);
                   if( $ref.from->is_reference() || $ref.len->is_reference() ) {
                     error_msg(@subs, "subscripts on start:len refmod "
                             "parameters are unsupported");
                     YYERROR;
                   }
                   cbl_span_t span( $ref.from, $ref.len );
-                  $$ = new cbl_refer_t($1, n, subscripts, span);
+                  $$ = new cbl_refer_t($1, $subs->vectorize(), span);
                 }
         |       name88 refmod[ref]
                 {
@@ -5439,7 +5438,7 @@ allocate:       ALLOCATE expr[size] CHARACTERS initialized RETURNING scalar[retu
                 {
                   statement_begin(@1, ALLOCATE);
                   if( $size->field->type == FldLiteralN ) {
-                   auto size = TREE_REAL_CST_PTR ($size->field->data.value_of());
+                   const auto size = TREE_REAL_CST_PTR ($size->field->data.value_of());
                     if( real_isneg(size) || real_iszero(size) ) {
                       error_msg(@size, "size must be greater than 0");
                       YYERROR;
@@ -5526,7 +5525,7 @@ display:        disp_body end_display
                    if( $1.vargs->args.size() != 1 ) {
                      error_msg(@1, "ARGUMENT-NUMBER can be set to only one value");
                    }
-                   cbl_refer_t& src( $1.vargs->args.front() );
+                  const  cbl_refer_t& src( $1.vargs->args.front() );
                    cbl_field_t *dst = register_find("_ARGI");
                    parser_move( dst, src );
                  } else {
@@ -5545,7 +5544,7 @@ display:        disp_body end_display
                    if( $1.vargs->args.size() != 1 ) {
                      error_msg(@1, "ARGUMENT-NUMBER can be set to only one value");
                    }
-                   cbl_refer_t& src( $1.vargs->args.front() );
+                  const cbl_refer_t& src( $1.vargs->args.front() );
                    cbl_field_t *dst = register_find("_ARGI");
                    parser_move( dst, src );
                  } else {
@@ -5705,7 +5704,7 @@ end_program:    end_program1[end] '.'
                   }
                   std::set<std::string> externals = current.end_program();
                   if( !externals.empty() ) {
-                   for( auto name : externals ) {
+                   for( const auto& name : externals ) {
                      yywarn("%s calls external symbol '%s'", prog->name, name.c_str());
                    }
                     YYERROR;
@@ -5800,7 +5799,7 @@ exit_with:      %empty
                    static cbl_refer_t status(rt);
                    $$ = &status;
                  }
-                 auto prog = cbl_label_of(symbol_at(current_program_index()));
+                 const auto prog = cbl_label_of(symbol_at(current_program_index()));
                  if( prog->returning ) {
                    $$ = new cbl_refer_t( cbl_field_of(symbol_at(prog->returning)) );
                  }
@@ -6489,7 +6488,7 @@ true_false:     TRUE_kw  { $$ = TRUE_kw; }
 
 scalar:         tableref {
                  // Check for missing subscript; others already checked.
-                  if( $1->nsubscript == 0 && 0 < dimensions($1->field) ) {
+                  if( $1->nsubscript() == 0 && 0 < dimensions($1->field) ) {
                     subscript_dimension_error(@1, 0, $$);
                   }
                }
@@ -6500,8 +6499,8 @@ tableref: tableish {
                  $$ = $1;
                  $$->loc = @1;
                  if( $$->is_table_reference() ) {
-                    if( $$->nsubscript != dimensions($$->field) ) {
-                      subscript_dimension_error(@1, $$->nsubscript, $$);
+                    if( $$->nsubscript() != dimensions($$->field) ) {
+                      subscript_dimension_error(@1, $$->nsubscript(), $$);
                      YYERROR;
                    }
                  }
@@ -7173,7 +7172,7 @@ section_kw:     SECTION
                     } else {
                      if( dialect_ibm() ) {
                        int sectno;
-                       sscanf($1, "%u", &sectno);
+                       sscanf($1, "%d", &sectno);
                        if( ! (0 <= sectno && sectno <= 99) ) {
                          error_msg(@1, "SECTION segment %<%s%> must be 0-99", $1);
                        } else {
@@ -7593,7 +7592,7 @@ perform_when1:    WHEN perform_ec {
                  std::transform( $perform_ec->elems.begin(),
                                  $perform_ec->elems.end(),
                                  std::back_inserter(perf->dcls),
-                                 []( cbl_declarative_t *p ) {
+                                 []( const cbl_declarative_t *p ) {
                                    return *p;
                                  } );
                  ast_enter_paragraph(when);
@@ -7683,12 +7682,12 @@ except_files:   except_name[ec] FILE_KW filenames {
 
 perform_ec_other:
                %empty %prec WHEN {
-                 auto& ec_labels( perform_current()->ec_labels );
+                  const auto& ec_labels( perform_current()->ec_labels );
                  ast_enter_paragraph(ec_labels.other);
                  parser_exit_paragraph();
                }
        |       WHEN OTHER {
-                 auto& ec_labels( perform_current()->ec_labels );
+                  const auto& ec_labels( perform_current()->ec_labels );
                  ast_enter_paragraph(ec_labels.other);
                }
                exception statements %prec WHEN {
@@ -7697,12 +7696,12 @@ perform_ec_other:
                ;
 perform_ec_common:
                %empty {
-                 auto& ec_labels( perform_current()->ec_labels );
+                 const auto& ec_labels( perform_current()->ec_labels );
                  ast_enter_paragraph(ec_labels.common);
                  parser_exit_paragraph();
                }
        |       WHEN COMMON {
-                 auto& ec_labels( perform_current()->ec_labels );
+                 const auto& ec_labels( perform_current()->ec_labels );
                  ast_enter_paragraph(ec_labels.common);
                }
                exception statements {
@@ -7711,18 +7710,18 @@ perform_ec_common:
                ;
 perform_ec_finally:
                %empty {
-                 auto& ec_labels( perform_current()->ec_labels );
+                 const auto& ec_labels( perform_current()->ec_labels );
                  ast_enter_paragraph(ec_labels.finally);
                  parser_exit_paragraph();
                  parser_label_goto(ec_labels.fini);
                }
        |       FINALLY {
-                 auto& ec_labels( perform_current()->ec_labels );
+                 const auto& ec_labels( perform_current()->ec_labels );
                  ast_enter_paragraph(ec_labels.finally);
                }
                exception statements {
                  parser_exit_paragraph();
-                 auto& ec_labels( perform_current()->ec_labels );
+                 const auto& ec_labels( perform_current()->ec_labels );
                  parser_label_goto(ec_labels.fini);
                }
                ;
@@ -8000,10 +7999,6 @@ read_body:      NAME read_next read_into read_key
                     error_msg(@1, "syntax error? invalid file record name");
                     YYERROR;
                   }
-                  if( 0 && $$->access == file_access_dyn_e && $read_next >= 0 ) {
-                    error_msg(@1, "sequential DYNAMIC access requires NEXT RECORD");
-                    YYERROR;
-                  }
                   if( $read_key->field && is_sequential($$) ) {
                     error_msg(@1, "SEQUENTIAL file %s has no KEY", $$->name);
                     YYERROR;
@@ -8451,8 +8446,8 @@ merge:          MERGE { statement_begin(@1, MERGE); }
                   USING filenames[inputs] sort_output
                 {
                   std::vector <cbl_key_t> keys($sort_keys->key_list.size());
-                 std::copy( $sort_keys->key_list.begin(),
-                            $sort_keys->key_list.end(), keys.begin() );
+                  std::copy( $sort_keys->key_list.begin(),
+                             $sort_keys->key_list.end(), keys.begin() );
 
                   size_t ninput = $inputs->files.size();
                   size_t noutput = $sort_output->nfile();
@@ -8471,8 +8466,7 @@ merge:          MERGE { statement_begin(@1, MERGE); }
                     out_proc = &$sort_output->tgt;
                   }
 
-                  parser_file_merge( $file, $sort_seq,
-                                     keys.size(), keys.empty()? NULL : keys.data(),
+                  parser_file_merge( $file, $sort_seq, keys, 
                                      ninput, inputs,
                                      noutput, outputs,
                                      out_proc );
@@ -8638,7 +8632,7 @@ set:            SET set_tgts[tgts] TO set_operand[src]
                   class set_conditional {
                     bool tf;
                    public:
-                    set_conditional( int token ) : tf(token == TRUE_kw) {}
+                    explicit set_conditional( int token ) : tf(token == TRUE_kw) {}
                     void operator()(cbl_refer_t& refer) {
                       if( refer.field->data.false_value_of() == NULL && !tf ) {
                        auto loc = symbol_field_location(field_index(refer.field));
@@ -8663,7 +8657,7 @@ set_switches:   switches TO on_off
                 {
                   struct switcheroo {
                     bitop_t op;
-                    switcheroo( bool tf ) : op( tf? bit_set_op : bit_clear_op ) {}
+                    explicit switcheroo( bool tf ) : op( tf? bit_set_op : bit_clear_op ) {}
                     switcheroo& operator()(cbl_field_t* sw) {
                       assert(sw->type == FldSwitch);
                       assert(sw->data.initial); // not a switch condition
@@ -8803,14 +8797,14 @@ search_terms:   search_term
                 ;
 search_term:    scalar[key] '=' search_expr[sarg]
                 {
-                  if( $key->nsubscript == 0 ) {
+                  if( $key->nsubscript() == 0 ) {
                     error_msg(@1, "no index for key");
                     YYERROR;
                   }
-                  if( dimensions($key->field) < $key->nsubscript ) {
+                  if( dimensions($key->field) < $key->nsubscript() ) {
                     error_msg(@1, "too many subscripts: "
                               "%zu for table of %zu dimensions",
-                              $key->nsubscript, dimensions($key->field) );
+                              $key->nsubscript(), dimensions($key->field) );
                     YYERROR;
                   }
 
@@ -8849,8 +8843,7 @@ sort_table:     SORT tableref[table] sort_keys sort_dup sort_seq {
                     keys.at(i++) = cbl_key_t(k);
                   }
 
-                  parser_sort( *$table, $sort_dup, $sort_seq,
-                              keys.size(), keys.empty()? NULL : keys.data() );
+                  parser_sort( *$table, $sort_dup, $sort_seq, keys );
                 }
         |       SORT tableref[table] sort_dup sort_seq {
                   statement_begin(@1, SORT);
@@ -8860,9 +8853,10 @@ sort_table:     SORT tableref[table] sort_keys sort_dup sort_seq {
                   cbl_key_t
                     key = cbl_key_t($table->field->occurs.keys[0]),
                     guess(1, &$table->field);
-                  ;
-                  if( key.nfield == 0 ) key = guess;
-                  parser_sort( *$table, $sort_dup, $sort_seq, 1, &key );
+                  
+                  if( key.fields.empty() ) key = guess;
+                  std::vector<cbl_key_t> keys(1, key);
+                  parser_sort( *$table, $sort_dup, $sort_seq, keys );
                 }
                 ;
 
@@ -8903,7 +8897,7 @@ sort_file:      SORT FILENAME[file] sort_keys  sort_dup    sort_seq
                   parser_file_sort( file,
                                     $sort_dup,
                                     $sort_seq,
-                                    keys.size(), keys.empty()? NULL : keys.data(),
+                                    keys
                                     ninput, inputs,
                                     noutput, outputs,
                                     in_proc, out_proc );
@@ -9095,7 +9089,7 @@ backward: %empty   { $$ = false; }
 inspect:        INSPECT backward inspected TALLYING tallies
                 {
                   statement_begin(@1, INSPECT);
-                  ast_inspect( *$inspected, $backward, *$tallies );
+                  ast_inspect( @$, *$inspected, $backward, *$tallies );
                 }
         |       INSPECT backward inspected TALLYING tallies REPLACING replacements
                 {
@@ -9107,8 +9101,8 @@ inspect:        INSPECT backward inspected TALLYING tallies
                   }
                   statement_begin(@1, INSPECT);
                   // All tallying is done before any replacing
-                  ast_inspect( *$inspected, $backward, *$tallies );
-                  ast_inspect( *$inspected, $backward, *$replacements );
+                  ast_inspect( @$, *$inspected, $backward, *$tallies );
+                  ast_inspect( @$, *$inspected, $backward, *$replacements );
                 }
         |       INSPECT backward inspected                  REPLACING replacements
                 {
@@ -9119,11 +9113,11 @@ inspect:        INSPECT backward inspected TALLYING tallies
                     YYERROR;
                   }
                   statement_begin(@1, INSPECT);
-                  ast_inspect( *$inspected, $backward, *$replacements );
+                  ast_inspect( @$, *$inspected, $backward, *$replacements );
                 }
         |       INSPECT backward inspected CONVERTING alpha_val[match]
                                   TO  all    alpha_val[replace_oper]
-                                             insp_mtquals[qual]
+                                             insp_mtqual[qual]
                 {
                  if( $all ) {
                    $replace_oper->all = true;
@@ -9169,7 +9163,7 @@ inspect:        INSPECT backward inspected TALLYING tallies
 
 tallies:        { need_nume_set(); } tally
                 {
-                  $$ = new ast_inspect_list_t( *$tally );
+                  $$ = new cbl_inspect_opers_t( 1, *$tally );
                 }
         |       tallies { need_nume_set(); } tally
                 {
@@ -9179,12 +9173,17 @@ tallies:        { need_nume_set(); } tally
                   if( !next.tally.field ) {
                     // prior tally swallowed one too many
                     cbl_inspect_t& prior = $$->back();
-                    assert(prior.nbound > 0);
-                    assert(prior.opers);
-                    cbl_inspect_oper_t& prior_op = prior.opers[prior.nbound - 1];
-
-                    assert(prior_op.n_identifier_3 > 0 );
-                    next.tally = prior_op.matches[--prior_op.n_identifier_3].matching;
+                    assert(prior.nbound() > 0);
+                    cbl_inspect_oper_t& prior_op = prior.back();
+                    assert(! prior_op.matches.empty() );
+                    assert(prior_op.n_identifier_3() > 0 );
+                    cbl_inspect_match_t wrong_match = prior_op.matches.back();
+                    dbgmsg("moving overeager tally to next clause");
+                    dump_inspect_match(wrong_match);
+                    next.tally = wrong_match.premature_tally();
+                    if( wrong_match.empty() ) {
+                      prior_op.matches.pop_back();
+                    }
                   }
                   if( !next.tally.field ) {
                     error_msg(@$, "missing summation field before FOR");
@@ -9196,44 +9195,37 @@ tallies:        { need_nume_set(); } tally
 
                 /*
                  * numref might be "empty" only because it was consumed by a
-                 * prior insp_mtquals, which can end in a scalar. If that
+                 * prior insp_mtqual, which can end in a scalar. If that
                  * happens, the tallies target, above, takes back the borrowed
                  * scalar and assigns it to be the tally total, as the user
                  * intended.
                  */
 tally:          numeref[total] FOR tally_fors[fors]
-                { // reduce ast_inspect_t to cbl_inspect_t
+                { 
                   if( yydebug && !$total ) {
-                    error_msg(@FOR, "caution: missing summation field before FOR");
+                    dbgmsg("tally: caution: missing summation field before FOR");
                   }
-                  cbl_refer_t total( $total? *$total : cbl_refer_t() );
-                  $$ = new cbl_inspect_t( total, $fors->opers() );
+                  $$ = $fors;
+                  if( $total ) $$->tally = *$total;
                 }
                 ;
 
-tally_fors:     tally_forth
-                { // reduce ast_inspect_oper_t to cbl_inspect_oper_t
-                  cbl_inspect_oper_t oper( $1->bound, $1->matches );
-                  $$ = new ast_inspect_t;
-                  $$ ->push_back(oper);
-                }
-        |       tally_fors tally_forth
-                {
-                  cbl_inspect_oper_t oper( $2->bound, $2->matches );
-                  $1 ->push_back(oper);
-                }
+tally_fors:     tally_forth { $$ = new cbl_inspect_t(1, *$1); }
+        |       tally_fors tally_forth { $$->push_back(*$2); $$ = $1; }
                 ;
 
-tally_forth:    CHARACTERS insp_mtquals[q] scalar[next_tally]
+tally_forth:    CHARACTERS insp_mtqual[q] scalar[next_tally]
                 {
                   // Add ensuing scalar as if it were an argument to CHARACTERS.
                   // It will be moved to the succeeding FOR as its tally.
-                  $q->matching = *$next_tally;
-                  $$ = new ast_inspect_oper_t(*$q);
+                  dbgmsg("saving overeager tally for next clause");
+                  $q->save_premature_tally(*$next_tally);
+                  $$ = new cbl_inspect_oper_t(*$q);
+                  dump_inspect_match($$->matches.back());
                 }
-        |       CHARACTERS insp_mtquals[q]
+        |       CHARACTERS insp_mtqual[q]
                 {
-                  $$ = new ast_inspect_oper_t(*$q);
+                  $$ = new cbl_inspect_oper_t(*$q);
                 }
         |       ALL tally_matches[q]
                 { $q->bound = bound_all_e;
@@ -9252,26 +9244,23 @@ tally_forth:    CHARACTERS insp_mtquals[q] scalar[next_tally]
                 }
                 ;
 
-tally_matches:  tally_match { $$ = new ast_inspect_oper_t(*$1); }
+tally_matches:  tally_match { $$ = new cbl_inspect_oper_t(*$1); }
         |       tally_matches tally_match
                 { // add to the list of matches for an operand
                   $1->matches.push_back(*$2);
                 }
                 ;
-tally_match:    alpha_val[matching] insp_mtquals[q]
+tally_match:    alpha_val[matching] insp_mtqual[q]
                 { // include the matching field with the qualifiers
                   $$ = $q;
-                  $$->matching = *$matching;
+                  $$->matching(*$matching);
                 }
                 ;
 
 numeref:        %empty { $$ = NULL; need_nume_set(false); }
         |       nume[name] subscripts[subs]
                 {
-                  size_t n = $subs->size();
-                  auto offsets = new cbl_refer_t[n];
-                  std::copy( $subs->begin(), $subs->end(), offsets );
-                  $$ = new cbl_refer_t($name, n, offsets);
+                  $$ = new cbl_refer_t($name, $subs->vectorize());
                 }
         |       nume { $$ = new cbl_refer_t($nume); }
                 ;
@@ -9301,13 +9290,13 @@ qnume:          NUME            { name_queue.qualify(@1, $1); }
 
 replacements:   replacement
                 {
-                  cbl_inspect_t inspect( cbl_refer_t(), $1->opers() );
-                  $$ = new ast_inspect_list_t(inspect);
+                  cbl_inspect_t inspect( cbl_refer_t(), *$1 );
+                  $$ = new cbl_inspect_opers_t(1, inspect);
                 }
                 ;
 replacement:    replace_oper
                 {
-                  $$ = new ast_inspect_t;
+                  $$ = new cbl_inspect_t;
                   $$->push_back( cbl_inspect_oper_t($1->bound, $1->replaces) );
                 }
         |       replacement replace_oper
@@ -9315,9 +9304,9 @@ replacement:    replace_oper
                   $$->push_back( cbl_inspect_oper_t($2->bound, $2->replaces)  );
                 }
                 ;
-replace_oper:   CHARACTERS BY alpha_val[replace] insp_mtquals[q]
+replace_oper:   CHARACTERS BY alpha_val[replace] insp_mtqual[q]
                 {
-                  $$ = new ast_inspect_oper_t( cbl_inspect_replace_t(NULL,
+                  $$ = new cbl_inspect_oper_t( cbl_inspect_replace_t(NULL,
                                                                      *$replace,
                                                                      $q->before,
                                                                      $q->after) );
@@ -9331,21 +9320,22 @@ replace_oper:   CHARACTERS BY alpha_val[replace] insp_mtquals[q]
 
 x_by_ys:        x_by_y
                 {
-                  $$ = new ast_inspect_oper_t(*$1);
+                  $$ = new cbl_inspect_oper_t(*$1);
                 }
         |       x_by_ys x_by_y
                 {
                   $$->replaces.push_back(*$2);
                 }
                 ;
-x_by_y:         alpha_val[matching] BY alpha_val[replace] insp_mtquals[q]
+x_by_y:         alpha_val[matching] BY alpha_val[replace] insp_mtqual[q]
                 {
                   $$ = new cbl_inspect_replace_t(*$matching, *$replace,
                                                    $q->before, $q->after);
                 }
                 ;
 
-insp_mtquals:   %empty     { $$ = new cbl_inspect_match_t; }
+               /* mt may be "empty": match may have no qualifiers */
+insp_mtqual:   %empty { $$ = new cbl_inspect_match_t; }
         |       insp_quals
                 ;
 insp_quals:     insp_qual  {
@@ -9355,6 +9345,7 @@ insp_quals:     insp_qual  {
                   } else {
                     $$->after = *$insp_qual.qual;
                   }
+                  dump_inspect_match(*$$);
                 }
         |       insp_quals insp_qual
                 {
@@ -9774,7 +9765,7 @@ alter_tgt:      label_1[old] alter_to label_1[new]
                   cbl_perform_tgt_t tgt( $old, $new );
                   parser_alter(&tgt);
 
-                  auto prog = cbl_label_of( symbol_at(symbol_elem_of($old)->program));
+                  const auto prog = cbl_label_of( symbol_at(symbol_elem_of($old)->program));
                   if( prog->initial ) {
                     cbl_unimplemented("ALTER %s", $old->name);
                   }
@@ -10172,7 +10163,7 @@ function_udf:   FUNCTION_UDF '(' arg_list[args] ')' {
                  size_t i = 0;
                  // Pass parameters as defined by the function.
                   std::transform( $args->refers.begin(), $args->refers.end(), args.begin(),
-                                 [params, &i]( cbl_refer_t& arg ) {
+                                 [params, &i]( const cbl_refer_t& arg ) {
                                    function_descr_arg_t param = params.at(i++);
                                    auto ar = new cbl_refer_t(arg);
                                    cbl_ffi_arg_t actual(param.crv, ar);
@@ -11315,7 +11306,7 @@ first_line_of( YYLTYPE loc ) {
     return loc;
 }
 
-void ast_call( const YYLTYPE& loc, cbl_refer_t name, cbl_refer_t returning,
+void ast_call( const YYLTYPE& loc, cbl_refer_t name, const cbl_refer_t& returning,
                   size_t narg, cbl_ffi_arg_t args[],
                   cbl_label_t *except,
                   cbl_label_t *not_except,
@@ -11407,7 +11398,7 @@ statement_begin( const YYLTYPE& loc, int token ) {
 
 struct string_match {
   const char *name;
-  string_match( const char name[] ) : name(name) {}
+  explicit string_match( const char name[] ) : name(name) {}
   bool operator()( const char input[] ) const {
     return strlen(name) == strlen(input) && 0 == strcasecmp(name, input);
   }
@@ -11415,9 +11406,13 @@ struct string_match {
 
 const char *
 keyword_str( int token ) {
-  if( token == YYEOF )   return "YYEOF";
-  if( token == YYEMPTY ) return "YYEMPTY";
-
+  switch( token ) {
+  case YYEOF:   return "YYEOF";
+  case YYEMPTY: return "YYEMPTY";
+  case YYerror: return "YYerror";
+  case YYUNDEF: return "invalid token";
+  }
+  
   if( token < 256 ) {
     static char ascii[2];
     ascii[0] = token;
@@ -11461,9 +11456,9 @@ tokenset_t::find( const cbl_name_t name, bool include_intrinsics ) {
   if( dialect_ibm() ) {
       static const cbl_name_t ibm_non_names[] = {
          "RESUME",
-      }, * const eonames = ibm_non_names + COUNT_OF(ibm_non_names);
+      }, * const eoibm = ibm_non_names + COUNT_OF(ibm_non_names);
 
-      if( std::any_of(ibm_non_names, eonames,
+      if( std::any_of(ibm_non_names, eoibm,
                      [candidate=name](const cbl_name_t non_name) {
                          return 0 == strcasecmp(non_name, candidate)
                              && strlen(non_name) == strlen(candidate);
@@ -11500,7 +11495,7 @@ keyword_tok( const char * text, bool include_intrinsics ) {
 
 static inline size_t
 verify_figconst( enum cbl_figconst_t figconst , size_t pos ) {
-  cbl_field_t *f = cbl_field_of(symbol_at(pos));
+  const cbl_field_t *f = cbl_field_of(symbol_at(pos));
   assert((f->attr & FIGCONST_MASK) == figconst);
   return pos;
 }
@@ -11792,7 +11787,7 @@ current_t::udf_update( const ffi_args_t *ffi_args ) {
   if( ! ffi_args ) return;
   assert(ffi_args->elems.size() < sizeof(function_descr_t::types));
 
-  auto returning = cbl_field_of(symbol_at(L->returning));
+  const auto returning = cbl_field_of(symbol_at(L->returning));
   auto key = function_descr_t::init(L->name);
   auto func = udfs.find(key);
   assert(func != udfs.end());
@@ -11834,7 +11829,7 @@ current_t::udf_args_valid( const cbl_label_t *L,
   }
 
   size_t i = 0;
-  for( cbl_refer_t arg : args ) {
+  for( const cbl_refer_t& arg : args ) {
     if( arg.field ) { // else omitted
       auto tgt = cbl_field_of(symbol_at(udf.linkage_fields.at(i).isym));
       if( ! valid_move(tgt, arg.field) ) {
@@ -11891,7 +11886,7 @@ function_descr_t
 function_descr_t::init( int isym ) {
   function_descr_t descr = { FUNCTION_UDF_0 };
   descr.ret_type = FldInvalid;
-  auto L = cbl_label_of(symbol_at(isym));
+  const auto L = cbl_label_of(symbol_at(isym));
   bool ok = namcpy(YYLTYPE(), descr.name, L->name);
   gcc_assert(ok);
   return descr;
@@ -11905,16 +11900,16 @@ arith_t::arith_t( cbl_arith_format_t format, refer_list_t * refers )
   delete refers;
 }
 
-
-cbl_key_t::cbl_key_t( const sort_key_t& that )
+cbl_key_t::cbl_key_t( sort_key_t that )
   : ascending(that.ascending)
-  , nfield(that.fields.size())
-  , fields(NULL)
-{
-  if( nfield > 0 ) {
-    fields = new cbl_field_t* [nfield];
-    std::copy(that.fields.begin(), that.fields.end(), fields);
-  }
+  , fields( that.fields.begin(), that.fields.end() )
+{}
+
+cbl_key_t&
+cbl_key_t::operator=( const sort_key_t& that ) {
+  ascending = that.ascending;
+  fields = that.as_vector();
+  return *this;
 }
 
 static cbl_refer_t *
@@ -12020,10 +12015,10 @@ ast_divide( arith_t *arith ) {
  * the convenience of the parser.
 */
 struct stringify_src_t : public cbl_string_src_t {
- stringify_src_t( const refer_marked_list_t& marked = refer_marked_list_t() )
-   : cbl_string_src_t( marked.marker? *marked.marker : null_reference,
-                       marked.refers.size(),
-                       new cbl_refer_t[marked.refers.size()] )
 stringify_src_t( const refer_marked_list_t& marked = refer_marked_list_t() )
+    : cbl_string_src_t( marked.marker? *marked.marker : null_reference,
+                        marked.refers.size(),
+                        new cbl_refer_t[marked.refers.size()] )
   {
     std::copy( marked.refers.begin(), marked.refers.end(), inputs );
   }
@@ -12043,7 +12038,7 @@ struct stringify_src_t : public cbl_string_src_t {
 
 void
 stringify( refer_collection_t *inputs,
-           cbl_refer_t into, cbl_refer_t pointer,
+           const cbl_refer_t& into, const cbl_refer_t& pointer,
            cbl_label_t  *on_error,
            cbl_label_t *not_error )
 {
@@ -12058,7 +12053,7 @@ stringify( refer_collection_t *inputs,
 }
 
 void
-unstringify( cbl_refer_t& src,
+unstringify( const cbl_refer_t& src,
              refer_list_t *delimited,
              unstring_into_t * into,
              cbl_label_t  *on_error,
@@ -12066,6 +12061,7 @@ unstringify( cbl_refer_t& src,
 {
   size_t ndelimited = delimited? delimited->size() : 0;
   cbl_refer_t *pdelimited = NULL;
+  // cppcheck-suppress [variableScope] pdelimited points to delimiteds.data()
   std::vector <cbl_refer_t> delimiteds(ndelimited);
   if( ndelimited > 0 ) {
     pdelimited = use_any( delimited->refers, delimiteds );
@@ -12177,15 +12173,19 @@ lang_check_failed (const char* file, int line, const char* function) {}
 
 #pragma GCC diagnostic pop
 
-void ast_inspect( cbl_refer_t& input, bool backward, ast_inspect_list_t& inspects ) {
+void
+ast_inspect( YYLTYPE loc, cbl_refer_t& input, bool backward,
+             cbl_inspect_opers_t& inspects )
+{
   if( yydebug ) {
-    dbgmsg("%s:%d: INSPECT " HOST_SIZE_T_PRINT_UNSIGNED " operations on %s, line %d",
-          __func__, __LINE__, (fmt_size_t)inspects.size(), input.field->name, yylineno);
+    dbgmsg("%s:%d: INSPECT " HOST_SIZE_T_PRINT_UNSIGNED " operations on %s, "
+           "lines %d:%d - %d:%d",
+           __func__, __LINE__,
+           (fmt_size_t)inspects.size(), input.field->name,
+           loc.first_line, loc.first_column, loc.last_line, loc.last_column );
   }
   std::for_each(inspects.begin(), inspects.end(), dump_inspect);
-  auto array = inspects.as_array();
-  parser_inspect( input, backward, inspects.size(), array );
-  delete[] array;
+  parser_inspect( input, backward, inspects );
 }
 
 static const char *
@@ -12197,28 +12197,29 @@ cbl_refer_str( char output[], const cbl_refer_t& R ) {
   return output;
 }
 
-static void
+void
 dump_inspect_match( const cbl_inspect_match_t& M ) {
-  static char fields[3][4 * 64];
-  cbl_refer_str(fields[0], M.matching);
-  cbl_refer_str(fields[1], M.before.identifier_4);
-  cbl_refer_str(fields[2], M.after.identifier_4);
-
-  yywarn( "matching %s \n\t\tbefore %s%s \n\t\tafter  %s%s",
-         fields[0],
-         M.before.initial? "initial " : "", fields[1],
-         M.after.initial?  "initial " : "", fields[2] );
+  static char fields[4][4 * 64];
+  cbl_refer_str(fields[0], M.match);
+  cbl_refer_str(fields[1], M.tally);
+  cbl_refer_str(fields[2], M.before.identifier_4);
+  cbl_refer_str(fields[3], M.after.identifier_4);
+
+  dbgmsg( "matching %s [tally %s]\n\t\tbefore %s%s \n\t\tafter  %s%s",
+         fields[0], fields[1],
+         M.before.initial? "initial " : "", fields[2],
+         M.after.initial?  "initial " : "", fields[3] );
 }
 
 static void
 dump_inspect_replace( const cbl_inspect_replace_t& R ) {
   static char fields[4][4 * 64];
-  cbl_refer_str(fields[0], R.matching);
+  cbl_refer_str(fields[0], R.matching());
   cbl_refer_str(fields[1], R.before.identifier_4);
   cbl_refer_str(fields[2], R.after.identifier_4);
   cbl_refer_str(fields[3], R.replacement);
 
-  yywarn( "matching    %s \n\treplacement %s\n\t\tbefore %s%s \n\t\tafter  %s%s",
+  dbgmsg( "matching    %s \n\treplacement %s\n\t\tbefore %s%s \n\t\tafter  %s%s",
          fields[0], fields[3],
          R.before.initial? "initial " : "", fields[1],
          R.after.initial?  "initial " : "", fields[2] );
@@ -12334,7 +12335,7 @@ numstr2i( const char input[], radix_t radix ) {
     break;
   case hexadecimal_e:
     erc = sscanf(input, "%" GCC_PRISZ "x", &integerf);
-    integer = integer;
+    integer = integerf;
     real_from_integer (&output, VOIDmode, integer, UNSIGNED);
     break;
   case boolean_e:
@@ -12384,7 +12385,7 @@ new_literal( const char initial[], enum radix_t radix ) {
 class is_elementary_type { // for INITIALIZE purposes
   bool with_filler;
 public:
-  is_elementary_type( bool with_filler ) : with_filler(with_filler) {}
+  explicit is_elementary_type( bool with_filler ) : with_filler(with_filler) {}
 
   bool operator()( const symbol_elem_t& elem ) const {
     if( elem.type != SymField ) return false;
@@ -12398,7 +12399,7 @@ public:
 size_t end_of_group( size_t igroup );
 
 static std::list<cbl_refer_t>
-symbol_group_data_members( cbl_refer_t refer, bool with_filler ) {
+symbol_group_data_members( const cbl_refer_t& refer, bool with_filler ) {
   std::list<cbl_refer_t> refers;
   refers.push_front( refer );
 
@@ -12406,7 +12407,7 @@ symbol_group_data_members( cbl_refer_t refer, bool with_filler ) {
 
   class refer_of : public cbl_refer_t {
    public:
-    refer_of( const cbl_refer_t& refer ) : cbl_refer_t(refer) {}
+    explicit refer_of( const cbl_refer_t& refer ) : cbl_refer_t(refer) {}
     cbl_refer_t operator()( symbol_elem_t& elem ) {
       this->field = cbl_field_of(&elem); // preserve subscript/refmod
       return *this;
@@ -12430,7 +12431,7 @@ struct expand_group : public std::list<cbl_refer_t> {
     return cbl_refer_t(field);
   }
   bool with_filler;
-  expand_group( bool with_filler ) : with_filler(with_filler) {}
+  explicit expand_group( bool with_filler ) : with_filler(with_filler) {}
 
   void operator()( const cbl_refer_t& refer ) {
     assert(refer.field);
@@ -12456,7 +12457,7 @@ wsclear( char ch ) {
 }
 
 static void
-initialize_allocated( cbl_refer_t input ) {
+initialize_allocated( const cbl_refer_t& input ) {
   cbl_num_result_t result = { truncation_e, input };
   std::list<cbl_num_result_t> results;
   results.push_back(result);
@@ -12465,13 +12466,14 @@ initialize_allocated( cbl_refer_t input ) {
 }
 
 static int
-initialize_with( cbl_refer_t tgt ) {
+initialize_with( const cbl_refer_t& tgt ) {
   if( tgt.field->type == FldPointer ) return ZERO;
   if( tgt.is_refmod_reference() ) return SPACES;
   return is_numeric(tgt.field)? ZERO : SPACES;
 }
 
 static bool
+// cppcheck-suppress [passedByValue] target.refer.field is modified
 initialize_one( cbl_num_result_t target, bool with_filler,
                 data_category_t value_category,
                 const category_map_t& replacements,
@@ -12541,11 +12543,11 @@ typedef std::pair<size_t, size_t>  cbl_bytespan_t;
  * After the 1st record is initialized, copy it to the others.
  */
 static bool
-initialize_table( cbl_num_result_t target,
+initialize_table( const cbl_num_result_t& target,
                  size_t nspan, const cbl_bytespan_t spans[],
                  const std::list<cbl_subtable_t>& subtables )
 {
-  assert( target.refer.nsubscript == dimensions(target.refer.field) );
+  assert( target.refer.nsubscript() == dimensions(target.refer.field) );
   const cbl_refer_t& src( target.refer );
   size_t n( src.field->occurs.ntimes());
   assert( 0 < n );
@@ -12561,17 +12563,17 @@ static cbl_refer_t
 synthesize_table_refer( cbl_refer_t tgt ) {
   // For a table, use supplied subscripts or start with 1.
   auto ndim( dimensions(tgt.field) );
-  if( tgt.nsubscript < ndim ) { // it's an incomplete table
+  if( tgt.nsubscript() < ndim ) { // it's an incomplete table
     std::vector <cbl_refer_t> subscripts(ndim);
     for( size_t i=0; i < ndim; i++ ) {
-      if( i < tgt.nsubscript ) {
+      if( i < tgt.nsubscript() ) {
        subscripts[i] = tgt.subscripts[i];
        continue;
       }
       subscripts[i].field = new_tempnumeric();
       parser_set_numeric(subscripts[i].field, 1);
     }
-    return cbl_refer_t( tgt.field, subscripts.size(), subscripts.data() );
+    return cbl_refer_t( tgt.field, subscripts );
   }
   return tgt;
 }
@@ -12581,7 +12583,7 @@ group_offset( const cbl_field_t *field ) {
   if( field->parent ) {
     auto e = symbol_at(field->parent);
     if( e->type == SymField ) {
-      auto parent = cbl_field_of(e);
+      const auto parent = cbl_field_of(e);
       return field->offset - parent->offset;
     }
   }
@@ -12595,7 +12597,7 @@ initialize_statement( const cbl_num_result_t& target, bool with_filler,
                       size_t depth = 0 )
 {
   const cbl_refer_t& tgt( target.refer );
-  assert(dimensions(tgt.field) == tgt.nsubscript || 0 < depth);
+  assert(dimensions(tgt.field) == tgt.nsubscript() || 0 < depth);
   assert(!is_literal(tgt.field));
 
   if( tgt.field->type == FldGroup ) {
@@ -12632,7 +12634,7 @@ initialize_statement( const cbl_num_result_t& target, bool with_filler,
 
     if( fOK && is_table(tgt.field) ) {
       cbl_num_result_t output = { target.rounded, synthesize_table_refer(tgt) };
-      if( tgt.nsubscript < output.refer.nsubscript ) { // tgt is whole table
+      if( tgt.nsubscript() < output.refer.nsubscript() ) { // tgt is whole table
        std::list<field_span_t> field_spans;
        static const field_span_t empty_span = { NULL, NULL };
        field_span_t span = empty_span;
@@ -12743,17 +12745,7 @@ static void
 initialize_statement( std::list<cbl_num_result_t>& tgts, bool with_filler,
                      data_category_t value_category,
                      const category_map_t& replacements) {
-
-  bool is_refmod = std::any_of( tgts.begin(), tgts.end(),
-                               []( const auto& tgt ) {
-                                 return tgt.refer.is_refmod_reference();
-                               } );
-  if( false && is_refmod ) { // refmod seems valid per ISO
-    dbgmsg("INITIALIZE cannot initialize a refmod");
-    return;
-  }
-
-  for( auto tgt : tgts ) {
+  for( const auto& tgt : tgts ) {
     initialize_statement( tgt, with_filler, value_category,
                          replacements );
   }
@@ -12764,13 +12756,11 @@ static void
 dump_inspect_oper( const cbl_inspect_oper_t& op ) {
   dbgmsg("\t%s: " HOST_SIZE_T_PRINT_UNSIGNED
          " \"matches\", " HOST_SIZE_T_PRINT_UNSIGNED " \"replaces\"",
-        bound_str(op.bound),
-        op.matches? (fmt_size_t)op.n_identifier_3 : 0,
-        op.replaces? (fmt_size_t)op.n_identifier_3 : 0);
-  if( op.matches )
-    std::for_each(op.matches, op.matches + op.n_identifier_3, dump_inspect_match);
-  if( op.replaces )
-    std::for_each(op.replaces, op.replaces + op.n_identifier_3, dump_inspect_replace);
+         bound_str(op.bound),
+         (fmt_size_t)op.matches.size(), 
+         (fmt_size_t)op.replaces.size());
+  std::for_each(op.matches.begin(), op.matches.end(), dump_inspect_match);
+  std::for_each(op.replaces.begin(), op.replaces.end(), dump_inspect_replace);
 }
 
 #pragma GCC diagnostic push
@@ -12787,14 +12777,14 @@ dump_inspect( const cbl_inspect_t& I ) {
   } else {
     fprintf( stderr, "\tREPLACING:\n" );
   }
-  std::for_each( I.opers, I.opers + I.nbound, dump_inspect_oper );
+  std::for_each( I.begin(), I.end(), dump_inspect_oper );
 }
 #pragma GCC diagnostic pop
 
 #include <iterator>
 
 struct declarative_file_list_t : protected cbl_declarative_t {
-  declarative_file_list_t( const cbl_declarative_t& d )
+  explicit declarative_file_list_t( const cbl_declarative_t& d )
     : cbl_declarative_t(d)
     {
       if( nfile > 0 )
@@ -12819,7 +12809,7 @@ operator<<( std::ostream& os, const declarative_file_list_t& dcl ) {
 
 static declarative_file_list_t
 file_list_of( const cbl_declarative_t& dcl ) {
-  return dcl;
+  return declarative_file_list_t(dcl);
 }
 
 std::ostream&
@@ -12891,7 +12881,7 @@ cbl_file_t::validate_key( const cbl_file_key_t& key ) const {
 
 bool
 cbl_file_t::validate() const {
-  size_t members[] = { user_status, vsam_status, record_length };
+  const size_t members[] = { user_status, vsam_status, record_length };
   bool tf = true;
 
   for( auto isym : members ) {
@@ -13102,7 +13092,7 @@ literal_refmod_valid( YYLTYPE loc, const cbl_refer_t& r ) {
        if( --edge < r.field->data.capacity ) return true;
       }
       // len < 0 or not: 0 < from + len <= capacity
-      auto loc = symbol_field_location(field_index(r.field));
+      loc = symbol_field_location(field_index(r.field));
       error_msg(loc, "%s(%zu:%zu) out of bounds, "
                "size is %u",
                r.field->name,
@@ -13125,19 +13115,22 @@ literal_subscript_oob( const cbl_refer_t& r, size_t& isub );
 
 static bool
 literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) {
-  static char subs[ 7 * 32 ], *esub = subs + sizeof(subs);
-  char *p = subs;
   size_t isub;
 
-  // Find subscript in the supplied refer
+  // Report any out-of-bound subscript. 
   const cbl_field_t *oob = literal_subscript_oob(name, isub);
   if( oob ) {
-    const char *sep = "";
-    for( auto r = name.subscripts; r < name.subscripts + name.nsubscript; r++ ) {
-      snprintf( p, esub - p, "%s%s", sep, nice_name_of(r->field) );
-      sep = " ";
-    }
-
+    std::string sep("");
+    std::string subscript_names = 
+      std::accumulate( name.subscripts.begin(),
+                       name.subscripts.end(),
+                       std::string(),
+                       [&sep]( std::string acc, const auto& sub ) {
+                         acc += sep;
+                         sep = " ";
+                         return acc + nice_name_of(sub.field);
+                       } );
+    
     const char *upper_phrase = "";
     if( ! oob->occurs.bounds.fixed_size() ) {
       static char ub[32] = "boo";
@@ -13149,7 +13142,7 @@ literal_subscripts_valid( YYLTYPE loc, const cbl_refer_t& name ) {
     // X(0): subscript 1 of for out of range for 02 X OCCURS 4 to 6
     error_msg(loc, "%s(%s): subscript %zu out of range "
                    "for %s %s OCCURS %lu%s",
-             oob->name, subs, 1 + isub,
+             oob->name, subscript_names.c_str(), 1 + isub,
              oob->level_str(), oob->name,
              oob->occurs.bounds.lower, upper_phrase );
     return false;
@@ -13171,14 +13164,14 @@ subscript_dimension_error( YYLTYPE loc, size_t nsub, const cbl_refer_t *scalar )
 }
 
 static void
-reject_refmod( YYLTYPE loc, cbl_refer_t scalar ) {
+reject_refmod( YYLTYPE loc, const cbl_refer_t& scalar ) {
   if( scalar.is_refmod_reference() ) {
     error_msg(loc, "%s cannot be reference-modified here", scalar.name());
   }
 }
 
 static bool
-require_pointer( YYLTYPE loc, cbl_refer_t scalar ) {
+require_pointer( YYLTYPE loc, const cbl_refer_t& scalar ) {
   if( scalar.field->type != FldPointer ) {
     error_msg(loc, "%s must have USAGE POINTER", scalar.name());
     return false;
@@ -13187,7 +13180,7 @@ require_pointer( YYLTYPE loc, cbl_refer_t scalar ) {
 }
 
 static bool
-require_numeric( YYLTYPE loc, cbl_refer_t scalar ) {
+require_numeric( YYLTYPE loc, const cbl_refer_t& scalar ) {
   if( ! is_numeric(scalar.field) ) {
     error_msg(loc, "%s must have numeric USAGE", scalar.name());
     return false;
@@ -13196,7 +13189,7 @@ require_numeric( YYLTYPE loc, cbl_refer_t scalar ) {
 }
 
 static bool
-require_integer( YYLTYPE loc, cbl_refer_t scalar ) {
+require_integer( YYLTYPE loc, const cbl_refer_t& scalar ) {
   if( is_literal(scalar.field) ) {
     if( ! is_integer_literal(scalar.field) ) {
       error_msg(loc, "numeric literal '%s' must be an integer",
index 22ce612a2e8a0ffc5c5fc612e43183b9876a5a52..ffb4c986aa6e649f6a46174c7fc576ec7e8821cd 100644 (file)
@@ -244,9 +244,9 @@ new_reference_like( const cbl_field_t& skel ) {
   return new cbl_refer_t( new_temporary_like(skel) );
 }
 
-static void reject_refmod( YYLTYPE loc, cbl_refer_t );
-static bool require_pointer( YYLTYPE loc, cbl_refer_t );
-static bool require_integer( YYLTYPE loc, cbl_refer_t );
+static void reject_refmod( YYLTYPE loc, const cbl_refer_t& );
+static bool require_pointer( YYLTYPE loc, const cbl_refer_t& );
+static bool require_integer( YYLTYPE loc, const cbl_refer_t& );
 
 struct cbl_field_t * constant_of( size_t isym );
 
@@ -289,7 +289,7 @@ struct evaluate_elem_t {
     relop_t oper;
    public:
     cbl_field_t *subject, *object, *cond;
-    case_t( cbl_field_t * subject )
+    explicit case_t( cbl_field_t * subject )
       : oper(eq_op)
       , subject(subject)
       , object(NULL)
@@ -328,11 +328,10 @@ struct evaluate_elem_t {
 
   explicit evaluate_elem_t( const char skel[] )
     : nother(0)
+    , label{LblEvaluate}
     , result( keep_temporary(FldConditional) )
     , pcase( cases.end() )
   {
-    static const cbl_label_t protolabel = { LblEvaluate };
-    label = protolabel;
     label.line = yylineno;
     if( -1 == snprintf(label.name, sizeof(label.name),
                        "%.*s_%d", (int)sizeof(label.name)-6, skel, yylineno) ) {
@@ -367,13 +366,14 @@ struct evaluate_elem_t {
 static class file_delete_args_t {
   cbl_file_t *file;
 public:
+  file_delete_args_t() : file(nullptr) {}
   void init( cbl_file_t *file ) {
     this->file = file;
   }
-  bool ready() const { return file != NULL; }
+  bool ready() const { return file != nullptr; }
   void call_parser_file_delete( bool sequentially ) {
     parser_file_delete(file, sequentially);
-    file = NULL;
+    file = nullptr;
   }
 } file_delete_args;
 
@@ -389,7 +389,7 @@ static struct file_read_args_t {
 
   void
   init( struct cbl_file_t *file,
-        cbl_refer_t record,
+        const cbl_refer_t& record,
         cbl_refer_t *read_into,
         int where ) {
     this->file = file;
@@ -438,7 +438,7 @@ public:
     this->file = file;
   }
   bool ready() const { return file != NULL; }
-  void call_parser_return_start(cbl_refer_t into = cbl_refer_t() ) {
+  void call_parser_return_start(const cbl_refer_t& into = cbl_refer_t() ) {
     parser_return_start(file, into);
     file = NULL;
   }
@@ -448,17 +448,18 @@ static class file_rewrite_args_t {
   cbl_file_t *file;
   cbl_field_t *record;
 public:
+  file_rewrite_args_t() :  file(nullptr), record(nullptr) {}
   void init( cbl_file_t *file, cbl_field_t *record ) {
     this->file = file;
     this->record = record;
   }
-  bool ready() const { return file != NULL; }
+  bool ready() const { return file != nullptr; }
   void call_parser_file_rewrite( bool sequentially ) {
     sequentially = sequentially || file->access == file_access_seq_e;
     if( file->access == file_access_rnd_e ) sequentially = false;
     parser_file_rewrite(file, record, sequentially);
-    file = NULL;
-    record = NULL;
+    file = nullptr;
+    record = nullptr;
   }
 } file_rewrite_args;
 
@@ -487,21 +488,22 @@ static class file_write_args_t {
   cbl_refer_t *advance;
 public:
   file_write_args_t()
-    : file(NULL)
+    : file(nullptr)
+    , data_source(nullptr)
     , after(false)
-    , advance(NULL)
+    , advance(nullptr)
   {}
   cbl_file_t * init( cbl_file_t *file,
                      cbl_field_t *data_source,
                      bool after,
-                     cbl_refer_t *advance ) {
+                     const cbl_refer_t *advance ) {
     this->file = file;
     this->data_source = data_source;
     this->after = after;
     this->advance = new cbl_refer_t(*advance);
     return this->file;
   }
-  bool ready() const { return file != NULL; }
+  bool ready() const { return file != nullptr; }
   void call_parser_file_write( bool sequentially ) {
     sequentially = sequentially || file->access == file_access_seq_e;
     parser_file_write(file, data_source, after, *advance, sequentially);
@@ -535,7 +537,7 @@ struct arith_t {
   cbl_refer_t remainder;
   cbl_label_t *on_error, *not_error;
 
-  arith_t( cbl_arith_format_t format )
+  explicit arith_t( cbl_arith_format_t format )
     : format(format), on_error(NULL), not_error(NULL)
   {}
   arith_t( cbl_arith_format_t format, refer_list_t * refers );
@@ -619,7 +621,7 @@ class eval_subject_t {
   void new_object_labels();
  public:
   eval_subject_t();
-  void append( cbl_refer_t field ) {
+  void append( const cbl_refer_t& field ) {
     columns.push_back(field);
     pcol = columns.begin();
   }
@@ -750,6 +752,7 @@ public:
 
 
 static void dump_inspect( const cbl_inspect_t& i );
+void dump_inspect_match( const cbl_inspect_match_t& M );
 
 struct perform_t {
   struct cbl_perform_tgt_t tgt;
@@ -789,11 +792,10 @@ struct perform_t {
     cbl_refer_t table;
   } search;
 
-  perform_t( cbl_label_t *from, cbl_label_t *to = NULL )
+  explicit perform_t( cbl_label_t *from, cbl_label_t *to = NULL )
     : tgt( from, to ), before(true)
-  {
-    search = {};
-  }
+    , search()
+  {}
   ~perform_t() { varys.clear(); }
   cbl_field_t * until() {
     assert(!varys.empty());
@@ -892,7 +894,7 @@ static struct cbl_label_t *
 paragraph_reference( const char name[], size_t section );
 
 static inline void
-list_add( list<cbl_num_result_t>& list, cbl_refer_t refer, int round ) {
+list_add( list<cbl_num_result_t>& list, const cbl_refer_t& refer, int round ) {
   struct cbl_num_result_t arg = { static_cast<cbl_round_t>(round), refer };
   list.push_back(arg);
 }
@@ -1027,7 +1029,7 @@ class tokenset_t {
   const char * name_of( int tok ) const {
     tok -= (255 + 3);
     gcc_assert(0 <= tok && size_t(tok) < token_names.size());
-    return token_names[tok];
+    return tok < 0? "???" : token_names[tok];
   }
 };
 
@@ -1094,7 +1096,7 @@ redefined_token( const cbl_name_t name ) {
 struct file_list_t {
   list<cbl_file_t*> files;
   file_list_t() {}
-  file_list_t( cbl_file_t* file ) {
+  explicit file_list_t( cbl_file_t* file ) {
     files.push_back(file);
   }
   file_list_t( file_list_t& that ) : files(that.files.size()) {
@@ -1108,10 +1110,15 @@ struct file_list_t {
 
 struct field_list_t {
   list<cbl_field_t*> fields;
-  field_list_t( cbl_field_t *field ) {
+  field_list_t() {}
+  explicit field_list_t( cbl_field_t *field ) {
     fields.push_back(field);
   }
-  explicit field_list_t() {}
+  std::vector<const cbl_field_t*>
+  as_vector() const {
+    std::vector<const cbl_field_t*> output( fields.begin(), fields.end() );
+    return output;
+  }
 };
 
 cbl_field_t **
@@ -1138,7 +1145,7 @@ cbl_file_t **
 
 struct refer_list_t {
   list<cbl_refer_t> refers;
-  refer_list_t( cbl_refer_t *refer ) {
+  explicit refer_list_t( cbl_refer_t *refer ) {
     if( refer ) {
       refers.push_back(*refer);
       delete refer;
@@ -1160,13 +1167,20 @@ struct refer_list_t {
     refers.clear();
     return tgt;
   }
+  std::vector<cbl_refer_t>
+  vectorize() {
+    std::vector<cbl_refer_t> tgt(refers.size());
+    std::copy(refers.begin(), refers.end(), tgt.begin());
+    refers.clear();
+    return tgt;
+  }
 };
 
 struct refer_marked_list_t : public refer_list_t {
   cbl_refer_t *marker;
 
   refer_marked_list_t()  : refer_list_t(NULL),  marker(NULL) {}
-  refer_marked_list_t( cbl_refer_t *marker, refer_list_t *refers )
+  refer_marked_list_t( cbl_refer_t *marker, const refer_list_t *refers )
     : refer_list_t(*refers), marker(marker) {}
   refer_marked_list_t( cbl_refer_t *marker, cbl_refer_t *input )
     : refer_list_t(input)
@@ -1186,7 +1200,7 @@ struct refer_marked_list_t : public refer_list_t {
 struct refer_collection_t {
   list<refer_marked_list_t> lists;
 
-  refer_collection_t( const refer_marked_list_t& marked_list )
+  explicit refer_collection_t( const refer_marked_list_t& marked_list )
   {
     lists.push_back( marked_list );
   }
@@ -1212,48 +1226,13 @@ struct refer_collection_t {
   }
 };
 
-struct ast_inspect_oper_t {
-  cbl_inspect_bound_t bound;  // CHARACTERS/ALL/LEADING/FIRST
-  std::list<cbl_inspect_match_t>    matches;
-  std::list<cbl_inspect_replace_t> replaces;
-
-ast_inspect_oper_t( const cbl_inspect_match_t& match,
-                    cbl_inspect_bound_t bound = bound_characters_e )
-    : bound(bound)
-  {
-    matches.push_back(match);
-  }
-  ast_inspect_oper_t( const cbl_inspect_replace_t& replace,
-                    cbl_inspect_bound_t bound = bound_characters_e )
-    : bound(bound)
-  {
-    replaces.push_back(replace);
-  }
-};
-
-struct ast_inspect_t : public std::list<cbl_inspect_oper_t> {
-  cbl_refer_t tally; // field is NULL for REPLACING
-  const std::list<cbl_inspect_oper_t>& opers() const { return *this; }
-};
-
-struct ast_inspect_list_t : public std::list<cbl_inspect_t> {
-  ast_inspect_list_t( const cbl_inspect_t& insp ) {
-    push_back(insp);
-  }
-
-  cbl_inspect_t * as_array() {
-    cbl_inspect_t *output = new cbl_inspect_t[ size() ];
-    std::copy( begin(), end(), output );
-    return output;
-  }
-};
-
-void ast_inspect( cbl_refer_t& input, bool backward, ast_inspect_list_t& inspects );
+void ast_inspect( YYLTYPE loc, cbl_refer_t& input, bool backward,
+                  cbl_inspect_opers_t& inspects );
 
 template <typename E>
 struct elem_list_t {
   list<E*> elems;
-  elem_list_t( E *elem ) {
+  explicit elem_list_t( E *elem ) {
     elems.push_back(elem);
   }
   void clear() {
@@ -1278,7 +1257,7 @@ template <typename L, typename E>
 
 struct unstring_tgt_t {
   cbl_refer_t *tgt, *delimiter, *count;
-  unstring_tgt_t( cbl_refer_t *tgt,
+  explicit unstring_tgt_t( cbl_refer_t *tgt,
                   cbl_refer_t *delimiter = NULL,
                   cbl_refer_t *count = NULL )
     : tgt(tgt), delimiter(delimiter), count(count)
@@ -1302,7 +1281,7 @@ private:
 struct unstring_tgt_list_t {
   list<unstring_tgt_t> unstring_tgts;
 
-  unstring_tgt_list_t( unstring_tgt_t *unstring_tgt ) {
+  explicit unstring_tgt_list_t( unstring_tgt_t *unstring_tgt ) {
     unstring_tgts.push_back(*unstring_tgt);
     delete unstring_tgt;
   }
@@ -1324,7 +1303,7 @@ struct unstring_tgt_list_t {
 
 struct unstring_into_t : public unstring_tgt_list_t {
   cbl_refer_t pointer, tally;
-  unstring_into_t( unstring_tgt_list_t *tgt_list,
+  explicit unstring_into_t( unstring_tgt_list_t *tgt_list,
                    cbl_refer_t *pointer = NULL,
                    cbl_refer_t *tally = NULL )
     : unstring_tgt_list_t(*tgt_list)
@@ -1340,7 +1319,7 @@ struct unstring_into_t : public unstring_tgt_list_t {
 struct ffi_args_t {
   list<cbl_ffi_arg_t> elems;
 
-  ffi_args_t( cbl_ffi_arg_t *arg ) {
+  explicit ffi_args_t( cbl_ffi_arg_t *arg ) {
     this->push_back(arg);
   }
 
@@ -1416,8 +1395,8 @@ struct file_sort_io_t {
   file_list_t file_list;
   cbl_perform_tgt_t tgt;
 
-  file_sort_io_t( file_list_t& files ) : file_list(files) {}
-  file_sort_io_t( cbl_perform_tgt_t& tgt ) : tgt(tgt.from(), tgt.to()) {}
+  explicit file_sort_io_t( file_list_t& files ) : file_list(files) {}
+  explicit file_sort_io_t( cbl_perform_tgt_t& tgt ) : tgt(tgt.from(), tgt.to()) {}
   size_t nfile() const { return file_list.files.size(); }
 };
 
@@ -1432,14 +1411,14 @@ struct merge_t {
   cbl_perform_tgt_t tgt;
   list<cbl_file_t*> outputs;
 
-  merge_t( cbl_file_t *input ) : master(input), type(output_unknown_e) {}
+  explicit merge_t( cbl_file_t *input ) : master(input), type(output_unknown_e) {}
 };
 
 static list<merge_t> merges;
 
 static inline merge_t&
 merge_alloc( cbl_file_t *file ) {
-  merges.push_back(file);
+  merges.push_back(merge_t(file));
   return merges.back();
 }
 
@@ -1460,7 +1439,7 @@ static  list<cbl_refer_t> lhs;
 struct vargs_t {
   std::list<cbl_refer_t> args;
     vargs_t() {}
-    vargs_t( struct cbl_refer_t *p ) { args.push_back(*p); delete p; }
+    explicit vargs_t( struct cbl_refer_t *p ) { args.push_back(*p); delete p; }
     void push_back( cbl_refer_t *p ) { args.push_back(*p); delete p; }
 };
 
@@ -1484,7 +1463,8 @@ class prog_descr_t {
   const char *collating_sequence;
   struct locale_t {
     cbl_name_t name; const char *os_name;
-    locale_t(const cbl_name_t name = NULL, const char *os_name = NULL)
+    locale_t() : name(""), os_name(nullptr) {}
+    locale_t(const cbl_name_t name, const char *os_name)
       : name(""), os_name(os_name) {
       if( name ) {
         bool ok = namcpy(YYLTYPE(), this->name, name);
@@ -1495,7 +1475,7 @@ class prog_descr_t {
   cbl_call_convention_t call_convention;
   cbl_options_t options;
 
-  prog_descr_t( size_t isymbol )
+  explicit prog_descr_t( size_t isymbol )
     : program_index(isymbol)
     , declaratives_eval(NULL)
     , paragraph(NULL)
@@ -1607,9 +1587,9 @@ class program_stack_t : protected  std::stack<prog_descr_t> {
   bool pending_initial() { return pending.initial = true; }
 
   void push( prog_descr_t descr ) {
-    cbl_call_convention_t current_call_convention = cbl_call_cobol_e;
-    if( !empty() ) current_call_convention = top().call_convention;
-    descr.call_convention = current_call_convention;
+    cbl_call_convention_t call_convention = cbl_call_cobol_e;
+    if( !empty() ) call_convention = top().call_convention;
+    descr.call_convention = call_convention;
     std::stack<prog_descr_t>& me(*this);
     me.push(descr);
   }
@@ -1645,11 +1625,12 @@ class program_stack_t : protected  std::stack<prog_descr_t> {
     }
   }
 
+  // cppcheck-suppress-begin useStlAlgorithm
   cbl_label_t *first_declarative() {
     auto eval = top().declaratives_eval;
     if( eval ) return eval;
     // scan stack container for declaratives
-    for( auto& prog : c ) {
+    for( const auto& prog : c ) {
       if( prog.declaratives_eval ) {
         eval = prog.declaratives_eval;
         break;
@@ -1657,6 +1638,7 @@ class program_stack_t : protected  std::stack<prog_descr_t> {
     }
     return eval;
   }
+  // cppcheck-suppress-end useStlAlgorithm
 };
 
 struct rel_part_t {
@@ -1664,9 +1646,13 @@ struct rel_part_t {
   bool has_relop, invert;
   relop_t relop;
 
-  rel_part_t( cbl_refer_t *operand = NULL,
-              relop_t relop = relop_t(-1),
-              bool invert = false )
+  rel_part_t()
+    : operand(nullptr),
+      has_relop(false),
+      invert(false),
+      relop(relop_t(-1))
+  {}
+  rel_part_t( cbl_refer_t *operand, relop_t relop, bool invert )
     : operand(operand),
       has_relop(relop != -1),
       invert(invert),
@@ -1700,7 +1686,7 @@ struct rel_part_t {
 class log_expr_t {
   cbl_field_t *orable, *andable;
  public:
-  log_expr_t( cbl_field_t *init ) : orable(NULL), andable(init) {
+  explicit log_expr_t( cbl_field_t *init ) : orable(NULL), andable(init) {
     if( ! is_conditional(init) ) {
       dbgmsg("%s:%d: logic error: %s is not a truth value",
                __func__, __LINE__, name_of(init));
@@ -1859,6 +1845,10 @@ static class current_t {
   class declaratives_t : protected declaratives_list_t {
     struct file_exception_t {
       ec_type_t type; uint32_t file;
+      file_exception_t() : type(ec_none_e), file(0) {}
+      file_exception_t(ec_type_t type, uint32_t file)
+        : type(type), file(file)
+      {}
       bool operator<( const file_exception_t& that ) const {
         if( type == that.type ) return file < that.file;
         return type < that.type;
@@ -1866,9 +1856,11 @@ static class current_t {
     };
     std::set<file_exception_t> file_exceptions;
    public:
+    declaratives_t() {}
     // current compiled data for enabled ECs and Declaratives, used by library.
     struct runtime_t {
       tree ena, dcl;
+      runtime_t() : ena(nullptr), dcl(nullptr) {}
     } runtime;
     
     bool empty() const {
@@ -1888,7 +1880,7 @@ static class current_t {
       }
       for( auto f = declarative.files;
            f && f < declarative.files + declarative.nfile; f++ ) {
-        file_exception_t ex = { declarative.type, *f };
+        file_exception_t ex( declarative.type, *f );
         auto result = file_exceptions.insert(ex);
         if( ! result.second ) {
           yyerror("%s defined twice for %s",
@@ -1901,6 +1893,7 @@ static class current_t {
       return true;
     }
 
+    // cppcheck-suppress-begin useStlAlgorithm
     uint32_t status() const {
       uint32_t status_word = 0;
       for( auto dcl : *this ) {
@@ -1908,6 +1901,7 @@ static class current_t {
       }
       return status_word;
     }
+    // cppcheck-suppress-end useStlAlgorithm
 
     bool has_format_1() const {
       return std::any_of( begin(), end(),
@@ -1947,7 +1941,6 @@ static class current_t {
   const cbl_field_t * has_typedef( const cbl_field_t *field ) {
     auto found = typedefs.find(field);
     return found == typedefs.end()? NULL : *found;
-    return found == typedefs.end()? NULL : *found;
   }
 
   void udf_add( size_t isym ) {
@@ -2003,12 +1996,12 @@ static class current_t {
 
   std::list<std::string>& debugging_declaratives(bool all) const {
     const char *para = programs.top().paragraph->name;
-    auto declaratives = debugging_clients.find(all? ":all:" : para);
-    if( declaratives == debugging_clients.end() ) {
+    auto client = debugging_clients.find(all? ":all:" : para);
+    if( client == debugging_clients.end() ) {
       static std::list<std::string> empty;
       return empty;
     }
-    return declaratives->second;
+    return client->second;
   }
 
   bool
@@ -2079,7 +2072,7 @@ static class current_t {
 
     const cbl_label_t *L;
     if( (L = symbol_program_add(parent, &label)) == NULL ) return false;
-    programs.push( symbol_index(symbol_elem_of(L)));
+    programs.push( prog_descr_t(symbol_index(symbol_elem_of(L))) );
     programs.apply_pending();
 
     bool fOK = symbol_at(programs.top().program_index) + 1 == symbols_end();
@@ -2147,7 +2140,7 @@ static class current_t {
 
     assert(!programs.empty());
 
-    procref_t *ref = ambiguous_reference(program_index());
+    const procref_t *ref = ambiguous_reference(program_index());
     std::set<std::string> externals = programs.top().external_targets();
 
     /*
@@ -2371,11 +2364,12 @@ void current_enabled_ecs( tree ena ) {
 
 static void
 add_debugging_declarative( const cbl_label_t * label ) {
+  // cppcheck-suppress [unreadVariable] obviously not true
   const char *section = current.declarative_section_name();
   if( section ) {
     debugging_clients[label->name].push_back(section);
   }
-};
+}
 
 cbl_options_t current_options() {
   return current.options_paragraph;
@@ -2611,7 +2605,7 @@ intrinsic_call_1( cbl_field_t *output, int token,
 }
 
 static bool
-intrinsic_call_2( cbl_field_t *tgt, int token, cbl_refer_t *r1, cbl_refer_t *r2 ) {
+intrinsic_call_2( cbl_field_t *tgt, int token, const cbl_refer_t *r1, cbl_refer_t *r2 ) {
   std::vector<cbl_refer_t> args { *r1, r2? *r2 : cbl_refer_t() };
   size_t n = intrinsic_invalid_parameter(token, args);
   if( n < args.size() ) {
@@ -2689,18 +2683,14 @@ table_primary_index( cbl_field_t *table ) {
     NULL : cbl_field_of(symbol_at(table->occurs.indexes.fields[0]));
 }
 
-static inline const cbl_refer_t  // & // Removed the '&' to stop a weird compiler error
+static inline const cbl_refer_t  // return copy, not element reference
 invalid_key( const cbl_refer_t& ref ) {
   assert(ref.field);
-
-  if( ref.nsubscript == 0 ) return ref;
-
-  for( size_t i=0; i < ref.nsubscript; i++ ) {
-    if( ref.subscripts[i].field->parent != ref.field->parent ) {
-      return ref.subscripts[i];
-    }
-  }
-  return NULL;
+  auto p = std::find_if( ref.subscripts.begin(), ref.subscripts.end(),
+                         [parent = ref.field->parent]( const auto &sub ) {
+                           return sub.field->parent == parent;
+                         } );
+  return p != ref.subscripts.end() ? *p : nullptr;
 }
 
 static inline symbol_elem_t *
@@ -3186,14 +3176,14 @@ cmd_or_env_special_of( std::string name ) {
 }
 
 static inline void
-parser_add2( struct cbl_num_result_t& to,
-             struct cbl_refer_t from ) {
+parser_add2( const cbl_num_result_t& to,
+             const cbl_refer_t& from ) {
   parser_add(to.refer, to.refer, from, to.rounded);
 }
 
 static inline void
-parser_subtract2( struct cbl_num_result_t to,
-                  struct cbl_refer_t from ) {
+parser_subtract2(  const cbl_num_result_t& to,
+                   const cbl_refer_t& from ) {
   parser_subtract(to.refer, to.refer, from, to.rounded);
 }
 
@@ -3277,11 +3267,11 @@ ast_set_pointers( const list<cbl_num_result_t>& tgts, cbl_refer_t src ) {
 
 void
 stringify( refer_collection_t *inputs,
-           cbl_refer_t into, cbl_refer_t pointer,
+           const cbl_refer_t& into, const cbl_refer_t& pointer,
            cbl_label_t  *on_error = NULL,
            cbl_label_t *not_error = NULL);
 
-void unstringify( cbl_refer_t& src, refer_list_t *delimited,
+void unstringify( const cbl_refer_t& src, refer_list_t *delimited,
                   unstring_into_t * into,
                   cbl_label_t  *on_error = NULL,
                   cbl_label_t *not_error = NULL );
@@ -3306,6 +3296,7 @@ implicit_section()
 }
 
 static void
+// cppcheck-suppress constParameterPointer
 ast_enter_exit_section( cbl_label_t * section ) {
   auto implicit = section?  implicit_paragraph() : NULL;
 
@@ -3385,7 +3376,7 @@ data_division_ready() {
 
 static
 bool
-anybody_redefines(cbl_field_t *tree)
+anybody_redefines( const cbl_field_t *tree )
   {
   bool retval = false;
   while(tree)
@@ -3395,7 +3386,8 @@ anybody_redefines(cbl_field_t *tree)
       retval = true;
       break;
       }
-    tree = parent_of(tree);
+    // cppcheck-suppress [unreadVariable] obviously not true
+    tree = parent_of(tree);   
     }
   return retval;
   }
@@ -3615,14 +3607,14 @@ file_section_parent_set( cbl_field_t *field ) {
                                                 field->data.capacity);
 
     field->file = file_section_fd;
-    auto redefined = symbol_redefines(record_area);
+    const auto redefined = symbol_redefines(record_area);
     field->parent = redefined? record_area->parent : file->default_record;
   }
   return file_section_fd > 0;
 }
 
 void ast_call(const YYLTYPE& loc, cbl_refer_t name,
-                  cbl_refer_t returning,
+                  const cbl_refer_t& returning,
                   size_t narg, cbl_ffi_arg_t args[],
                   cbl_label_t *except,
                   cbl_label_t *not_except,
index e504f46ee40565a56e1ac3a9ee60f11bc1cfacff..11b86a3d446d2046f8aa3b1ab9c3e73eeeb337c8 100644 (file)
@@ -271,7 +271,7 @@ function_descr_t *function_descrs_end = function_descrs + COUNT_OF(function_desc
 class cname_cmp {
   const char *cname;
  public:
-  cname_cmp( const char *cname ) : cname(cname) {}
+  explicit cname_cmp( const char *cname ) : cname(cname) {}
 
   bool operator()( const function_descr_t& descr ) {
     return strlen(cname) == strlen(descr.cname) &&
@@ -293,8 +293,8 @@ intrinsic_inconsistent_parameter( size_t n, cbl_refer_t *args ) {
   class commensurate_type {
     cbl_refer_t first;
    public:
-    commensurate_type( const cbl_refer_t& first ) : first(first) {}
-    bool operator()( cbl_refer_t& arg )  const {
+    explicit commensurate_type( const cbl_refer_t& first ) : first(first) {}
+    bool operator()( const cbl_refer_t& arg )  const {
       return is_numeric(first.field) == is_numeric(arg.field);
     }
   };
index 7f1153248af6036d33eea12391bb167ea35a4ba5..21e89e40f0ae8a42e1048886762904827ed6468c 100644 (file)
@@ -214,7 +214,11 @@ struct cdf_status_t {
   const char *filename;
   int  token;
   bool parsing;
-  cdf_status_t( int token = 0, bool parsing = true )
+  cdf_status_t()
+    : lineno(yylineno), filename(cobol_filename())
+    , token(0), parsing(true)
+  {}
+  cdf_status_t( int token, bool parsing )
     : lineno(yylineno), filename(cobol_filename())
     , token(token), parsing(parsing)
   {}
@@ -371,7 +375,7 @@ class enter_leave_t {
   enter_leave_t() : entering(NULL), leaving(NULL), filename(NULL) {}
   enter_leave_t(  parser_enter_file_f *entering, const char *filename )
     : entering(entering), leaving(NULL), filename(filename) {}
-  enter_leave_t(parser_leave_file_f *leaving)
+  explicit enter_leave_t(parser_leave_file_f *leaving)
     : entering(NULL), leaving(leaving), filename(NULL) {}
 
   void notify( unsigned int newlines = 0 ) {
@@ -405,7 +409,7 @@ static class input_file_status_t {
     trailing_newlines = std::count(yytext, yytext + yyleng, '\n');
     if( trailing_newlines && yy_flex_debug )
       dbgmsg("adding %u lines after POP", trailing_newlines);
-    inputs.push( parser_leave_file );
+    inputs.push( enter_leave_t(parser_leave_file) );
   }
   void notify() {
     while( ! inputs.empty() ) {
@@ -429,7 +433,7 @@ update_location() {
 
   auto nline = std::count(yytext, yytext + yyleng, '\n');
   if( nline ) {
-    char *p = static_cast<char*>(memrchr(yytext, '\n', yyleng));
+    const char *p = static_cast<char*>(memrchr(yytext, '\n', yyleng));
     loc.last_column = (yytext + yyleng) - p;
   }
 
@@ -666,7 +670,7 @@ bool need_nume_set( bool tf ) {
 static int datetime_format_of( const char input[] );
 
 static int symbol_function_token( const char name[] ) {
-  auto e = symbol_function( 0, name );
+  const auto e = symbol_function( 0, name );
   return e ? symbol_index(e) : 0;
 }
 
@@ -754,7 +758,7 @@ typed_name( const char name[] ) {
     __attribute__((fallthrough));
   case FldLiteralN:
     {
-      auto f = cbl_field_of(e);
+      const auto f = cbl_field_of(e);
       if( type == FldLiteralN ) {
         yylval.numstr.radix =
           f->has_attr(hex_encoded_e)? hexadecimal_e : decimal_e;
index dc315191362aac2345efe7544fc58193b6eb2aef..385ea67299a60c734e7d4e0d57769c577d644edc 100644 (file)
@@ -116,10 +116,10 @@ datetime_format_of( const char input[] ) {
 
     for( auto p = patterns; p < eopatterns; p++ ) {
       static const int cflags = REG_EXTENDED | REG_ICASE;
-      static char msg[80];
       int erc;
 
       if( 0 != (erc = regcomp(&p->re, p->regex, cflags)) ) {
+        static char msg[80];
         regerror(erc, &p->re, msg, sizeof(msg));
         yywarn("%s:%d: %s: %s", __func__, __LINE__, keyword_str(p->token), msg);
       }
index f7ab98220a5a519f1e60be5221f201e2ddec052a..d417af3fd2cc4e45c7d333a07fce238d4e15f250 100644 (file)
@@ -147,10 +147,10 @@ extern bool cursor_at_sol;
                     fprintf(stderr, "<%s>", cbl_field_type_str((b).field->type)); \
                     } \
                 } \
-            if( (b).nsubscript) \
+            if( (b).nsubscript()) \
                 { \
                 fprintf(stderr,"("); \
-                for(size_t jjj=0; jjj<(b).nsubscript; jjj++) \
+                for(size_t jjj=0; jjj<(b).nsubscript(); jjj++) \
                     { \
                     if(jjj) \
                       { \
@@ -337,13 +337,13 @@ extern bool cursor_at_sol;
     else \
       { \
       gg_fprintf(trace_handle, 1, "%s", gg_string_literal( (b).field->name ? (b).field->name:"")); \
-      if( b.nsubscript ) \
+      if( b.nsubscript() ) \
         { \
         gg_fprintf(trace_handle, 0, "("); \
-        for(unsigned int i=0; i<b.nsubscript; i++) \
+        for(unsigned int i=0; i<b.nsubscript(); i++) \
           { \
           gg_fprintf(trace_handle, 1, "%s", gg_string_literal(    b.subscripts[i].field->name ? b.subscripts[i].field->name : ""  )); \
-          if( i<b.nsubscript-1 ) \
+          if( i<b.nsubscript()-1 ) \
             { \
             gg_fprintf(trace_handle, 0, " "); \
             } \
@@ -506,7 +506,7 @@ class ANALYZE
 class ANALYZE
   {
   public:
-    ANALYZE(const char *)
+    explicit ANALYZE(const char *)
       {
       }
     ~ANALYZE()
index 2b9888c89367c9c6c2e6c25416257e1f06f62ec3..d75ca29be0f7ed0d44f01a29207acdfd6fa7791a 100644 (file)
@@ -136,11 +136,9 @@ static struct symbol_table_t {
 
 static symbol_table_t&
 symbol_table_extend() {
-  static FILE *mapped;
 
   if( symbols.nelem == 0 ) {  // first time: create file & set initial capacity
-    assert(mapped == NULL && symbols.fd == -1);
-
+    FILE *mapped;
     if( (mapped = tmpfile()) == NULL ) {
       cbl_err( "could not create temporary file for symbol table");
     }
@@ -229,6 +227,12 @@ cbl_span_t::from_field() { assert(from); return from->field; }
 cbl_field_t *
 cbl_span_t::len_field()  { assert(len); return len->field; }
 
+cbl_ffi_arg_t::cbl_ffi_arg_t()
+  : optional(false)
+  , crv(by_reference_e)
+  , attr(none_of_e)
+{}
+
 cbl_ffi_arg_t::
 cbl_ffi_arg_t( cbl_refer_t* refer, cbl_ffi_arg_attr_t attr )
   : optional(false)
@@ -927,7 +931,7 @@ end_of_group( size_t igroup ) {
       if( e->program != group->program ) return isym;
       if( e->type == SymLabel ) return isym; // end of data division
       if( e->type == SymField ) {
-        auto f = cbl_field_of(e);
+        const auto f = cbl_field_of(e);
         if( f->level == LEVEL77 || f->level == 66 ) return isym;
         if( f->level == 1 && f->parent != igroup ) {
           return isym;
@@ -938,7 +942,7 @@ end_of_group( size_t igroup ) {
   }
 
   eog_t eog(symbol_at(igroup));
-  symbol_elem_t *e = std::find_if( symbols_begin(++igroup), symbols_end(), eog );
+  const symbol_elem_t *e = std::find_if( symbols_begin(++igroup), symbols_end(), eog );
   return e - symbols_begin();
 }
 
@@ -993,7 +997,7 @@ symbol_find_odo_debug( cbl_field_t * field ) {
 
 // Return OCCURS DEPENDING ON table subordinate to field, if any.
 struct cbl_field_t *
-symbol_find_odo( cbl_field_t * field ) {
+symbol_find_odo( const cbl_field_t * field ) {
   size_t bog = field_index(field), eog = end_of_group(bog);
   auto e = std::find_if( symbol_at(bog), symbol_at_impl(eog, true), has_odo );
   return e == symbol_at_impl(eog, true)? NULL : cbl_field_of(e);
@@ -1170,7 +1174,7 @@ static struct symbol_elem_t *
         // If an 01 record exists for the FD/SD, use its capacity as the
         // default_record capacity.
         if( p != symbols_end() ) {
-          auto record = cbl_field_of(p);
+          const auto record = cbl_field_of(p);
           assert(record->level == 1);
           e = calculate_capacity(p);
           auto record_size = std::max(record->data.memsize,
@@ -1362,7 +1366,7 @@ is_variable_length( const cbl_field_t *field ) {
  *  occurs-depending table."
 */
 cbl_field_t *
-rename_not_ok( cbl_field_t *first, cbl_field_t *last) {
+rename_not_ok( const cbl_field_t *first, const cbl_field_t *last) {
   symbol_elem_t
     *beg = symbol_at(field_index(first)),
     *end = symbol_at(field_index(last));
@@ -1463,7 +1467,7 @@ field_str( const cbl_field_t *field ) {
   }
 
   pend += snprintf(pend, string + sizeof(string) - pend,
-                   "%02d %-20s ", field->level, name);
+                   "%02u %-20s ", field->level, name);
 
   char offset[32] = "";
   if( field->level > 1 ) {
@@ -1574,7 +1578,7 @@ struct capacity_of {
 
   capacity_of operator()( symbol_elem_t& elem ) {
     if( elem.type == SymField ) {
-      cbl_field_t *f = cbl_field_of(&elem);
+      const cbl_field_t *f = cbl_field_of(&elem);
       if( is_elementary(f->type) ) {
         capacity += field_size(f);
       }
@@ -1741,7 +1745,7 @@ symbols_update( size_t first, bool parsed_ok ) {
 
     bool size_invalid = field->data.memsize > 0 && symbol_redefines(field);
     if( size_invalid ) { // redefine of record area is ok
-      auto redefined = symbol_redefines(field);
+      const auto redefined = symbol_redefines(field);
       size_invalid = ! is_record_area(redefined);
     }
     if( !field->is_valid() || size_invalid )
@@ -1824,7 +1828,7 @@ symbols_update( size_t first, bool parsed_ok ) {
     }
 
     // Verify REDEFINing field has no ODO components
-    auto parent = symbol_redefines(field);
+    const auto parent = symbol_redefines(field);
     if( parent && !is_record_area(parent) && is_variable_length(field) ) {
       ERROR_FIELD(field, "line %d: REDEFINES field %s cannot be variable length",
                field->line, field->name);
@@ -2014,15 +2018,15 @@ symbol_in_file( symbol_elem_t *e ) {
 }
 #endif
 
-static struct cbl_field_t *
-symbol_field_parent_set( struct cbl_field_t *field )
+static cbl_field_t *
+symbol_field_parent_set( cbl_field_t *field )
 {
   if( field->level == 01 ) return NULL;
   if( field->level == 77 ) return NULL;
   if( field->level == 78 ) return NULL;
 
   struct symbol_elem_t *e = symbols.elems + symbols.nelem - 1;
-  struct symbol_elem_t *first = symbols.elems + symbols.first_program;
+  const struct symbol_elem_t *first = symbols.elems + symbols.first_program;
 
   for( ; field->parent == 0 && e >= first; e-- ) {
     if( ! (e->type == SymField && cbl_field_of(e)->level > 0) ) {
@@ -2404,7 +2408,7 @@ symbol_file_add( size_t program, cbl_file_t *file ) {
     return NULL;
   }
 
-  struct symbol_elem_t sym = { SymFile, program };
+  symbol_elem_t sym{ SymFile, program };
   sym.elem.file = *file;
 
   e = symbol_add(&sym);
@@ -2462,7 +2466,7 @@ symbol_typedef_add( size_t program, struct cbl_field_t *field ) {
   auto e = symbols_end() - 1;
   assert( symbols_begin() < e );
   if( e->type == SymField ) {
-    auto f = cbl_field_of(e);
+    const auto f = cbl_field_of(e);
     if( f == field ) return e;
   }
 
@@ -2500,7 +2504,7 @@ struct symbol_elem_t *
 symbol_field_add( size_t program, struct cbl_field_t *field )
 {
   field->our_index = symbols.nelem;
-  cbl_field_t *parent = symbol_field_parent_set( field );
+  const cbl_field_t *parent = symbol_field_parent_set( field );
   if( parent && parent->type == FldGroup) {
     // Inherit effects of parent's USAGE, as though it appeared 1st in the
     // member's definition.
@@ -2512,7 +2516,7 @@ symbol_field_add( size_t program, struct cbl_field_t *field )
     if( is_numeric(parent->usage) && parent->data.capacity > 0 ) {
       field->type = parent->usage;
       field->data = parent->data;
-      field->data = 0.0;
+      field->data = 0;
       field->data.initial = NULL;
     }
   }
@@ -2631,6 +2635,7 @@ symbol_field( size_t program, size_t parent, const char name[] )
   return p != end? &*p : NULL;
 }
 
+// cppcheck-suppress-begin [CastIntegerToAddressAtReturn] obviously not true
 symbol_elem_t *
 symbol_register( const char name[] )
 {
@@ -2646,6 +2651,7 @@ symbol_register( const char name[] )
 
   return p;
 }
+// cppcheck-suppress-end [CastIntegerToAddressAtReturn]
 
 // Find current 01 record during Level 66 construction.
 const symbol_elem_t *
@@ -2708,11 +2714,12 @@ symbol_literalA( size_t program, const char name[] )
 struct symbol_elem_t *
 symbol_file( size_t program, const char name[] ) {
   size_t nelem = symbols.nelem;
-  struct symbol_elem_t key = { SymFile, program }, *e = &key;
+  symbol_elem_t key{ SymFile, program }, *e = &key;
 
   assert(strlen(name) < sizeof(key.elem.file.name));
   strcpy(key.elem.file.name, name);
 
+  // cppcheck-suppress-begin [knownConditionTrueFalse]
   do {
     e = static_cast<struct symbol_elem_t *>(lfind( &key, symbols.elems,
                                                    &nelem, sizeof(*e),
@@ -2721,6 +2728,7 @@ symbol_file( size_t program, const char name[] ) {
     key.program = cbl_label_of(symbol_at(key.program))->parent;
     if( key.program == 0 ) break; // no file without a program
   } while( !e );
+  // cppcheck-suppress-end [knownConditionTrueFalse]
 
   if( e ) {
     assert(e->type == SymFile);
@@ -2914,7 +2922,7 @@ symbol_file_same_record_area( std::list<cbl_file_t*>& files ) {
 }
 
 static symbol_elem_t *
-next_program( symbol_elem_t *elem ) {
+next_program( const symbol_elem_t *elem ) {
   size_t start = elem? symbol_index(elem) : 0;
   symbol_elem_t * e =
     std::find_if( symbols_begin(start), symbols_end(), is_program );
@@ -2952,14 +2960,14 @@ is_numeric_constant( const char name[] ) {
 
 // get default record layout for a file
 struct cbl_field_t *
-symbol_file_record( struct cbl_file_t *file ) {
+symbol_file_record( const cbl_file_t *file ) {
   return cbl_field_of(symbol_at(file->default_record));
 }
 
 class is_section {
   cbl_section_type_t section_type;
  public:
-  is_section( cbl_section_type_t sect ) : section_type(sect) {}
+  explicit is_section( cbl_section_type_t sect ) : section_type(sect) {}
   bool operator()( symbol_elem_t& e ) const {
     return e.type == SymDataSection && cbl_section_of(&e)->type == section_type;
   }
@@ -2970,8 +2978,6 @@ static bool fd_record_size_cmp( const symbol_elem_t& a, const symbol_elem_t& b )
   return cbl_field_of(&a)->data.capacity < cbl_field_of(&b)->data.capacity;
 }
 
-cbl_file_key_t cbl_file_t::no_key;
-
 /*
  * Find largest and smallest record defined for a file.  The rule is:
  * cbl_file_t::varies() returns true if the record size varies,
@@ -3604,12 +3610,9 @@ cbl_label_t::explicit_parent() const {
 }
 
 cbl_prog_hier_t::cbl_prog_hier_t() {
-  nlabel = std::count_if( symbols_begin(), symbols_end(), is_program );
-  assert(nlabel >0);
-  labels = new cbl_prog_hier_t::program_label_t[nlabel];
-
   std::copy_if( symbols_begin(), symbols_end(),
-                labels, is_program );
+                std::back_inserter(labels), is_program );
+  assert(! labels.empty());
 }
 
 /*
@@ -3702,7 +3705,8 @@ symbol_label_add( size_t program, cbl_label_t *input )
   if( (e = symbol_add(&elem)) == NULL ) {
     cbl_errx("%s:%d: could not add '%s'", __func__, __LINE__, label->name);
   }
-
+  assert(e);
+  
   common_callables_update( symbol_index(e) );
 
   // restore munged line number unless symbol_add returned an existing label
@@ -3723,7 +3727,7 @@ symbol_label_section_exists( size_t eval_label_index ) {
   bool has_section = std::any_of( ++eval, symbols_end(),
                                [program = eval->program]( const auto& sym ) {
                                  if( program == sym.program && sym.type == SymLabel ) {
-                                   auto& L(sym.elem.label);
+                                   const auto& L(sym.elem.label);
                                   // true if the symbol is an explicit label.
                                    return L.type == LblSection &&  L.name[0] != '_'; 
                                  }
@@ -3875,7 +3879,7 @@ expand_picture(const char *picture)
     {
     assert(strlen(picture) < PICTURE_MAX); // guaranteed by picset() in scanner
     size_t retval_length = PICTURE_MAX;
-    char *retval = (char *)xmalloc(retval_length);
+    char *retval = static_cast<char *>(xmalloc(retval_length));
     size_t index = 0;
 
     int ch;
@@ -3904,7 +3908,7 @@ expand_picture(const char *picture)
             if( index + repeat >= retval_length )
                 {
                 retval_length <<= 1;
-                retval = (char *)xrealloc(retval, retval_length);
+                retval = static_cast<char *>(xrealloc(retval, retval_length));
                 }
 
             while(repeat--)
@@ -3917,7 +3921,7 @@ expand_picture(const char *picture)
             if( index >= retval_length )
                 {
                 retval_length <<= 1;
-                retval = (char *)xrealloc(retval, retval_length);
+                retval = static_cast<char *>(xrealloc(retval, retval_length));
                 }
             retval[index++] = ch;
             }
@@ -3926,7 +3930,7 @@ expand_picture(const char *picture)
     if( index >= retval_length )
         {
         retval_length <<= 1;
-        retval = (char *)xrealloc(retval, retval_length);
+        retval = static_cast<char *>(xrealloc(retval, retval_length));
         }
     retval[index++] = '\0';
 
@@ -3949,7 +3953,6 @@ expand_picture(const char *picture)
                 {
                 pcurrency[i] = 'B';
                 }
-            dest_length += sign_length;
             }
         }
 
@@ -4180,7 +4183,7 @@ symbol_program_callables( size_t program ) {
     if( e->type != SymLabel ) continue;
     if( e->elem.label.type != LblProgram ) continue;
 
-    auto prog = cbl_label_of(e);
+    const auto prog = cbl_label_of(e);
     if( program == symbol_index(e) && !prog->recursive ) continue;
 
     if( (self->parent == prog->parent && prog->common) ||
@@ -4214,6 +4217,7 @@ symbol_program_local( const char tgt_name[] ) {
  */
 std::map<char, const char *> currencies;
 
+// cppcheck-suppress-begin [nullPointerRedundantCheck]
 bool
 symbol_currency_add( const char symbol[], const char sign[] ) {
   // In service of CURRENCY sign PICTURE SYMBOL symbol
@@ -4225,6 +4229,7 @@ symbol_currency_add( const char symbol[], const char sign[] ) {
   currencies[*symbol] = sign;
   return true;
 }
+// cppcheck-suppress-end [nullPointerRedundantCheck]
 
 const char *
 symbol_currency( char sign ) {
@@ -4247,24 +4252,19 @@ bool decimal_is_comma() { return decimal_point == ','; }
 /*
  * A cbl_occurs_key_t is part of a field definition, and comprises
  * size_t symbol indexes.  A cbl_key_t is a list of field pointers,
- * and can be created ad hoc to describe a sort. We can construct a
+ * and can be created ad hoc to describe a sort. We construct a
  * cbl_key_t from cbl_occurs_key_t.
  */
 cbl_key_t::
 cbl_key_t( const cbl_occurs_key_t& that )
   : ascending(that.ascending)
 {
-  if( that.field_list.nfield == 0 ) {
-    *this = cbl_key_t();
-    return;
-  }
-
-  nfield = that.field_list.nfield;
-  fields = static_cast<cbl_field_t**>( xcalloc(nfield,
-                                                   sizeof(*fields)) );
-  for( size_t i=0; i < that.field_list.nfield; i++ ) {
-    fields[i] = cbl_field_of(symbol_at(that.field_list.fields[i]));
-  }
+  std::transform( that.field_list.fields,
+                  that.field_list.fields + that.field_list.nfield,
+                  std::back_inserter(fields),
+                  []( size_t isym ) {
+                    return cbl_field_of(symbol_at(isym));
+                  } );
 }
 
 void
@@ -4277,7 +4277,7 @@ cbl_occurs_t::key_alloc( bool ascending ) {
 }
 
 void
-cbl_occurs_t::field_add( cbl_field_list_t& field_list, cbl_field_t *field ) {
+cbl_occurs_t::field_add( cbl_field_list_t& field_list, const cbl_field_t *field ) {
   cbl_field_list_t list = field_list;
   size_t ifield = field_index(field);
   auto nbytes = sizeof(list.fields[0]) * (list.nfield + 1);
@@ -4295,14 +4295,14 @@ cbl_occurs_t::key_field_add( cbl_field_t *field ) {
 }
 
 void
-cbl_occurs_t::index_add( cbl_field_t *field ) {
+cbl_occurs_t::index_add( const cbl_field_t *field ) {
   field_add(indexes, field);
 }
 
 class is_field_at {
   cbl_field_t *field;
  public:
- is_field_at( cbl_field_t *field ) : field(field) {}
explicit is_field_at( cbl_field_t *field ) : field(field) {}
   bool operator()( size_t isym ) const  {
     return field == field_at(isym);
   }
@@ -4470,11 +4470,11 @@ cbl_file_key_t::deforward( size_t ifile ) {
   const auto file = cbl_file_of(symbol_at(ifile));
   std::transform( fields, fields + nfield, fields,
                   [ifile, file]( size_t fwd ) {
-                    static std::map<size_t, int> keys;
                     auto ifield = symbol_forward_to(fwd);
                     const auto field = cbl_field_of(symbol_at(ifield));
 
                     if( is_forward(field) && yydebug ) {
+                      static std::map<size_t, int> keys;
                       dbgmsg("%s:%d: key %d: #" HOST_SIZE_T_PRINT_UNSIGNED " %s of %s is %s",
                             "deforward", __LINE__,
                             keys[ifile]++, (fmt_size_t)ifield, field->name, file->name,
@@ -4561,27 +4561,12 @@ cbl_file_t::deforward() {
 
 char *
 cbl_file_t::keys_str() const {
-  std::vector <char *> ks(nkey);
-  std::transform(keys, keys + nkey, ks.begin(),
-                 []( const cbl_file_key_t& key ) {
-                   return key.str();
-                 } );
-  size_t n = 4 * nkey + std::accumulate(ks.begin(), ks.end(), 0,
-                                        []( int n, const char *s ) {
-                                          return n +  strlen(s);
-                                        } );
-  char *output = static_cast<char*>( xcalloc(1, n) ), *p = output;
-  const char *sep = "";
-
-  *p++ = '[';
-  for( auto k : ks ) {
-    p = stpcpy(p, sep);
-    p = stpcpy(p, k);
-    sep = ", ";
-    free(k);
+  std::string names = "[";
+  for( cbl_file_key_t *p = keys;  p < keys + nkey; p++ ) {
+    names += p->str();
+    names += p + 1 < keys + nkey ? "," : "]";
   }
-  *p++ = ']';
-  return output;
+  return xasprintf("%s", names.c_str());
 }
 
 /*
@@ -4643,7 +4628,7 @@ cbl_file_status_cmp( const void *K, const void *E ) {
 static long
 file_status_status_of( file_status_t status ) {
   size_t n = COUNT_OF(file_status_fields);
-  file_status_field_t *fs, key { status };
+  const file_status_field_t *fs, key { status };
 
   fs = (file_status_field_t*)lfind( &key, file_status_fields,
                                     &n, sizeof(*fs), cbl_file_status_cmp );
@@ -4673,7 +4658,7 @@ ast_file_status_between( file_status_t lower, file_status_t upper ) {
 }
 
 bool
-is_register_field(cbl_field_t *field)
+is_register_field(const cbl_field_t *field)
   {
   // TRUE when the field is an executable-level global variable of the type we
   // are calling a "register", like RETURN-CODE or UPSI or the like:
index 154c9fe67f0459f6a4c44bd0386114994945c74c..84a984e6ba650ecde0f4f3aed0079dad25df3bd1 100644 (file)
@@ -264,7 +264,18 @@ struct cbl_field_data_t {
     explicit etc_t( tree v = build_zero_cst (float128_type_node)) : value(v) {}
   } etc;
 
-  cbl_field_data_t( uint32_t memsize=0,  uint32_t capacity=0 )
+  cbl_field_data_t()
+    : memsize(0)
+    , capacity(0)
+    , digits(0)
+    , rdigits(0)
+    , initial(0)
+    , picture(0)
+    , etc_type(value_e)
+    , etc()
+  {}
+
+  cbl_field_data_t( uint32_t memsize,  uint32_t capacity )
     : memsize(memsize)
     , capacity(capacity)
     , digits(0)
@@ -327,6 +338,10 @@ struct cbl_field_data_t {
     etc_type = value_e;
     return etc.value = v;
   } 
+  tree& operator=(int i) {
+    etc_type = value_e;
+    return etc.value = build_int_cst_type(integer_type_node, i);
+  } 
 
   void set_real_from_capacity( REAL_VALUE_TYPE *r ) const {
     real_from_integer (r, VOIDmode, capacity, SIGNED);
@@ -412,8 +427,11 @@ struct cbl_occurs_bounds_t {
   // variable size table.  lower can be zero.
   size_t lower, upper;
 
-  cbl_occurs_bounds_t(size_t lower=0, size_t upper=0)
+  cbl_occurs_bounds_t()
+    : lower(0), upper(0) {}
+  explicit cbl_occurs_bounds_t(size_t lower, size_t upper=0)
     : lower(lower), upper(upper) {}
+
   size_t ntimes() const {
     return upper;
   }
@@ -446,12 +464,12 @@ struct cbl_occurs_t {
 
   void key_alloc( bool ascending );
   void key_field_add( cbl_field_t *field );
-  void index_add( cbl_field_t *field );
+  void index_add( const cbl_field_t *field );
   cbl_occurs_key_t * key_of( cbl_field_t *field );
   bool subscript_ok( const cbl_field_t *subscript ) const;
 
 protected:
-  void field_add( cbl_field_list_t& fields, cbl_field_t *field );
+  void field_add( cbl_field_list_t& fields, const cbl_field_t *field );
 };
 
 /*
@@ -655,50 +673,64 @@ struct cbl_refer_t {
   cbl_field_t *field;
   cbl_label_t *prog_func;
   bool all, addr_of;
-  uint32_t nsubscript;
-  cbl_refer_t *subscripts;  // indices
+  std::vector<cbl_refer_t> subscripts;  // indices
   cbl_span_t refmod;        // substring bounds
 
   cbl_refer_t()
     : loc(), field(NULL), prog_func(NULL)
     , all(NULL), addr_of(false)
-    , nsubscript(0), subscripts(NULL), refmod(NULL)
+    , refmod(NULL)
   {}
+  // cppcheck-suppress noExplicitConstructor
   cbl_refer_t( cbl_field_t *field, bool all = false )
     : loc(), field(field), prog_func(NULL)
     , all(all), addr_of(false)
-    , nsubscript(0), subscripts(NULL), refmod(NULL)
+    , refmod(NULL)
   {}
   cbl_refer_t( const YYLTYPE& loc, cbl_field_t *field, bool all = false )
     : loc(loc), field(field), prog_func(NULL)
     , all(all), addr_of(false)
-    , nsubscript(0), subscripts(NULL), refmod(NULL)
+    , refmod(NULL)
   {}
   cbl_refer_t( cbl_field_t *field, cbl_span_t& refmod )
     : loc(), field(field), prog_func(NULL)
     , all(false), addr_of(false)
-    , nsubscript(0), subscripts(NULL), refmod(refmod)
+    , refmod(refmod)
   {}
   cbl_refer_t( cbl_field_t *field,
-               size_t nsubscript, cbl_refer_t *subscripts,
+               const std::vector<cbl_refer_t>& subscripts,
                cbl_span_t refmod = cbl_span_t(NULL) )
     : loc(), field(field), prog_func(NULL)
     , all(false), addr_of(false)
-    , nsubscript(nsubscript) , subscripts( new cbl_refer_t[nsubscript] )
+    , subscripts(subscripts)
     , refmod(refmod)
-  {
-    std::copy(subscripts, subscripts + nsubscript, this->subscripts);
-  }
+  {}
   explicit cbl_refer_t( cbl_label_t *prog_func, bool addr_of = true )
     : loc(), field(NULL), prog_func(prog_func)
     , all(false), addr_of(addr_of)
-    , nsubscript(0), subscripts(NULL), refmod(cbl_span_t(NULL))
+    , refmod(cbl_span_t(NULL))
   {}
 
+  cbl_refer_t( const cbl_refer_t& that ) = default;
+
+  cbl_refer_t& operator=( const cbl_refer_t& that ) {
+    loc = that.loc;
+    field = that.field;
+    prog_func = that.prog_func;
+    all = that.all;
+    addr_of = that.addr_of;
+    subscripts = that.subscripts;
+    refmod = that.refmod;
+    return *this;
+  }
+    
+  
   cbl_refer_t duplicate() const {
-    return cbl_refer_t( field, nsubscript, subscripts, refmod );
+    return cbl_refer_t( field, subscripts, refmod );
   }
 
+  uint32_t nsubscript() const { return subscripts.size(); }
+
   static cbl_refer_t *empty();
 
   cbl_refer_t * name( const char name[] ) {
@@ -709,8 +741,8 @@ struct cbl_refer_t {
   }
 
   bool is_pointer() const { return addr_of || field->type == FldPointer; }
-  bool is_reference() const { return nsubscript > 0 || refmod.is_active(); }
-  bool is_table_reference() const  { return nsubscript > 0; }
+  bool is_reference() const { return nsubscript() > 0 || refmod.is_active(); }
+  bool is_table_reference() const  { return nsubscript() > 0; }
   bool is_refmod_reference() const  { return refmod.is_active(); }
 
   size_t subscripts_set( const std::list<cbl_refer_t>& subs );
@@ -775,7 +807,7 @@ struct field_key_t {
   }
 };
 
-bool valid_move( const struct cbl_field_t *tgt, const struct cbl_field_t *src );
+bool valid_move( const cbl_field_t *tgt, const cbl_field_t *src );
 
 #define record_area_name_stem "_ra_"
 
@@ -785,8 +817,7 @@ is_record_area( const cbl_field_t *field ) {
   return 0 == memcmp(field->name, stem, sizeof(stem)-1);
 }
 
-bool
-is_register_field(cbl_field_t *field);
+bool is_register_field( const cbl_field_t *field );
 
 static inline bool
 is_constant( const cbl_field_t *field ) {
@@ -804,17 +835,20 @@ symbol_field_type_update( cbl_field_t *field,
                           cbl_field_type_t type, bool is_usage );
 
 struct sort_key_t;
+struct sort_key_t;
 
 struct cbl_key_t {
   bool ascending;
-  size_t nfield;
-  cbl_field_t **fields;
+  std::vector<const cbl_field_t*> fields;
 
-  cbl_key_t() : ascending(false), nfield(0), fields(0) {}
-  cbl_key_t( size_t nfield, cbl_field_t **fields, bool ascending = true )
-    : ascending(ascending), nfield(nfield), fields(fields) {}
-  cbl_key_t( const sort_key_t& src );
+  cbl_key_t() : ascending(true) {}
+  explicit cbl_key_t( sort_key_t src );
   explicit cbl_key_t( const cbl_occurs_key_t& that );
+  cbl_key_t( size_t nfield, cbl_field_t **fields, bool ascending = true )
+    : ascending(ascending)
+    , fields(fields, fields + nfield)
+  {}
+  cbl_key_t& operator=( const sort_key_t& that );
 };
 
 enum cbl_label_type_t {
@@ -911,8 +945,12 @@ struct cbl_substitute_t {
   subst_fl_t first_last;
   cbl_refer_t orig, replacement;
 
-  cbl_substitute_t( bool anycase = false, char first_last = 0,
-                    cbl_refer_t *orig = NULL, cbl_refer_t *replacement = NULL )
+  cbl_substitute_t()
+    : anycase(false)
+    , first_last(subst_all_e)
+  {}
+  cbl_substitute_t( bool anycase, char first_last,
+                    cbl_refer_t *orig, cbl_refer_t *replacement )
     : anycase(anycase)
     , first_last(subst_fl_t(first_last))
     , orig( orig? *orig : cbl_refer_t() )
@@ -945,7 +983,10 @@ struct cbl_num_result_t {
   enum cbl_round_t rounded;
   struct cbl_refer_t refer;
 
-  static cbl_refer_t refer_of( const cbl_num_result_t& res ) { return res.refer; }
+  static const cbl_refer_t&
+  refer_of( const cbl_num_result_t& res ) {
+    return res.refer;
+  }
 };
 
 void parser_symbol_add( struct cbl_field_t *new_var );
@@ -957,8 +998,9 @@ struct cbl_ffi_arg_t {
   cbl_ffi_arg_attr_t attr;
   cbl_refer_t refer; // refer::field == NULL is OMITTED
 
-  cbl_ffi_arg_t( cbl_refer_t* refer = NULL,
-                 cbl_ffi_arg_attr_t attr = none_of_e );
+  cbl_ffi_arg_t();
+  cbl_ffi_arg_t( cbl_refer_t* refer,
+                 cbl_ffi_arg_attr_t attr );
   cbl_ffi_arg_t( cbl_ffi_crv_t crv,
                  cbl_refer_t* refer,
                  cbl_ffi_arg_attr_t attr = none_of_e );
@@ -1171,7 +1213,8 @@ class temporaries_t {
   struct literal_an {
     bool is_quoted;
     std::string value;
-    literal_an( const char value[] = "???", bool is_quoted = false )
+    literal_an() : is_quoted(false), value("???") {}
+    literal_an( const char value[], bool is_quoted )
       : is_quoted(is_quoted), value(value) {}
     literal_an& operator=( const literal_an& that ) {
       is_quoted = that.is_quoted;
@@ -1513,9 +1556,19 @@ struct cbl_file_key_t {
   cbl_name_t name;
   size_t leftmost; // START or READ named leftmost field in key
   size_t nfield;
-  size_t *fields;
+  size_t *fields; // cppcheck-suppress unsafeClassCanLeak
+
+  cbl_file_key_t()
+    : unique(true)
+    , leftmost(0)
+    , nfield(0)
+    , fields(nullptr)
+  {
+    memset(name, '\0', sizeof(name));
+  }
 
-  cbl_file_key_t( size_t field = 0, bool unique = true )
+  // Construct a key of length 1 having a single field. 
+  explicit cbl_file_key_t( size_t field, bool unique = true )
     : unique(unique)
     , leftmost(0)
     , nfield(1)
@@ -1529,6 +1582,29 @@ struct cbl_file_key_t {
                   const std::list<cbl_field_t *>& fields,
                   bool is_unique );
 
+  // The copy constructor and assignment operator exist to quell reports from
+  // cppcheck. When these objects are copied, the copy still points to the
+  // original data.
+  cbl_file_key_t( const cbl_file_key_t& that )
+    : unique(that.unique)
+    , leftmost(that.leftmost)
+    , nfield(that.nfield)
+      // cppcheck-suppress copyCtorPointerCopying
+    , fields(that.fields)
+  {
+    strcpy(name, that.name);
+  }
+  ~cbl_file_key_t() {}
+  cbl_file_key_t& operator=( const cbl_file_key_t& that ) {
+    unique = that.unique;
+    leftmost = that.leftmost;
+    nfield = that.nfield;
+    // cppcheck-suppress copyCtorPointerCopying
+    fields = that.fields;
+    strcpy(name, that.name);
+    return *this;
+  }
+
   uint32_t size();
   void deforward( size_t ifile );
   char * str() const;
@@ -1542,12 +1618,12 @@ struct cbl_file_key_t {
 struct cbl_file_lock_t {
   bool multiple;
   enum lock_mode_t { unlocked_e, manual_e, record_e, automatic_e } mode;
+  cbl_file_lock_t() : multiple(false), mode(unlocked_e) {}
   bool mode_set( int token );
   bool locked() const { return mode != unlocked_e; }
 };
 
 struct cbl_file_t {
-  static cbl_file_key_t no_key;
   enum cbl_file_org_t org;
   enum file_entry_type_t entry_type;
   uint32_t attr;
@@ -1574,15 +1650,32 @@ struct cbl_file_t {
   tree var_decl_node;           // GENERIC tag for the run-time FIELD structure
 
   cbl_file_t()
-    : org(file_disorganized_e),
-      access(file_access_seq_e)
+    : org(file_disorganized_e)
+    , entry_type(fd_e)
+    , attr(0), reserve(0), same_record_as(0)
+    , padding('\0')
+    , optional(false)
+    , varying_size{ false, 0, 0 }
+    , access(file_access_seq_e)
+    , filename(0)
+    , default_record(0)
+    , nkey(0)
+    , keys(nullptr)
+    , password(0), user_status(0), vsam_status(0), record_length(0)
+    , line(0)
+    , addresses(nullptr)
+    , var_decl_node(nullptr)
   {
-    keys = &no_key;
+    memset(name, '\0', sizeof(name));
   }
   
   bool varies() const { return varying_size.min != varying_size.max; }
   bool validate() const;
   void deforward();
+  cbl_file_key_t * keys_update( cbl_file_key_t * keys ) {
+    if( this->keys ) delete[] this->keys;
+    return this->keys = keys;
+  }
   char * keys_str() const;
   int  key_one( cbl_field_t *field ) const {
     auto ekey = keys + nkey, p = ekey;
@@ -1630,7 +1723,8 @@ struct symbol_elem_t {
     symbol_elem_u() : field() {}
   } elem;
   
-  symbol_elem_t( symbol_type_t type = SymField, size_t program = 0 )
+  symbol_elem_t() : type(SymField), program(0) {}
+  explicit symbol_elem_t( symbol_type_t type, size_t program = 0 )
     : type(type), program(program)
   {}
 
@@ -1700,6 +1794,7 @@ static inline symbol_elem_t *
 symbol_elem_of( cbl_label_t *label ) {
   size_t n = offsetof(struct symbol_elem_t, elem.label);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<struct symbol_elem_t *>((char*)label - n);
 }
 
@@ -1707,6 +1802,7 @@ static inline const symbol_elem_t *
 symbol_elem_of( const cbl_label_t *label ) {
   size_t n = offsetof(symbol_elem_t, elem.label);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<const symbol_elem_t *>((const char*)label - n);
 }
 
@@ -1714,6 +1810,7 @@ static inline symbol_elem_t *
 symbol_elem_of( cbl_special_name_t *special ) {
   size_t n = offsetof(symbol_elem_t, elem.special);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<symbol_elem_t *>((char*)special - n);
 }
 
@@ -1721,6 +1818,7 @@ static inline symbol_elem_t *
 symbol_elem_of( cbl_alphabet_t *alphabet ) {
   size_t n = offsetof(symbol_elem_t, elem.alphabet);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<symbol_elem_t *>((char*)alphabet - n);
 }
 
@@ -1728,12 +1826,14 @@ static inline symbol_elem_t *
 symbol_elem_of( cbl_file_t *file ) {
   size_t n = offsetof(struct symbol_elem_t, elem.file);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<struct symbol_elem_t *>((char*)file - n);
 }
 static inline const symbol_elem_t *
 symbol_elem_of( const cbl_file_t *file ) {
   size_t n = offsetof(symbol_elem_t, elem.file);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<const symbol_elem_t *>((const char*)file - n);
 }
 
@@ -1741,18 +1841,20 @@ static inline symbol_elem_t *
 symbol_elem_of( cbl_field_t *field ) {
   size_t n = offsetof(struct symbol_elem_t, elem.field);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<struct symbol_elem_t *>((char*)field - n);
 }
 static inline const symbol_elem_t *
 symbol_elem_of( const cbl_field_t *field ) {
   size_t n = offsetof(symbol_elem_t, elem.field);
   return
+    // cppcheck-suppress cstyleCast
     reinterpret_cast<const symbol_elem_t *>((const char*)field - n);
 }
 
 symbol_elem_t * symbols_begin( size_t first = 0 );
 symbol_elem_t * symbols_end(void);
-cbl_field_t   * symbol_redefines( const struct cbl_field_t *field );
+cbl_field_t   * symbol_redefines( const cbl_field_t *field );
 
 void build_symbol_map();
 bool update_symbol_map( symbol_elem_t *e );
@@ -1768,7 +1870,7 @@ symbol_find( size_t program, std::list<const char *> names );
 symbol_elem_t * symbol_find_of( size_t program,
                                 std::list<const char *> names, size_t group );
 
-struct cbl_field_t *symbol_find_odo( cbl_field_t * field );
+struct cbl_field_t *symbol_find_odo( const cbl_field_t * field );
 size_t dimensions( const cbl_field_t *field );
 
 const symbol_elem_t * symbol_field_current_record();
@@ -1792,54 +1894,54 @@ bool redefine_field( cbl_field_t *field );
 
 static inline struct cbl_section_t *
 cbl_section_of( struct symbol_elem_t *e ) {
-  assert(e->type == SymDataSection);
+  assert(e && e->type == SymDataSection);
   return &e->elem.section;
 }
 
 static inline struct cbl_field_t *
 cbl_field_of( struct symbol_elem_t *e ) {
-  assert(e->type == SymField);
+  assert(e && e->type == SymField);
   return &e->elem.field;
 }
-static inline const struct cbl_field_t *
-cbl_field_of( const struct symbol_elem_t *e ) {
-  assert(e->type == SymField);
+static inline const cbl_field_t *
+cbl_field_of( const symbol_elem_t *e ) {
+  assert(e && e->type == SymField);
   return &e->elem.field;
 }
 
 static inline struct cbl_label_t *
 cbl_label_of( struct symbol_elem_t *e ) {
-  assert(e->type == SymLabel);
+  assert(e && e->type == SymLabel);
   return &e->elem.label;
 }
 
-static inline const struct cbl_label_t *
-cbl_label_of( const struct symbol_elem_t *e ) {
-  assert(e->type == SymLabel);
+static inline const cbl_label_t *
+cbl_label_of( const symbol_elem_t *e ) {
+  assert(e && e->type == SymLabel);
   return &e->elem.label;
 }
 
 static inline struct cbl_special_name_t *
 cbl_special_name_of( struct symbol_elem_t *e ) {
-  assert(e->type == SymSpecial);
+  assert(e && e->type == SymSpecial);
   return &e->elem.special;
 }
 
 static inline struct cbl_alphabet_t *
 cbl_alphabet_of( struct symbol_elem_t *e ) {
-  assert(e->type == SymAlphabet);
+  assert(e && e->type == SymAlphabet);
   return &e->elem.alphabet;
 }
 
 static inline struct cbl_file_t *
 cbl_file_of( struct symbol_elem_t *e ) {
-  assert(e->type == SymFile);
+  assert(e && e->type == SymFile);
   return &e->elem.file;
 }
 
-static inline const struct cbl_file_t *
-cbl_file_of( const struct symbol_elem_t *e ) {
-  assert(e->type == SymFile);
+static inline const cbl_file_t *
+cbl_file_of( const symbol_elem_t *e ) {
+  assert(e && e->type == SymFile);
   return &e->elem.file;
 }
 
@@ -1858,43 +1960,43 @@ is_procedure( const symbol_elem_t& e ) {
 }
 
 static inline bool
-is_figconst(const struct cbl_field_t *field ) {
-    return ((field->attr & FIGCONST_MASK) != 0 );
+is_figconst(const cbl_field_t *field ) {
+    return (field->attr & FIGCONST_MASK) != 0;
 }
 
 static inline bool
-is_figconst_low( const struct cbl_field_t *field ) {
-  return ((field->attr & FIGCONST_MASK) == low_value_e );
+is_figconst_low( const cbl_field_t *field ) {
+  return (field->attr & FIGCONST_MASK) == low_value_e;
 }
 
 static inline bool
-is_figconst_zero( const struct cbl_field_t *field ) {
-  return ((field->attr & FIGCONST_MASK) == zero_value_e );
+is_figconst_zero( const cbl_field_t *field ) {
+  return (field->attr & FIGCONST_MASK) == zero_value_e;
 }
 
 static inline bool
-is_figconst_space( const struct cbl_field_t *field ) {
-  return ((field->attr & FIGCONST_MASK) == space_value_e );
+is_figconst_space( const cbl_field_t *field ) {
+  return (field->attr & FIGCONST_MASK) == space_value_e;
 }
 
 static inline bool
-is_figconst_quote( const struct cbl_field_t *field ) {
-  return ((field->attr & FIGCONST_MASK) == quote_value_e );
+is_figconst_quote( const cbl_field_t *field ) {
+  return (field->attr & FIGCONST_MASK) == quote_value_e;
 }
 
 static inline bool
-is_figconst_high( const struct cbl_field_t *field ) {
-  return ((field->attr & FIGCONST_MASK) == high_value_e );
+is_figconst_high( const cbl_field_t *field ) {
+  return (field->attr & FIGCONST_MASK) == high_value_e;
 }
 
 static inline bool
-is_space_value( const struct cbl_field_t *field ) {
-  return( (strcmp(field->name, "SPACE") == 0)
-            || (strcmp(field->name, "SPACES") == 0) );
+is_space_value( const cbl_field_t *field ) {
+  return (strcmp(field->name, "SPACE") == 0)
+      || (strcmp(field->name, "SPACES") == 0);
 }
 
 static inline bool
-is_quoted( const struct cbl_field_t *field ) {
+is_quoted( const cbl_field_t *field ) {
   return field->has_attr(quoted_e);
 }
 
@@ -1922,7 +2024,7 @@ struct cbl_until_addresses_t {
 };
 
 size_t symbol_index(); // nth after first program symbol
-size_t symbol_index( const struct symbol_elem_t *e );
+size_t symbol_index( const symbol_elem_t *e );
 struct symbol_elem_t * symbol_at( size_t index );
 
 struct cbl_options_t {
@@ -1974,17 +2076,20 @@ symbol_field_forward_add( size_t program, size_t parent,
 struct cbl_field_t * symbol_field_forward( size_t index );
 
 struct cbl_prog_hier_t {
-  size_t nlabel;
   struct program_label_t {
     size_t ordinal;
     cbl_label_t label;
     program_label_t() : ordinal(0), label() {}
-    program_label_t( const symbol_elem_t& e ) {
+    // because std::copy_if:
+    // cppcheck-suppress noExplicitConstructor 
+    program_label_t( const symbol_elem_t& e ) { 
+      assert(is_program(e));
       ordinal = symbol_index(&e);
       label = e.elem.label;
     }
-  } *labels;
-
+  };
+  std::vector<program_label_t> labels;
+  
   cbl_prog_hier_t();
 };
 
@@ -2038,10 +2143,11 @@ struct cbl_perform_vary_t {
   struct cbl_refer_t  by;       // numeric
   struct cbl_field_t *until;    // FldConditional
 
-  cbl_perform_vary_t( const cbl_refer_t& varying = cbl_refer_t(),
-                      const cbl_refer_t& from = cbl_refer_t(),
-                      const cbl_refer_t& by = cbl_refer_t(),
-                      cbl_field_t *until = NULL )
+  cbl_perform_vary_t() : until(nullptr) {}
+  cbl_perform_vary_t( const cbl_refer_t& varying,
+                      const cbl_refer_t& from,
+                      const cbl_refer_t& by,
+                      cbl_field_t *until )
     : varying(varying)
     , from(from)
     , by(by)
@@ -2063,12 +2169,12 @@ is_literal( const cbl_field_t *field ) {
 }
 
 static inline bool
-is_signable( const struct cbl_field_t *field ) {
+is_signable( const cbl_field_t *field ) {
   return field->attr & signable_e;
 }
 
 static inline bool
-is_temporary( const struct cbl_field_t *field ) {
+is_temporary( const cbl_field_t *field ) {
   return field->attr & intermediate_e;
 }
 
@@ -2203,7 +2309,7 @@ struct symbol_elem_t * symbol_special( size_t program, const char name[] );
 struct symbol_elem_t * symbol_alphabet( size_t program, const char name[] );
 
 struct symbol_elem_t * symbol_file( size_t program, const char name[] );
-struct cbl_field_t   * symbol_file_record( struct cbl_file_t *file );
+struct cbl_field_t   * symbol_file_record( const cbl_file_t *file );
 cbl_file_t::varying_t symbol_file_record_sizes( struct cbl_file_t *file );
 struct cbl_section_t * symbol_section( size_t program,
                                        struct cbl_section_t *section );
@@ -2213,7 +2319,7 @@ size_t symbol_label_id( const cbl_label_t *label );
 struct cbl_field_t * parent_of( const cbl_field_t *f );
  const cbl_field_t * occurs_in( const cbl_field_t *f );
 
-cbl_field_t *rename_not_ok( cbl_field_t *first, cbl_field_t *last);
+cbl_field_t *rename_not_ok( const cbl_field_t *first, const cbl_field_t *last);
 bool immediately_follows( const cbl_field_t *first );
 bool is_variable_length( const cbl_field_t *field );
 
@@ -2226,7 +2332,7 @@ uint64_t numeric_group_attrs( const cbl_field_t *field );
 static inline struct cbl_field_t *
 field_at( size_t index ) {
   struct symbol_elem_t *e = symbol_at(index);
-  assert(e->type == SymField);
+  assert(e && e->type == SymField);
 
   return &e->elem.field;
 }
@@ -2288,8 +2394,9 @@ class procref_base_t {
 private:
   const char *section_name, *paragraph_name;
 public:
-  procref_base_t( const char *section_name = NULL,
-                  const char *paragraph_name = NULL )
+  procref_base_t() : section_name(nullptr) , paragraph_name(nullptr) {}
+  procref_base_t( const char *section_name,
+                  const char *paragraph_name )
     : section_name(section_name)
     , paragraph_name(paragraph_name)
   {}
@@ -2356,7 +2463,7 @@ refer_type_str( const cbl_refer_t *r ) {
 
 enum cbl_field_type_t symbol_field_type( size_t program, const char name[] );
 
-struct symbol_elem_t * symbol_parent( const struct symbol_elem_t *e );
+struct symbol_elem_t * symbol_parent( const symbol_elem_t *e );
 
 int length_of_picture(const char *picture);
 int rdigits_of_picture(const char *picture);
index 224f3ff6cf95f5badd8ad317460b89c325bcc4b9..39df2a0390e62b9d642822d697984e973e6481f0 100644 (file)
@@ -48,7 +48,7 @@ extern int yydebug;
 static bool
 is_data_field( symbol_elem_t& e ) {
   if( e.type != SymField ) return false;
-  auto f = cbl_field_of(&e);
+  const auto f = cbl_field_of(&e);
   if( f->name[0] == '\0' ) return false;
   if( is_filler(f) ) return false;
 
@@ -129,7 +129,7 @@ finalize_symbol_map2() {
   for( auto& elem : symbol_map2 ) {
     auto& fields( elem.second );
     fields.remove_if( []( auto isym ) {
-                       auto f = cbl_field_of(symbol_at(isym));
+                       const auto f = cbl_field_of(symbol_at(isym));
                        return f->type == FldInvalid;
                      } );
     if( fields.empty() ) empties.insert(elem.first);
@@ -341,7 +341,7 @@ class in_scope {
   size_t program;
 
   static size_t prog_of( size_t program ) {
-    auto L = cbl_label_of(symbol_at(program));
+    const auto L = cbl_label_of(symbol_at(program));
     return L->parent;
   }
 
@@ -350,7 +350,7 @@ public:
 
   // A symbol is in scope if it's defined by this program or by an ancestor.
   bool operator()( const symbol_map_t::value_type& item ) const {
-    symbol_elem_t *e = symbol_at(item.second.front());
+    const symbol_elem_t *e = symbol_at(item.second.front());
     for( size_t prog = this->program; prog != 0; prog = prog_of(prog) ) {
       if( e->program == prog ) return true;
     }
@@ -430,7 +430,7 @@ symbol_match2( size_t program,
   auto plist = symbol_map2.find(key);
   if( plist != symbol_map2.end() ) {
     for( auto candidate : plist->second ) {
-      auto e = symbol_at(candidate);
+      const auto e = symbol_at(candidate);
       if( name_has_names( e, names, local ) ) {
         fields.push_back( symbol_index(e) );
       }
index 682d68df2dc3a3aa2524c739976180f1b5fe2a2c..4b24fc67769cd0a9de32466a60f51cfe8d6db072 100644 (file)
@@ -691,6 +691,7 @@ tokens = {
        { "neg", NEG }, // 939
 };
 
+// cppcheck-suppress useInitializationList
 token_names = {
        "IDENTIFICATION", // 0 (258)
        "ENVIRONMENT", // 1 (259)
index 82a72f5f00a67135d4330eac46ae0940241704f9..b6c92802c791995aefe9bc19c49e6d533b526f98 100644 (file)
@@ -365,51 +365,50 @@ normalize_picture( char picture[] )
     regmatch_t pmatch[4];
 
     if( (erc = regcomp(preg, regex, cflags)) != 0 ) {
-        regerror(erc, preg, regexmsg, sizeof(regexmsg));
-        dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg );
-        return picture;
+      regerror(erc, preg, regexmsg, sizeof(regexmsg));
+      dbgmsg( "%s:%d: could not compile regex: %s", __func__, __LINE__, regexmsg );
+      return picture;
     }
 
     while( (erc = regexec(preg, picture, COUNT_OF(pmatch), pmatch, 0)) == 0 ) {
-        assert(pmatch[1].rm_so != -1 && pmatch[1].rm_so < pmatch[1].rm_eo);
-        size_t len = pmatch[1].rm_eo - pmatch[1].rm_so;
-        assert(len == 1);
-        const char *start = picture + pmatch[1].rm_so;
-
-        assert(pmatch[2].rm_so != -2 && pmatch[2].rm_so < pmatch[2].rm_eo);
-        len = pmatch[2].rm_eo - pmatch[2].rm_so;
-        assert(len > 0);
-
-        /*
-         * Overwrite e.g. A(4) with AAAA.
-         */
-        assert(pmatch[2].rm_so == pmatch[1].rm_eo + 1); // character paren number
-        p = picture + pmatch[2].rm_so;
-        len = 0;
-        fmt_size_t lenf = 0;
-        if( 1 != sscanf(p, "%" GCC_PRISZ "u", &lenf) ) {
-            dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p);
-            goto irregular;
-        }
-        len = lenf;
-        if( len == 0 ) {
-            dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p);
-            goto irregular;
-        }
+      assert(pmatch[1].rm_so != -1 && pmatch[1].rm_so < pmatch[1].rm_eo);
+      size_t len = pmatch[1].rm_eo - pmatch[1].rm_so;
+      assert(len == 1);
+      const char *start = picture + pmatch[1].rm_so;
+
+      assert(pmatch[2].rm_so != -2 && pmatch[2].rm_so < pmatch[2].rm_eo);
+      len = pmatch[2].rm_eo - pmatch[2].rm_so;
+      assert(len > 0);
+
+      /*
+       * Overwrite e.g. A(4) with AAAA.
+       */
+      assert(pmatch[2].rm_so == pmatch[1].rm_eo + 1); // character paren number
+      p = picture + pmatch[2].rm_so;
+      len = 0;
+      fmt_size_t lenf = 0;
+      if( 1 != sscanf(p, "%" GCC_PRISZ "u", &lenf) ) {
+        dbgmsg("%s:%d: no number found in '%s'", __func__, __LINE__, p);
+        goto irregular;
+      }
+      len = lenf;
+      if( len == 0 ) {
+        dbgmsg("%s:%d: ZERO length found in '%s'", __func__, __LINE__, p);
+        goto irregular;
+      }
 
-       std::vector <char> pic(len + 1, '\0');
-        memset(pic.data(), *start, len);
-        const char *finish = picture + pmatch[2].rm_eo,
-                    *eopicture = picture + strlen(picture);
+      std::vector <char> pic(len + 1, '\0');
+      memset(pic.data(), *start, len);
+      const char *finish = picture + pmatch[2].rm_eo,
+        *eopicture = picture + strlen(picture);
 
-        p = xasprintf( "%*s%s%*s",
-                      (int)(start - picture), picture,
-                      pic.data(),
-                      (int)(eopicture - finish), finish );
+      p = xasprintf( "%*s%s%*s",
+                     (int)(start - picture), picture,
+                     pic.data(),
+                     (int)(eopicture - finish), finish );
 
-        free(picture);
-        picture = p;
-        continue;
+      free(picture);
+      picture = p;
     }
     assert(erc == REG_NOMATCH);
 
@@ -792,7 +791,7 @@ symbol_field_type_update( cbl_field_t *field,
 
 bool
 redefine_field( cbl_field_t *field ) {
-  cbl_field_t *primary = symbol_redefines(field);
+  const cbl_field_t *primary = symbol_redefines(field);
   bool fOK = true;
 
   if( !primary ) return false;
@@ -840,7 +839,7 @@ cbl_field_t::report_invalid_initial_value(const YYLTYPE& loc) const {
         // 8 or more, we need do no further testing because we assume
         // everything fits.
         if( data.capacity < 8 ) {
-          auto p = strchr(data.initial, symbol_decimal_point());
+          const auto p = strchr(data.initial, symbol_decimal_point());
           if( p && atoll(p+1) != 0 ) {
             error_msg(loc, "integer type %s VALUE '%s' "
                      "requires integer VALUE",
@@ -962,8 +961,7 @@ const cbl_field_t *
 literal_subscript_oob( const cbl_refer_t& r, size_t& isub /* output */)  {
   // Verify literal subscripts if dimensions are correct.
   size_t ndim(dimensions(r.field));
-  if( ndim == 0 || ndim != r.nsubscript ) return NULL;
-  cbl_refer_t *esub = r.subscripts + r.nsubscript;
+  if( ndim == 0 || ndim != r.nsubscript() ) return NULL;
   std::vector<cbl_field_t *> dims( ndim, NULL );
   auto pdim = dims.end();
 
@@ -981,22 +979,20 @@ literal_subscript_oob( const cbl_refer_t& r, size_t& isub /* output */)  {
    * for the corresponding dimension.  Return the first subscript not
    * meeting those criteria, if any.
    */
-  auto p = std::find_if( r.subscripts, esub,
-                         [&pdim]( const cbl_refer_t& r ) {
+  auto psub = std::find_if( r.subscripts.begin(), r.subscripts.end(),
+                         [pdim]( const cbl_refer_t& r ) mutable {
                            const auto& occurs((*pdim)->occurs);
                            pdim++;
                            return ! occurs.subscript_ok(r.field);
                          } );
-  isub = p - r.subscripts;
-  return p == esub? NULL : dims[isub];
+  isub = psub - r.subscripts.begin(); 
+  return psub == r.subscripts.end()? NULL : dims[isub];
 }
 
 size_t
 cbl_refer_t::subscripts_set( const std::list<cbl_refer_t>& subs ) {
-  nsubscript = subs.size();
-  subscripts = new cbl_refer_t[nsubscript];
-  std::copy( subs.begin(), subs.end(), subscripts );
-
+  subscripts.clear();
+  std::copy( subs.begin(), subs.end(), std::back_inserter(subscripts) );
   return dimensions(field);
 }
 
@@ -1004,7 +1000,7 @@ const char *
 cbl_refer_t::str() const {
   static char subscripts[64];
   sprintf(subscripts, "(%u of " HOST_SIZE_T_PRINT_UNSIGNED " dimensions)",
-          nsubscript, (fmt_size_t)dimensions(field));
+          nsubscript(), (fmt_size_t)dimensions(field));
   char *output = xasprintf("%s %s %s",
                            field? field_str(field) : "(none)",
                            0 < dimensions(field)? subscripts : "",
@@ -1020,18 +1016,18 @@ cbl_refer_t::name() const {
 
 const char *
 cbl_refer_t::deref_str() const {
-  std::vector<char> dimstr(nsubscript * 16, '\0');
+  std::vector<char> dimstr(nsubscript() * 16, '\0');
   dimstr.at(0) = '(';
   auto p = dimstr.begin() + 1;
 
   if( !field ) return name();
 
-  for( auto sub = subscripts; sub <  subscripts + nsubscript; sub++ ) {
-    auto initial = sub->field->data.initial ? sub->field->data.initial : "?";
+  for( const auto& sub : subscripts ) {
+    auto initial = sub.field->data.initial ? sub.field->data.initial : "?";
     size_t len = dimstr.end() - p;
     p += snprintf( &*p, len, "%s ", initial );
   }
-  if( 0 < nsubscript ) {
+  if( ! subscripts.empty() ) {
     *--p = ')';
   }
   char *output = xasprintf("%s%s", field->name, dimstr.data());
@@ -1383,7 +1379,7 @@ public:
   {
     assert(isym);
   }
-  procdef_t( const procref_base_t& ref )
+  explicit procdef_t( const procref_base_t& ref )
     : procref_base_t(ref)
     , isym(0)
   {}
@@ -1392,13 +1388,6 @@ public:
     return procref_base_t(*this) < procref_base_t(that);
   }
 
-  bool operator<( const procref_base_t& that ) const {
-    if( that.has_section() ) {
-      return procref_base_t(*this) < that;
-    }
-    return strcasecmp(paragraph(), that.paragraph()) < 0;
-  }
-
   cbl_label_t * label_of() const {
     return isym == 0? NULL : cbl_label_of(symbol_at(isym));
   }
@@ -1429,7 +1418,7 @@ static procedures_t::iterator current_procedure = programs.end()->second.end();
 class procedure_match {
   const procref_base_t& ref;
 public:
-  procedure_match( const procref_base_t& ref ) : ref(ref) {}
+  explicit procedure_match( const procref_base_t& ref ) : ref(ref) {}
   // Match a 2-name reference to section & paragraph, else to one or the other.
   bool operator()( procedures_t::const_reference elem ) {
     const procdef_t& key = elem.first;
@@ -1457,7 +1446,7 @@ locally_unique( size_t program, const procdef_t& key, const procref_t& ref ) {
   const char *section_name = ref.has_section()? ref.section() : key.section();
   procref_base_t full_ref(section_name, ref.paragraph());
 
-  return 1 == procedures.count(full_ref);
+  return 1 == procedures.count(procdef_t(full_ref));
 }
 
 // Add each section and paragraph to the map as it occurs in the Cobol text.
@@ -1519,9 +1508,9 @@ ambiguous_reference( size_t program ) {
     if( proc.second.end() != ambiguous ) {
       if( yydebug ) {
         dbgmsg("%s: %s of '%s' has " HOST_SIZE_T_PRINT_UNSIGNED
-              "potential matches", __func__,
-              ambiguous->paragraph(), ambiguous->section(),
-              (fmt_size_t)procedures.count(*ambiguous));
+               "potential matches", __func__,
+               ambiguous->paragraph(), ambiguous->section(),
+               (fmt_size_t)procedures.count(procdef_t(*ambiguous)));
       }
       return new procref_t(*ambiguous);
     }
@@ -1548,7 +1537,7 @@ intradeclarative_reference() {
 class next_group {
   size_t isym;
 public:
 next_group( symbol_elem_t *group ) : isym(symbol_index(group)) {}
explicit next_group( const symbol_elem_t *group ) : isym(symbol_index(group)) {}
 
   // return true if elem is not a member of the group
   bool operator()( const symbol_elem_t& elem ) {
@@ -1595,7 +1584,7 @@ public:
   static bool
   any_redefines( const cbl_field_t& field, const symbol_elem_t *group ) {
     for( const cbl_field_t *f = &field; f && f->parent > 0; f = parent_of(f) ) {
-      symbol_elem_t *e = symbol_at(f->parent);
+      const symbol_elem_t *e = symbol_at(f->parent);
       if( e == group || e->type != SymField ) break;
       if( symbol_redefines(f) ) return true;
     }
@@ -1796,7 +1785,7 @@ class unique_stack : public std::stack<input_file_t>
   
   bool push( const value_type& value ) {
     auto ok = std::none_of( c.cbegin(), c.cend(),
-                            [value]( auto& that ) {
+                            [value]( const auto& that ) {
                               return value == that;
                                 } );
     if( ok ) {
@@ -1834,7 +1823,7 @@ class unique_stack : public std::stack<input_file_t>
   void print() const {
     std::string input( top().name );
     printf( "%s: ", input.c_str() );
-    for( auto name : all_names ) {
+    for( const auto& name : all_names ) {
       if( name != input ) 
        printf( "\\\n\t%s ", name.c_str() );
     }
@@ -1863,7 +1852,7 @@ void cobol_set_pp_option(int opt) {
  * to enforce uniqueness, and the scanner to maintain line numbers.
  */
 bool cobol_filename( const char *name, ino_t inode ) {
-  line_map *lines = NULL;
+  const line_map *lines = NULL;
   if( inode == 0 ) {
     auto p = old_filenames.find(name);
     if( p == old_filenames.end() ) {
@@ -1943,11 +1932,9 @@ verify_format( const char gmsgid[] ) {
   static regex_t re;
   static int cflags = REG_EXTENDED;
   static int status = regcomp( &re, pattern, cflags );
-  static char errbuf[80];
-
-
 
   if( status != 0 ) {
+    static char errbuf[80];
     int n = regerror(status, &re, errbuf, sizeof(errbuf));
     gcc_assert(size_t(n) < sizeof(errbuf));
     fprintf(stderr, "%s:%d: %s", __func__, __LINE__, errbuf);
@@ -1988,7 +1975,7 @@ extern YYLTYPE yylloc;
  * the global token_location, which is passed to the diagnostic framework. The
  * original value is restored when the instantiated variable goes out of scope.
  */
-class temp_loc_t : protected YYLTYPE {
+class temp_loc_t {
   location_t orig;
  public:
   temp_loc_t() : orig(token_location) {
@@ -1996,10 +1983,10 @@ class temp_loc_t : protected YYLTYPE {
 
     gcc_location_set(yylloc); // use lookahead location
   }
-  temp_loc_t( const YYLTYPE& loc) : orig(token_location) {
+  explicit temp_loc_t( const YYLTYPE& loc) : orig(token_location) {
     gcc_location_set(loc);
   }
-  temp_loc_t( const YDFLTYPE& loc) : orig(token_location) {
+  explicit temp_loc_t( const YDFLTYPE& loc) : orig(token_location) {
     YYLTYPE lloc = {
       loc.first_line, loc.first_column,
       loc.last_line,  loc.last_column };
@@ -2246,7 +2233,7 @@ os_locale_t os_locale = { "UTF-8", xstrdup("C.UTF-8") };
 void
 cobol_parse_files (int nfile, const char **files)
 {
-  char * opaque = setlocale(LC_CTYPE, "");
+  const char * opaque = setlocale(LC_CTYPE, "");
   if( ! opaque ) {
     yywarn("setlocale: unable to initialize LOCALE");
   } else {
index 44db645f1409f699d36a4f1ed978525e7b9b0607..54d3930100e4d6b00094bd989b1618229a8568ea 100644 (file)
@@ -50,4 +50,11 @@ const char * cobol_lineno_save();
 
 unsigned long gb4( size_t input );
 
+template <typename P>
+static inline const void *
+as_voidp( P p ) {
+  return static_cast<const void *>(p);
+}
+
+
 #endif
index 7336b15fcf74f86e5883785636a05d549a08a613..a78022ae12439de81ff72c353da4e68efa1c988b 100644 (file)
@@ -570,7 +570,7 @@ class cbl_enabled_exceptions_t : protected std::set<cbl_enabled_exception_t>
     : std::set<cbl_enabled_exception_t>(ecs, ecs + nec)
   {}
   void turn_on_off( bool enabled, bool location, ec_type_t type,
-                    std::set<size_t> files );
+                    const std::set<size_t>& files );
 
   const cbl_enabled_exception_t * match( ec_type_t ec, size_t file = 0 ) const;