cobol/scan.cc: cobol/scan.l
$(FLEX) -o$@ $(LFLAGS) $< 2>$@~ || { cat $@~ >&1; exit 1; }
awk '! /$(FLEX_WARNING)/ {print > "/dev/stderr"; nerr++} \
- END {print "$(FLEX):", NR, "messages" > "/dev/stderr"; \
- exit nerr}' $@~
+ END {print "$(FLEX):", NR, "messages" > "/dev/stderr"}' $@~
@rm $@~
--- /dev/null
+Below is listed work to be done, hopefully all of it in 2025 for
+GCC 16. They are vaguely in priority order, in that addressing more
+technical issues may illuminate ways to attack more amorphous ones.
+
+Portability:
+ - host/target, for cross-compilation
+ - OS portability, BSD, macOS, Solaris
+ - 64-bit portability, LE
+ - 64-bit portability, BE
+ - 2025 goal: Compile & run on primary & secondary GCC 15 platforms
+ https://www.gnu.org/software/gcc/gcc-15/criteria.html
+
+Correctness:
+ - LTO ODR, PR 119215
+ - cppcheck
+ - valgrind
+ - -static produces dynamic
+
+Efficiency:
+ - Code size for MOVE 'a' TO FOO(1,1)
+ - EC checking
+
+COBOL Features:
+ - XML, JSON
+ - MF system functions
+ - National characters (and Unicode, for IBM)
+ - GLOBAL and PERFORM declaratives
+ - dialect feature names (to enable and enumerate)
+
+GCC features:
+ - make check-nist
+ - -Werror, -Wno-<foo>
+ - -fEC-ALL, -fno-EC-I-O
void cbl_unimplemented_at( const YYLTYPE& loc, const char *gmsgid, ... );
/*
- * dbgmsg produce messages not intended for the user. They cannot
- * be localized and fwrite directly to standard out. dbgmsg is activated by
- * -fflex-debug or -fyacc-debug.
+ * dbgmsg produce messages not intended for the user. They cannot be localized
+ * and fwrite directly to standard error. dbgmsg is activated by -fflex-debug
+ * or -fyacc-debug.
*/
void dbgmsg( const char fmt[], ... ) ATTRIBUTE_PRINTF_1;
dbgmsg("found copybook file %s", filename);
this->source.name = xstrdup(filename);
if( ! cobol_filename(this->source.name, inode_of(fd)) ) {
- error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source);
- (void)! close(fd);
- fd = -1;
+ error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source);
+ (void)! close(fd);
+ fd = -1;
}
dbgmsg("%s: opened %s as fd %d", __func__, source.name, fd);
return fd;
}
| copy error {
error_msg(@error, "COPY directive must end in a '.'");
- YYACCEPT;
+ YYABORT;
}
| completes { YYACCEPT; }
;
if( -1 == copybook.open(@src, $src.string) ) {
error_msg(@src, "could not open copybook file "
"for '%s'", $src.string);
- YYERROR;
+ YYABORT;
}
}
| COPY name_one[src] IN name_one[lib]
if( -1 == copybook.open(@src, $src.string) ) {
error_msg(@src, "could not open copybook file "
"for '%s' in '%'s'", $src.string, $lib.string);
- YYERROR;
+ YYABORT;
}
}
;
}
bool
-cdf_value( const char name[], cdfval_t value ) {
+cdf_value( const char name[], const cdfval_t& value ) {
auto p = dictionary.find(name);
if( p != dictionary.end() ) return false;
cdf_value( const char name[] );
bool
-cdf_value( const char name[], cdfval_t value );
+cdf_value( const char name[], const cdfval_t& value );
#endif
struct copybook_loc_t {
YYLTYPE loc;
const char *name;
- copybook_loc_t() : name(NULL) {}
+ copybook_loc_t() : loc(), name(NULL) {}
} source, library;
bool suppress;
static std::list<const char *> suffixes;
copybook_elem_t()
: suppress(false)
+ , literally()
, fd(-1)
, nsubexpr(0)
, regex_text(NULL)
- {
- literally = {};
- }
+ {}
void clear() {
suppress = false;
class uppername_t {
std::string upper;
public:
- uppername_t( const std::string input ) : upper(input) {
+ explicit uppername_t( const std::string& input ) : upper(input) {
std::transform(input.begin(), input.end(), upper.begin(),
[]( char ch ) { return TOUPPER(ch); } );
}
ec_type_descr( ec_type_t type ) {
auto p = std::find( __gg__exception_table, __gg__exception_table_end, type );
if( p == __gg__exception_table_end ) {
- cbl_internal_error("no such exception: 0x%04x", type);
+ cbl_internal_error("no such exception: 0x%x", type);
}
return p;
}
exception_turn_t() : enabled(false), location(false) {};
- exception_turn_t( ec_type_t ec, bool enabled = true )
- : enabled(enabled)
+ explicit exception_turn_t( ec_type_t ec, bool enabled = true )
+ : enabled(enabled), location(false)
{
add_exception(ec);
}
const ec_filemap_t& exception_files() const { return exceptions; }
- bool add_exception( ec_type_t type, const filelist_t files = filelist_t() ) {
+ bool add_exception( ec_type_t type, const filelist_t& files = filelist_t() ) {
ec_disposition_t disposition = ec_type_disposition(type);
if( disposition != ec_implemented(disposition) ) {
cbl_unimplementedw("CDF: exception '%s'", ec_type_str(type));
return retval;
}
-static void store_location_stuff(const cbl_name_t statement_name);
+static void
+store_location_stuff(const cbl_name_t statement_name)
+ {
+ if( exception_location_active && !current_declarative_section_name() )
+ {
+ // We need to establish some stuff for EXCEPTION- function processing
+
+ gg_assign(var_decl_exception_program_id,
+ gg_string_literal(current_function->our_unmangled_name));
+
+ if( strstr(current_function->current_section->label->name, "_implicit")
+ != current_function->current_section->label->name )
+ {
+ gg_assign(var_decl_exception_section,
+ gg_string_literal(current_function->current_section->label->name));
+ }
+ else
+ {
+ gg_assign(var_decl_exception_section,
+ gg_cast(build_pointer_type(CHAR_P),null_pointer_node));
+ }
+
+ if( strstr(current_function->current_paragraph->label->name, "_implicit")
+ != current_function->current_paragraph->label->name )
+ {
+ gg_assign(var_decl_exception_paragraph,
+ gg_string_literal(current_function->current_paragraph->label->name));
+ }
+ else
+ {
+ gg_assign(var_decl_exception_paragraph,
+ gg_cast(build_pointer_type(CHAR_P), null_pointer_node));
+ }
+
+ gg_assign(var_decl_exception_source_file,
+ gg_string_literal(current_filename.back().c_str()));
+ gg_assign(var_decl_exception_line_number, build_int_cst_type(INT,
+ CURRENT_LINE_NUMBER));
+ gg_assign(var_decl_exception_statement, gg_string_literal(statement_name));
+ }
+ }
+
+static
+void
+set_exception_environment( tree ecs, tree dcls )
+ {
+ gg_call(VOID,
+ "__gg__set_exception_environment",
+ ecs ? gg_get_address_of(ecs) : null_pointer_node,
+ dcls ? gg_get_address_of(dcls) : null_pointer_node,
+ NULL_TREE);
+ }
void
-parser_statement_begin( const cbl_name_t statement_name, tree ecs, tree dcls )
+parser_statement_begin( const cbl_name_t statement_name,
+ tree ecs,
+ tree dcls )
{
SHOW_PARSE
{
TRACE1_END
}
+ gcc_assert( gg_trans_unit.function_stack.size() );
+
+ // In the cases where enabled_exceptions.size() is non-zero, or when
+ // there is a possibility of an EC-I-O exception because this is a file
+ // operation, we need to store the location information and do the exception
+ // overhead:
+
+ static const std::set<std::string> file_ops =
+ {
+ "OPEN",
+ "CLOSE",
+ "READ",
+ "WRITE",
+ "DELETE",
+ "REWRITE",
+ "START",
+ };
+
+ // Performance note: By doing exception processing only when necessary
+ // the execution time of a program doing two-billion simple adds in an inner
+ // loop dropped from 3.8 seconds to 0.175 seconds.
+
+ bool exception_processing = enabled_exceptions.size() ;
+
+ if( !exception_processing )
+ {
+ exception_processing = file_ops.find(statement_name) != file_ops.end();
+ }
+
if( gg_get_current_line_number() == DEFAULT_LINE_NUMBER )
{
// This code is intended to prevert GDB anomalies when the first line of a
// Each file I-O routine calls store_location_stuff explicitly, because
// those exceptions can't be defeated.
- if( enabled_exceptions.size() )
+ if( exception_processing )
{
store_location_stuff(statement_name);
}
gg_set_current_line_number(CURRENT_LINE_NUMBER);
- // if( ecs || dcls || sv_is_i_o )
+ if( exception_processing )
{
- gg_call(VOID,
- "__gg__set_exception_environment",
- ecs ? gg_get_address_of(ecs) : null_pointer_node,
- dcls ? gg_get_address_of(dcls) : null_pointer_node,
- NULL_TREE);
+ set_exception_environment(ecs, dcls);
}
-
- gcc_assert( gg_trans_unit.function_stack.size() );
sv_is_i_o = false;
}
SHOW_PARSE_END
}
- size_t i = tgt->addresses.number_of_conditionals;
+ unsigned int i = tgt->addresses.number_of_conditionals;
if( !(i < MAXIMUM_UNTILS) )
{
- cbl_internal_error("%s:%d: %zu exceeds MAXIMUM_UNTILS of %d, line %d",
- __func__, __LINE__, i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER);
+ cbl_internal_error("%s:%d: %u exceeds MAXIMUM_UNTILS of %d, line %d",
+ __func__, __LINE__,
+ i, MAXIMUM_UNTILS, CURRENT_LINE_NUMBER);
}
gcc_assert(i < MAXIMUM_UNTILS);
SHOW_PARSE_END
}
- size_t i = tgt->addresses.number_of_conditionals;
+ unsigned int i = tgt->addresses.number_of_conditionals;
gcc_assert(i);
// We need to cap off the prior conditional in this chain of conditionals
NULL_TREE );
}
-static void
-store_location_stuff(const cbl_name_t statement_name)
- {
- if( exception_location_active && !current_declarative_section_name() )
- {
- // We need to establish some stuff for EXCEPTION- function processing
-
- gg_assign(var_decl_exception_program_id,
- gg_string_literal(current_function->our_unmangled_name));
-
- if( strstr(current_function->current_section->label->name, "_implicit")
- != current_function->current_section->label->name )
- {
- gg_assign(var_decl_exception_section,
- gg_string_literal(current_function->current_section->label->name));
- }
- else
- {
- gg_assign(var_decl_exception_section,
- gg_cast(build_pointer_type(CHAR_P),null_pointer_node));
- }
-
- if( strstr(current_function->current_paragraph->label->name, "_implicit")
- != current_function->current_paragraph->label->name )
- {
- gg_assign(var_decl_exception_paragraph,
- gg_string_literal(current_function->current_paragraph->label->name));
- }
- else
- {
- gg_assign(var_decl_exception_paragraph,
- gg_cast(build_pointer_type(CHAR_P), null_pointer_node));
- }
-
- gg_assign(var_decl_exception_source_file,
- gg_string_literal(current_filename.back().c_str()));
- gg_assign(var_decl_exception_line_number, build_int_cst_type(INT,
- CURRENT_LINE_NUMBER));
- gg_assign(var_decl_exception_statement, gg_string_literal(statement_name));
- }
- }
-
void
parser_exception_clear()
{
TRACE1_END
}
+ // Performance note:
+ // A simple program that does two billion additions of 32-bit binary numbers
+ // in its innermost loop had an execution time of 19.5 seconds. By putting in
+ // the if() statement, that was reduced to 3.8 seconds.
+
+ if( enabled_exceptions.size() || sv_is_i_o )
+ {
gg_call(VOID,
"__gg__check_fatal_exception",
NULL_TREE);
+ }
}
void
cbx_inspect_match_t(
const DATA& matching = DATA(),
- cbx_inspect_qual_t<DATA> before = cbx_inspect_qual_t<DATA>(),
- cbx_inspect_qual_t<DATA> after = cbx_inspect_qual_t<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)
, before(before)
template <typename DATA>
struct cbx_inspect_t {
DATA tally; // identifier-2: NULL without a tally
- size_t nbound; // Each FOR or REPLACING operation starts with a cbl_inspect_bound_t
+ 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() )
, nbound(0)
, opers(NULL)
{}
- cbx_inspect_t( const DATA& tally, cbx_inspect_oper_t<DATA> oper )
+ cbx_inspect_t( const DATA& tally, const cbx_inspect_oper_t<DATA>& oper )
: tally(tally)
, nbound(1)
, opers(NULL)
segments.front().pend, '\n');
nlines.after = std::count(segments.back().p, segments.back().pend, '\n');
if( nlines.delta() < 0 ) {
- yywarn("line %zu: REPLACED %zu lines with %zu lines, "
- "line count off by %d", mfile.lineno(),
- nlines.before, nlines.after, nlines.delta());
+ 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 ) {
}
};
-/* Location type. Borrowed from parse.h as generated by Bison. */
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE YYLTYPE;
-struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-};
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
+// YYLTYPE supplied by cbldiag.h. Borrowed from parse.h as generated by Bison.
struct filespan_t : public bytespan_t {
char *cur, *eol, *quote;
cdf_words: %empty
| cobol_words
+ /* | error { error_msg(@1, "not a COBOL-WORD"); } */
;
cobol_words: cobol_words1
| cobol_words cobol_words1
}
}
}
- | REPOSITORY '.'
- | REPOSITORY '.' repo_members '.'
+ | REPOSITORY dot
+ | REPOSITORY dot repo_members '.'
;
repo_members: repo_member
f->attr |= external_e;
cbl_unimplemented("AS LITERAL");
}
- | fd_linage
+ | fd_linage { cbl_unimplemented("LINAGE"); }
| fd_report {
cbl_unimplemented("REPORT WRITER");
YYERROR;
auto redefined = symbol_redefines(field);
if( redefined && redefined->type == FldPointer ) {
if( yydebug ) {
- yywarn("expanding %s size from %u bytes to %zu "
- "because it redefines %s with USAGE POINTER",
+ yywarn("expanding %s size from %u bytes to "
+ HOST_WIDE_INT_PRINT " "
+ "because it redefines %s with USAGE POINTER",
field->name, field->size(),
- (size_t)int_size_in_bytes(ptr_type_node),
+ int_size_in_bytes(ptr_type_node),
redefined->name);
}
field->embiggen();
INTEGER 0*[1-9][[:digit:]]*
INTEGERZ [[:digit:]]+
+NONWORD [^[:alnum:]$_-]+
+
SPC [[:space:]]+
OSPC [[:space:]]*
EOL \r?\n
}
<function>{
-
-
- ABS{OSPC}/[(]? { pop_return ABS; }
- ACOS{OSPC}/[(]? { pop_return ACOS; }
- ANNUITY{OSPC}/[(]? { pop_return ANNUITY; }
- ASIN{OSPC}/[(]? { pop_return ASIN; }
- ATAN{OSPC}/[(]? { pop_return ATAN; }
- BASECONVERT{OSPC}/[(]? { pop_return BASECONVERT; }
- BIT-OF{OSPC}/[(]? { pop_return BIT_OF; }
- BIT-TO-CHAR{OSPC}/[(]? { pop_return BIT_TO_CHAR; }
- BOOLEAN-OF-INTEGER{OSPC}/[(]? { pop_return BOOLEAN_OF_INTEGER; }
- BYTE-LENGTH{OSPC}/[(]? { pop_return BYTE_LENGTH; }
- CHAR-NATIONAL{OSPC}/[(]? { pop_return CHAR_NATIONAL; }
- CHAR{OSPC}/[(]? { pop_return CHAR; }
- COMBINED-DATETIME{OSPC}/[(]? { pop_return COMBINED_DATETIME; }
- CONCAT{OSPC}/[(]? { pop_return CONCAT; }
- CONTENT-LENGTH{OSPC}/[(]? { pop_return NO_CONDITION; /* GNU only*/ }
- CONTENT-OF{OSPC}/[(]? { pop_return NO_CONDITION; /* GNU only*/ }
- CONVERT{OSPC}/[(]? { pop_return CONVERT; }
- COS{OSPC}/[(]? { pop_return COS; }
- CURRENCY-SYBOL{OSPC}/[(]? { pop_return NO_CONDITION; /* GNU only*/ }
- CURRENT-DATE{OSPC}/[(]? { pop_return CURRENT_DATE; }
- DATE-OF-INTEGER{OSPC}/[(]? { pop_return DATE_OF_INTEGER; }
- DATE-TO-YYYYMMDD{OSPC}/[(]? { pop_return DATE_TO_YYYYMMDD; }
- DAY-OF-INTEGER{OSPC}/[(]? { pop_return DAY_OF_INTEGER; }
- DAY-TO-YYYYDDD{OSPC}/[(]? { pop_return DAY_TO_YYYYDDD; }
- DISPLAY-OF{OSPC}/[(]? { pop_return DISPLAY_OF; }
- E{OSPC}/[(]? { pop_return E; }
-
- EXCEPTION-FILE-N{OSPC}/[(]? { pop_return EXCEPTION_FILE_N; }
- EXCEPTION-FILE{OSPC}/[(]? { pop_return EXCEPTION_FILE; }
- EXCEPTION-LOCATION-N{OSPC}/[(]? { pop_return EXCEPTION_LOCATION_N; }
- EXCEPTION-LOCATION{OSPC}/[(]? { pop_return EXCEPTION_LOCATION; }
- EXCEPTION-STATEMENT{OSPC}/[(]? { pop_return EXCEPTION_STATEMENT; }
- EXCEPTION-STATUS{OSPC}/[(]? { pop_return EXCEPTION_STATUS; }
-
- EXP{OSPC}/[(]? { pop_return EXP; }
- EXP10{OSPC}/[(]? { pop_return EXP10; }
- FACTORIAL{OSPC}/[(]? { pop_return FACTORIAL; }
- FIND-STRING{OSPC}/[(]? { pop_return FIND_STRING; }
-
- FORMATTED-CURRENT-DATE{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_CURRENT_DATE; }
- FORMATTED-DATE{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_DATE; }
- FORMATTED-DATETIME{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_DATETIME; }
- FORMATTED-TIME{OSPC}/[(]? { BEGIN(datetime_fmt); return FORMATTED_TIME; }
- FRACTION-PART{OSPC}/[(]? { pop_return FRACTION_PART; }
-
- HEX-OF{OSPC}/[(]? { pop_return HEX_OF; }
- HEX-TO-CHAR{OSPC}/[(]? { pop_return HEX_TO_CHAR; }
- HIGHEST-ALGEBRAIC{OSPC}/[(]? { pop_return HIGHEST_ALGEBRAIC; }
-
- INTEGER{OSPC}/[(]? { pop_return INTEGER; }
- INTEGER-OF-BOOLEAN{OSPC}/[(]? { pop_return INTEGER_OF_BOOLEAN; }
- INTEGER-OF-DATE{OSPC}/[(]? { pop_return INTEGER_OF_DATE; }
- INTEGER-OF-DAY{OSPC}/[(]? { pop_return INTEGER_OF_DAY; }
- INTEGER-OF-FORMATTED-DATE{OSPC}/[(]? { BEGIN(datetime_fmt); return INTEGER_OF_FORMATTED_DATE; }
- INTEGER-PART{OSPC}/[(]? { pop_return INTEGER_PART; }
- LENGTH{OSPC}/[(]? { pop_return LENGTH; }
- LOCALE-COMPARE{OSPC}/[(]? { pop_return LOCALE_COMPARE; }
- LOCALE-DATE{OSPC}/[(]? { pop_return LOCALE_DATE; }
- LOCALE-TIME{OSPC}/[(]? { pop_return LOCALE_TIME; }
- LOCALE-TIME-FROM-SECONDS{OSPC}/[(]? { pop_return LOCALE_TIME_FROM_SECONDS; }
- LOG{OSPC}/[(]? { pop_return LOG; }
- LOG10{OSPC}/[(]? { pop_return LOG10; }
- LOWER-CASE{OSPC}/[(]? { pop_return LOWER_CASE; }
- LOWEST-ALGEBRAIC{OSPC}/[(]? { pop_return LOWEST_ALGEBRAIC; }
- MAX{OSPC}/[(]? { pop_return MAXX; }
- MEAN{OSPC}/[(]? { pop_return MEAN; }
- MEDIAN{OSPC}/[(]? { pop_return MEDIAN; }
- MIDRANGE{OSPC}/[(]? { pop_return MIDRANGE; }
- MIN{OSPC}/[(]? { pop_return MINN; }
- MOD{OSPC}/[(]? { pop_return MOD; }
- MODULE-NAME{OSPC}/[(]? { pop_return MODULE_NAME; }
- NATIONAL-OF{OSPC}/[(]? { pop_return NATIONAL_OF; }
- NUMVAL{OSPC}/[(]? { pop_return NUMVAL; }
- NUMVAL-C{OSPC}/[(]? { pop_return NUMVAL_C; }
- NUMVAL-F{OSPC}/[(]? { pop_return NUMVAL_F; }
- ORD{OSPC}/[(]? { pop_return ORD; }
- ORD-MAX{OSPC}/[(]? { pop_return ORD_MAX; }
- ORD-MIN{OSPC}/[(]? { pop_return ORD_MIN; }
- PI{OSPC}/[(]? { pop_return PI; }
- PRESENT-VALUE{OSPC}/[(]? { pop_return PRESENT_VALUE; }
+ ABS/{NONWORD} { pop_return ABS; }
+ ACOS/{NONWORD} { pop_return ACOS; }
+ ANNUITY/{NONWORD} { pop_return ANNUITY; }
+ ASIN/{NONWORD} { pop_return ASIN; }
+ ATAN/{NONWORD} { pop_return ATAN; }
+ BASECONVERT/{NONWORD} { pop_return BASECONVERT; }
+ BIT-OF/{NONWORD} { pop_return BIT_OF; }
+ BIT-TO-CHAR/{NONWORD} { pop_return BIT_TO_CHAR; }
+ BOOLEAN-OF-INTEGER/{NONWORD} { pop_return BOOLEAN_OF_INTEGER; }
+ BYTE-LENGTH/{NONWORD} { pop_return BYTE_LENGTH; }
+ CHAR-NATIONAL/{NONWORD} { pop_return CHAR_NATIONAL; }
+ CHAR/{NONWORD} { pop_return CHAR; }
+ COMBINED-DATETIME/{NONWORD} { pop_return COMBINED_DATETIME; }
+ CONCAT/{NONWORD} { pop_return CONCAT; }
+ CONTENT-LENGTH/{NONWORD} { pop_return NO_CONDITION; /* GNU only*/ }
+ CONTENT-OF/{NONWORD} { pop_return NO_CONDITION; /* GNU only*/ }
+ CONVERT/{NONWORD} { pop_return CONVERT; }
+ COS/{NONWORD} { pop_return COS; }
+ CURRENCY-SYBOL/{NONWORD} { pop_return NO_CONDITION; /* GNU only*/ }
+ CURRENT-DATE/{NONWORD} { pop_return CURRENT_DATE; }
+ DATE-OF-INTEGER/{NONWORD} { pop_return DATE_OF_INTEGER; }
+ DATE-TO-YYYYMMDD/{NONWORD} { pop_return DATE_TO_YYYYMMDD; }
+ DAY-OF-INTEGER/{NONWORD} { pop_return DAY_OF_INTEGER; }
+ DAY-TO-YYYYDDD/{NONWORD} { pop_return DAY_TO_YYYYDDD; }
+ DISPLAY-OF/{NONWORD} { pop_return DISPLAY_OF; }
+ E/{NONWORD} { pop_return E; }
+
+ EXCEPTION-FILE-N/{NONWORD} { pop_return EXCEPTION_FILE_N; }
+ EXCEPTION-FILE/{NONWORD} { pop_return EXCEPTION_FILE; }
+ EXCEPTION-LOCATION-N/{NONWORD} { pop_return EXCEPTION_LOCATION_N; }
+ EXCEPTION-LOCATION/{NONWORD} { pop_return EXCEPTION_LOCATION; }
+ EXCEPTION-STATEMENT/{NONWORD} { pop_return EXCEPTION_STATEMENT; }
+ EXCEPTION-STATUS/{NONWORD} { pop_return EXCEPTION_STATUS; }
+
+ EXP/{NONWORD} { pop_return EXP; }
+ EXP10/{NONWORD} { pop_return EXP10; }
+ FACTORIAL/{NONWORD} { pop_return FACTORIAL; }
+ FIND-STRING/{NONWORD} { pop_return FIND_STRING; }
+
+ FORMATTED-CURRENT-DATE/{NONWORD} { BEGIN(datetime_fmt);
+ return FORMATTED_CURRENT_DATE; }
+ FORMATTED-DATE/{NONWORD} { BEGIN(datetime_fmt); return FORMATTED_DATE; }
+ FORMATTED-DATETIME/{NONWORD} { BEGIN(datetime_fmt); return FORMATTED_DATETIME; }
+ FORMATTED-TIME/{NONWORD} { BEGIN(datetime_fmt); return FORMATTED_TIME; }
+ FRACTION-PART/{NONWORD} { pop_return FRACTION_PART; }
+
+ HEX-OF/{NONWORD} { pop_return HEX_OF; }
+ HEX-TO-CHAR/{NONWORD} { pop_return HEX_TO_CHAR; }
+ HIGHEST-ALGEBRAIC/{NONWORD} { pop_return HIGHEST_ALGEBRAIC; }
+
+ INTEGER/{NONWORD} { pop_return INTEGER; }
+ INTEGER-OF-BOOLEAN/{NONWORD} { pop_return INTEGER_OF_BOOLEAN; }
+ INTEGER-OF-DATE/{NONWORD} { pop_return INTEGER_OF_DATE; }
+ INTEGER-OF-DAY/{NONWORD} { pop_return INTEGER_OF_DAY; }
+ INTEGER-OF-FORMATTED-DATE/{NONWORD} { BEGIN(datetime_fmt);
+ return INTEGER_OF_FORMATTED_DATE; }
+ INTEGER-PART/{NONWORD} { pop_return INTEGER_PART; }
+ LENGTH/{NONWORD} { pop_return LENGTH; }
+ LOCALE-COMPARE/{NONWORD} { pop_return LOCALE_COMPARE; }
+ LOCALE-DATE/{NONWORD} { pop_return LOCALE_DATE; }
+ LOCALE-TIME/{NONWORD} { pop_return LOCALE_TIME; }
+ LOCALE-TIME-FROM-SECONDS/{NONWORD} { pop_return LOCALE_TIME_FROM_SECONDS; }
+ LOG/{NONWORD} { pop_return LOG; }
+ LOG10/{NONWORD} { pop_return LOG10; }
+ LOWER-CASE/{NONWORD} { pop_return LOWER_CASE; }
+ LOWEST-ALGEBRAIC/{NONWORD} { pop_return LOWEST_ALGEBRAIC; }
+ MAX/{NONWORD} { pop_return MAXX; }
+ MEAN/{NONWORD} { pop_return MEAN; }
+ MEDIAN/{NONWORD} { pop_return MEDIAN; }
+ MIDRANGE/{NONWORD} { pop_return MIDRANGE; }
+ MIN/{NONWORD} { pop_return MINN; }
+ MOD/{NONWORD} { pop_return MOD; }
+ MODULE-NAME/{NONWORD} { pop_return MODULE_NAME; }
+ NATIONAL-OF/{NONWORD} { pop_return NATIONAL_OF; }
+ NUMVAL/{NONWORD} { pop_return NUMVAL; }
+ NUMVAL-C/{NONWORD} { pop_return NUMVAL_C; }
+ NUMVAL-F/{NONWORD} { pop_return NUMVAL_F; }
+ ORD/{NONWORD} { pop_return ORD; }
+ ORD-MAX/{NONWORD} { pop_return ORD_MAX; }
+ ORD-MIN/{NONWORD} { pop_return ORD_MIN; }
+ PI/{NONWORD} { pop_return PI; }
+ PRESENT-VALUE/{NONWORD} { pop_return PRESENT_VALUE; }
RANDOM{OSPC}{PARENS} { pop_return RANDOM; }
RANDOM{OSPC}[(] { pop_return RANDOM_SEED; }
RANDOM { pop_return RANDOM; }
- RANGE{OSPC}/[(]? { pop_return RANGE; }
- REM{OSPC}/[(]? { pop_return REM; }
- REVERSE{OSPC}/[(]? { pop_return REVERSE; }
- SECONDS-FROM-FORMATTED-TIME{OSPC}/[(]? { BEGIN(datetime_fmt);
+ RANGE/{NONWORD} { pop_return RANGE; }
+ REM/{NONWORD} { pop_return REM; }
+ REVERSE/{NONWORD} { pop_return REVERSE; }
+ SECONDS-FROM-FORMATTED-TIME/{NONWORD} { BEGIN(datetime_fmt);
return SECONDS_FROM_FORMATTED_TIME; }
- SECONDS-PAST-MIDNIGHT{OSPC}/[(]? { pop_return SECONDS_PAST_MIDNIGHT; }
- SIGN{OSPC}/[(]? { pop_return SIGN; }
- SIN{OSPC}/[(]? { pop_return SIN; }
- SMALLEST-ALGEBRAIC{OSPC}/[(]? { pop_return SMALLEST_ALGEBRAIC; }
- SQRT{OSPC}/[(]? { pop_return SQRT; }
- STANDARD-COMPARE{OSPC}/[(]? { pop_return STANDARD_COMPARE; }
- STANDARD-DEVIATION{OSPC}/[(]? { pop_return STANDARD_DEVIATION; }
- SUBSTITUTE{OSPC}/[(]? { pop_return SUBSTITUTE; }
- SUM{OSPC}/[(]? { pop_return SUM; }
- TAN{OSPC}/[(]? { pop_return TAN; }
- TEST-DATE-YYYYMMDD{OSPC}/[(]? { pop_return TEST_DATE_YYYYMMDD; }
- TEST-DAY-YYYYDDD{OSPC}/[(]? { pop_return TEST_DAY_YYYYDDD; }
- TEST-FORMATTED-DATETIME{OSPC}/[(]? { BEGIN(datetime_fmt); return TEST_FORMATTED_DATETIME; }
- TEST-NUMVAL{OSPC}/[(]? { pop_return TEST_NUMVAL; }
- TEST-NUMVAL-C{OSPC}/[(]? { pop_return TEST_NUMVAL_C; }
- TEST-NUMVAL-F{OSPC}/[(]? { pop_return TEST_NUMVAL_F; }
- TRIM{OSPC}/[(]? { pop_return TRIM; }
- ULENGTH{OSPC}/[(]? { pop_return ULENGTH; }
- UPOS{OSPC}/[(]? { pop_return UPOS; }
- UPPER-CASE{OSPC}/[(]? { pop_return UPPER_CASE; }
- USUBSTR{OSPC}/[(]? { pop_return USUBSTR; }
- USUPPLEMENTARY{OSPC}/[(]? { pop_return USUPPLEMENTARY; }
- UUID4{OSPC}/[(]? { pop_return UUID4; }
- UVALID{OSPC}/[(]? { pop_return UVALID; }
- UWIDTH{OSPC}/[(]? { pop_return UWIDTH; }
- VARIANCE{OSPC}/[(]? { pop_return VARIANCE; }
- WHEN-COMPILED{OSPC}/[(]? { pop_return WHEN_COMPILED; }
- YEAR-TO-YYYY{OSPC}/[(]? { pop_return YEAR_TO_YYYY; }
+ SECONDS-PAST-MIDNIGHT/{NONWORD} { pop_return SECONDS_PAST_MIDNIGHT; }
+ SIGN/{NONWORD} { pop_return SIGN; }
+ SIN/{NONWORD} { pop_return SIN; }
+ SMALLEST-ALGEBRAIC/{NONWORD} { pop_return SMALLEST_ALGEBRAIC; }
+ SQRT/{NONWORD} { pop_return SQRT; }
+ STANDARD-COMPARE/{NONWORD} { pop_return STANDARD_COMPARE; }
+ STANDARD-DEVIATION/{NONWORD} { pop_return STANDARD_DEVIATION; }
+ SUBSTITUTE/{NONWORD} { pop_return SUBSTITUTE; }
+ SUM/{NONWORD} { pop_return SUM; }
+ TAN/{NONWORD} { pop_return TAN; }
+ TEST-DATE-YYYYMMDD/{NONWORD} { pop_return TEST_DATE_YYYYMMDD; }
+ TEST-DAY-YYYYDDD/{NONWORD} { pop_return TEST_DAY_YYYYDDD; }
+ TEST-FORMATTED-DATETIME/{NONWORD} { BEGIN(datetime_fmt); return TEST_FORMATTED_DATETIME; }
+ TEST-NUMVAL/{NONWORD} { pop_return TEST_NUMVAL; }
+ TEST-NUMVAL-C/{NONWORD} { pop_return TEST_NUMVAL_C; }
+ TEST-NUMVAL-F/{NONWORD} { pop_return TEST_NUMVAL_F; }
+ TRIM/{NONWORD} { pop_return TRIM; }
+ ULENGTH/{NONWORD} { pop_return ULENGTH; }
+ UPOS/{NONWORD} { pop_return UPOS; }
+ UPPER-CASE/{NONWORD} { pop_return UPPER_CASE; }
+ USUBSTR/{NONWORD} { pop_return USUBSTR; }
+ USUPPLEMENTARY/{NONWORD} { pop_return USUPPLEMENTARY; }
+ UUID4/{NONWORD} { pop_return UUID4; }
+ UVALID/{NONWORD} { pop_return UVALID; }
+ UWIDTH/{NONWORD} { pop_return UWIDTH; }
+ VARIANCE/{NONWORD} { pop_return VARIANCE; }
+ WHEN-COMPILED/{NONWORD} { pop_return WHEN_COMPILED; }
+ YEAR-TO-YYYY/{NONWORD} { pop_return YEAR_TO_YYYY; }
+
+ /* Matches above include NONWORD because the NAME tests below are otherwise longer, */
{NAME}{OSPC}/[(] { /* If /{OSPC}, "dangerous trailing context" "*/
auto name = null_trim(xstrdup(yytext));
void scanner_parsing( int token, bool tf ) {
parsing.push( cdf_status_t(token, tf) );
if( yydebug ) {
- yywarn("%10s: parsing now %5s, depth %zu",
- keyword_str(token), boolalpha(parsing.on()), parsing.size());
+ yywarn("%10s: parsing now %5s, depth %lu",
+ keyword_str(token), boolalpha(parsing.on()),
+ gb4(parsing.size()));
parsing.splat();
}
}
}
parsing.pop();
if( yydebug ) {
- yywarn("%10s: parsing now %5s, depth %zu",
- keyword_str(CDF_END_IF), boolalpha(parsing.on()), parsing.size());
+ yywarn("%10s: parsing now %5s, depth %lu",
+ keyword_str(CDF_END_IF), boolalpha(parsing.on()),
+ gb4(parsing.size()));
parsing.splat();
}
}
std::transform(name, name + strlen(name), uname, ftoupper);
dbgmsg("%s:%d: checking %s in %zu keyword_aliases",
- __func__, __LINE__, uname, keyword_aliases.size() );
+ __func__, __LINE__, uname,
+ keyword_aliases.size() );
std::string key = uname;
auto alias = keyword_aliases.find(key);
while( is_cdf_token(token) ) {
if( ! run_cdf(token) ) {
- dbgmsg( ">>CDF parser failed" );
- return NO_CONDITION;
+ dbgmsg( ">>CDF parser failed, ydfchar %d", ydfchar );
}
// Return the CDF's discarded lookahead token, if extant.
token = ydfchar > 0? ydfchar : next_token();
if( token == NO_CONDITION && parsing.at_eof() ) {
- return token = YYEOF;
+ return YYEOF;
}
// Reenter cdf parser only if next token could affect parsing state.
token = prelex();
if( yy_flex_debug ) {
if( parsing.in_cdf() ) {
- dbgmsg( "%s:%d: %s routing %s to CDF parser", __func__, __LINE__,
+ dbgmsg( "%s:%d: <%s> routing %s to CDF parser", __func__, __LINE__,
start_condition_is(), keyword_str(token) );
} else if( !parsing.on() ) {
dbgmsg( "eating %s because conditional compilation is FALSE",
{
const symbol_elem_t *first, *last;
public:
- symbol_pair_t( const symbol_elem_t * first, const symbol_elem_t * end = NULL )
+ explicit symbol_pair_t( const symbol_elem_t * first, const symbol_elem_t * end = NULL )
: first(first), last(end)
{}
off_t len = symbols.size();
if( 0 != ftruncate(symbols.fd, len) ) {
- cbl_err( "%s:%d:could not extend symbol table to %zu elements",
- __func__, __LINE__, symbols.capacity);
+ cbl_err( "%s:%d: could not extend symbol table to %lu elements",
+ __func__, __LINE__, gb4(symbols.capacity));
}
/*
enum { constq = constant_e | quoted_e };
static symbol_elem_t
-elementize( cbl_field_t& field ) {
+elementize( const cbl_field_t& field ) {
symbol_elem_t sym (SymField);
sym.elem.field = field;
return sym;
class eog_t {
const cbl_field_t * group;
public:
- eog_t( const symbol_elem_t *e ) : group(cbl_field_of(e)) {}
+ explicit eog_t( const symbol_elem_t *e ) : group(cbl_field_of(e)) {}
bool operator()( symbol_elem_t& e ) {
return e.type == SymField && end_of_group(group, cbl_field_of(&e));
bool
is_variable_length( const cbl_field_t *field ) {
- bool odo = false;
- std::find_if( symbol_at(field_index(field)) + 1, symbols_end(),
- [&odo, field]( const auto& elem ) {
- if( elem.type == SymField ) {
- auto f = cbl_field_of(&elem);
- if( f->level <= field->level ) return true;
- if( f->occurs.depending_on ) {
- odo = true;
- return true;
- }
- }
- return false;
- } );
+ // RENAMES may be included in end_of_group.
+ size_t isym = field_index(field), esym = end_of_group(isym);
+ bool odo = std::any_of( symbol_at(isym) + 1, symbol_at_impl(esym),
+ [field]( const auto& elem ) {
+ if( elem.type == SymField ) {
+ auto f = cbl_field_of(&elem);
+ if( field->level < f->level ) { // exclude RENAMES
+ return 0 < f->occurs.depending_on;
+ }
+ }
+ return false;
+ } );
return odo;
}
case 1:
pend = calculate_capacity(p);
if( dialect_mf() && is_table(field) ) {
- cbl_field_t *field = cbl_field_of(p);
if( field->data.memsize < field->size() ) {
field->data.memsize = field->size();
}
private:
size_t parent_index;
public:
- parent_elem_set( size_t parent_index )
+ explicit parent_elem_set( size_t parent_index )
: parent_index(parent_index)
{}
void operator()( struct symbol_elem_t& e ) {
return e;
}
-struct symbol_elem_t *
-symbol_alphabet_add( size_t program, struct cbl_alphabet_t *alphabet ) {
- struct symbol_elem_t sym{ SymAlphabet, program };
+symbol_elem_t *
+symbol_alphabet_add( size_t program, const cbl_alphabet_t *alphabet ) {
+ symbol_elem_t sym{ SymAlphabet, program };
sym.elem.alphabet = *alphabet;
return symbol_add(&sym);
}
static cbl_field_t *
new_literal_add( const char initial[], uint32_t len, enum cbl_field_attr_t attr ) {
- static char empty[2] = "\0";
cbl_field_t *field = NULL;
if( !(attr & quoted_e) )
{
}
else
{
+ static char empty[2] = "\0";
field = new_temporary_impl(FldLiteralA);
field->attr |= attr;
field->data.initial = len > 0? initial : empty;
{
if( value && ! is_numeric ) {
auto s = consistent_encoding_check(loc, value);
- if( s ) value = s;
+ if( s ) this->value = s;
}
}
const char *name() const { return value; }
struct cbl_span_t {
cbl_refer_t *from, *len;
- cbl_span_t( cbl_refer_t *from, cbl_refer_t *len = NULL )
+ explicit cbl_span_t( cbl_refer_t *from, cbl_refer_t *len = NULL )
: from(from), len(len) {};
bool is_active() const { return !( from == NULL && len == NULL ); }
cbl_span_t refmod; // substring bounds
cbl_refer_t()
- : field(NULL), prog_func(NULL)
+ : loc(), field(NULL), prog_func(NULL)
, all(NULL), addr_of(false)
, nsubscript(0), subscripts(NULL), refmod(NULL)
{}
cbl_refer_t( cbl_field_t *field, bool all = false )
- : field(field), prog_func(NULL)
+ : loc(), field(field), prog_func(NULL)
, all(all), addr_of(false)
, nsubscript(0), subscripts(NULL), refmod(NULL)
{}
, nsubscript(0), subscripts(NULL), refmod(NULL)
{}
cbl_refer_t( cbl_field_t *field, cbl_span_t& refmod )
- : field(field), prog_func(NULL)
+ : loc(), field(field), prog_func(NULL)
, all(false), addr_of(false)
, nsubscript(0), subscripts(NULL), refmod(refmod)
{}
cbl_refer_t( cbl_field_t *field,
size_t nsubscript, cbl_refer_t *subscripts,
cbl_span_t refmod = cbl_span_t(NULL) )
- : field(field), prog_func(NULL)
+ : loc(), field(field), prog_func(NULL)
, all(false), addr_of(false)
, nsubscript(nsubscript) , subscripts( new cbl_refer_t[nsubscript] )
, refmod(refmod)
std::copy(subscripts, subscripts + nsubscript, this->subscripts);
}
explicit cbl_refer_t( cbl_label_t *prog_func, bool addr_of = true )
- : field(NULL), prog_func(prog_func)
+ : loc(), field(NULL), prog_func(prog_func)
, all(false), addr_of(addr_of)
, nsubscript(0), subscripts(NULL), refmod(cbl_span_t(NULL))
{}
add_sequence( const YYLTYPE& loc, const unsigned char seq[] ) {
if( low_index == 0 ) low_index = seq[0];
- unsigned char high_value = last_index > 0? alphabet[last_index] + 1 : 0;
+ unsigned char last = last_index > 0? alphabet[last_index] + 1 : 0;
for( const unsigned char *p = seq; !end_of_string(p); p++ ) {
- assign(loc, *p, high_value++);
+ assign(loc, *p, last++);
}
}
add_interval( const YYLTYPE& loc, unsigned char low, unsigned char high ) {
if( low_index == 0 ) low_index = low;
- unsigned char high_value = alphabet[last_index];
+ unsigned char last = alphabet[last_index];
for( unsigned char ch = low; ch < high; ch++ ) {
- assign(loc, ch, high_value++);
+ assign(loc, ch, last++);
}
}
fields[0] = field;
memset(name, '\0', sizeof(name));
}
- cbl_file_key_t( const cbl_file_key_t *that )
- : unique(that->unique)
- , leftmost(that->leftmost)
- , nfield(that->nfield)
- {
- memcpy(name, that->name, sizeof(name));
- fields = new size_t[nfield];
- std::copy( that->fields, that->fields + that->nfield, fields );
- }
cbl_file_key_t( cbl_name_t name,
const std::list<cbl_field_t *>& fields,
cbl_alphabet_t alphabet;
cbl_file_t file;
cbl_section_t section;
- symbol_elem_u() {
- static const cbl_field_t empty = {};
- field = empty;
- }
+ symbol_elem_u() : field() {}
} elem;
symbol_elem_t( symbol_type_t type = SymField, size_t program = 0 )
struct cbl_label_addresses_t test; // The test at the bottom of the body
struct cbl_label_addresses_t testA; // Starting point of a TEST_AFTER loop
struct cbl_label_addresses_t setup; // The actual entry point
- size_t number_of_conditionals;
+ unsigned int number_of_conditionals;
struct cbl_label_addresses_t condover[MAXIMUM_UNTILS]; // Jumping over the conditional
struct cbl_label_addresses_t condinto[MAXIMUM_UNTILS]; // Jumping into the conditional
struct cbl_label_addresses_t condback[MAXIMUM_UNTILS]; // Jumping back from the conditional
struct program_label_t {
size_t ordinal;
cbl_label_t label;
- program_label_t() : ordinal(0) {}
+ program_label_t() : ordinal(0), label() {}
program_label_t( const symbol_elem_t& e ) {
ordinal = symbol_index(&e);
label = e.elem.label;
struct cbl_perform_tgt_t {
struct cbl_until_addresses_t addresses;
- cbl_perform_tgt_t() : ifrom(0), ito(0) {}
- cbl_perform_tgt_t( cbl_label_t * from, cbl_label_t *to = NULL )
- : ifrom( from? symbol_index(symbol_elem_of(from)) : 0 )
+ cbl_perform_tgt_t() : addresses(), ifrom(0), ito(0) {}
+ explicit cbl_perform_tgt_t( cbl_label_t * from, cbl_label_t *to = NULL )
+ : addresses(), ifrom( from? symbol_index(symbol_elem_of(from)) : 0 )
, ito( to? symbol_index(symbol_elem_of(to)) : 0 )
- {
- addresses = {};
- }
+ {}
cbl_label_t * from( cbl_label_t * label ) {
ifrom = symbol_index(symbol_elem_of(label));
void symbol_table_init(void);
void symbol_table_check(void);
-struct symbol_elem_t * symbol_typedef_add( size_t program,
- struct cbl_field_t *field );
-struct symbol_elem_t * symbol_field_add( size_t program,
- struct cbl_field_t *field );
-struct cbl_label_t * symbol_label_add( size_t program,
- struct cbl_label_t *label );
-struct cbl_label_t * symbol_program_add( size_t program, cbl_label_t *input );
-struct symbol_elem_t * symbol_special_add( size_t program,
- struct cbl_special_name_t *special );
-struct symbol_elem_t * symbol_alphabet_add( size_t program,
- struct cbl_alphabet_t *alphabet );
-struct symbol_elem_t * symbol_file_add( size_t program,
- struct cbl_file_t *file );
-struct symbol_elem_t * symbol_section_add( size_t program,
- struct cbl_section_t *section );
+symbol_elem_t * symbol_typedef_add( size_t program,
+ cbl_field_t *field );
+symbol_elem_t * symbol_field_add( size_t program,
+ cbl_field_t *field );
+cbl_label_t * symbol_label_add( size_t program,
+ cbl_label_t *label );
+cbl_label_t * symbol_program_add( size_t program, cbl_label_t *input );
+symbol_elem_t * symbol_special_add( size_t program,
+ cbl_special_name_t *special );
+symbol_elem_t * symbol_alphabet_add( size_t program,
+ const cbl_alphabet_t *alphabet );
+symbol_elem_t * symbol_file_add( size_t program,
+ cbl_file_t *file );
+symbol_elem_t * symbol_section_add( size_t program,
+ cbl_section_t *section );
void symbol_field_location( size_t ifield, const YYLTYPE& loc );
YYLTYPE symbol_field_location( size_t ifield );
class is_name {
const char *name;
public:
- is_name( const char *name ) : name(name) {}
- bool operator()( symbol_map_t::value_type& elem ) {
+ explicit is_name( const char *name ) : name(name) {}
+ bool operator()( const symbol_map_t::value_type& elem ) {
const bool tf = elem.first == name;
return tf;
}
static symbol_map_t::mapped_type
candidates_only( const symbol_map_t::value_type& elem ) { return elem.second; }
public:
- reduce_ancestry( const symbol_map_t& groups )
+ explicit reduce_ancestry( const symbol_map_t& groups )
: candidates( groups.size() )
{
std::transform( groups.begin(), groups.end(), candidates.begin(),
class different_program {
size_t program;
public:
- different_program( size_t program ) : program(program) {}
+ explicit different_program( size_t program ) : program(program) {}
bool operator()( const symbol_map_t::value_type& item ) const {
return ! item.first.same_program(program);
}
}
public:
- in_scope( size_t program ) : program(program) {}
+ explicit in_scope( size_t program ) : program(program) {}
// 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 {
class in_group {
size_t group;
public:
- in_group( size_t group ) : group(group) {}
+ explicit in_group( size_t group ) : group(group) {}
bool operator()( symbol_map_t::const_reference elem ) const {
return 0 < std::count( elem.second.begin(),
}
#endif
+/*
+ * For printing messages, usually the size of the thing is some kind of string
+ * length, and doesn't really need a size_t. For message formatting, use a
+ * simple unsigned long, and warn if that's no good. "gb4" here stands for
+ * "4 Gigabytes".
+ */
+unsigned long
+gb4( size_t input ) {
+ if( input != static_cast<unsigned long>(input) ) {
+ yywarn("size too large to print: %lx:%lx",
+ (unsigned long)(input >> (4 * sizeof(unsigned long))),
+ static_cast<unsigned long>(input));
+ }
+ return input;
+}
+
const char *
symbol_type_str( enum symbol_type_t type )
{
const char * cobol_filename_restore();
const char * cobol_lineno_save();
+unsigned long gb4( size_t input );
#endif
file_mode_output_e = 'w',
file_mode_extend_e = 'a',
file_mode_io_e = '+',
- file_mode_any_e,
+ file_mode_any_e,
};
enum cbl_round_t {
};
enum file_stmt_t {
- file_stmt_delete_e,
- file_stmt_merge_e,
- file_stmt_read_e,
- file_stmt_rewrite_e,
- file_stmt_sort_e,
- file_stmt_start_e,
- file_stmt_write_e,
+ file_stmt_delete_e,
+ file_stmt_merge_e,
+ file_stmt_read_e,
+ file_stmt_rewrite_e,
+ file_stmt_sort_e,
+ file_stmt_start_e,
+ file_stmt_write_e,
};
-
+
enum file_close_how_t {
file_close_no_how_e = 0x00,
file_close_removal_e = 0x01,
{
if( raised == ec ) return true;
- // If both low bytes are nonzero, we had to match exactly, above.
+ // If both low bytes are nonzero, we had to match exactly, above.
if( (~EC_ALL_E & static_cast<uint32_t>(raised))
&&
(~EC_ALL_E & static_cast<uint32_t>(ec)) ) {
return false;
}
- // Level 1 and 2 have low byte of zero.
+ // Level 1 and 2 have low byte of zero.
// If one low byte is zero, see if they're the same kind.
return 0xFF < ( static_cast<uint32_t>(raised)
&
uint32_t nfile, files[files_max];
cbl_file_mode_t mode;
- // cppcheck-suppress noExplicitConstructor
- cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e )
+ explicit cbl_declarative_t( cbl_file_mode_t mode = file_mode_none_e )
: section(0)
, global(false)
, type(ec_none_e)
{
std::fill(files, files + COUNT_OF(files), 0);
}
- // cppcheck-suppress noExplicitConstructor
- cbl_declarative_t( ec_type_t type )
+ explicit cbl_declarative_t( ec_type_t type )
: section(0)
, global(false)
, type(type)
std::copy( that.files, that.files + nfile, this->files );
}
}
- constexpr cbl_declarative_t& operator=(const cbl_declarative_t&) = default;
+ cbl_declarative_t& operator=(const cbl_declarative_t&) = default;
std::vector<uint64_t> encode() const;
// TRUE if there are no files to match, or the provided file is in the list.
bool match_file( size_t file ) const {
- static const auto pend = files + nfile; // cppcheck-suppress constVariablePointer
+ static const uint32_t * pend = files + nfile;
return nfile == 0 || pend != std::find(files, files + nfile, file);
}
public:
cbl_enabled_exceptions_t() {}
- cbl_enabled_exceptions_t( size_t nec, const cbl_enabled_exception_t *ecs )
+ cbl_enabled_exceptions_t( size_t nec, const cbl_enabled_exception_t *ecs )
: std::set<cbl_enabled_exception_t>(ecs, ecs + nec)
{}
void turn_on_off( bool enabled, bool location, ec_type_t type,
*/
-/* cppcheck has its opinions about ++iterator being superior to iterator++.
- however, can't abide by the prefix notation; it just looks dumb to me.
- And I have to believe that in the year of our Lord 2025 that the
- optimizing algorithms in modern compilers have sorted this out by now. */
-
extern "C"
void
__gg__handle_error(const char *function, const char *msg)
done:
// Per the standard, return the file location pointer back to whence it came:
fseek(file->file_pointer, starting_position, SEEK_SET);
- handle_ferror(file, __func__, "fseek() error");
+ handle_ferror(file, __func__, "fseek() error");
file->prior_op = file_op_rewrite;
establish_status(file, starting_position);
}
done:
// Per the standard, return the file location pointer back to whence it came:
fseek(file->file_pointer, starting_position, SEEK_SET);
- handle_ferror(file, __func__, "fseek() error");
+ handle_ferror(file, __func__, "fseek() error");
file->prior_op = file_op_rewrite;
establish_status(file, starting_position);
}
, user_status(nullptr)
, filename(nullptr)
{}
-// cppcheck-suppress noExplicitConstructor
- file_status_t( const cblc_file_t *file )
+ explicit file_status_t( const cblc_file_t *file )
: ifile(file->symbol_table_index)
, operation(file->prior_op)
, mode(cbl_file_mode_t(file->mode_char))
cbl_declaratives_t declaratives;
struct file_status_t file;
public:
- size_t lineno;
+ int lineno;
const char *source_file;
cbl_name_t statement; // e.g., "ADD"
}
ec_status_t& clear() {
handled = type = ec_none_e;
- isection = lineno = 0;
+ isection = 0;
+ lineno = 0;
msg[0] = statement[0] = '\0';
return *this;
}
const file_status_t& file_status() const { return file; }
const char * exception_location() {
- snprintf(msg, sizeof(msg), "%s:%zu: '%s'", source_file, lineno, statement);
+ snprintf(msg, sizeof(msg), "%s:%d: '%s'", source_file, lineno, statement);
return msg;
}
};
}
if( matches && MATCH_DECLARATIVE ) {
- warnx(" matches exception %s (file %zu mode %s)",
+ warnx(" matches exception %s (file %u mode %s)",
local_ec_type_str(raised.type),
- raised.file,
+ static_cast<unsigned int>(raised.file),
cbl_file_mode_str(raised.mode));
}
}
case ec_category_fatal_e:
case uc_category_fatal_e:
if( filename ) {
- syslog(priority, "fatal exception: %s:%zu: %s %s: %s (%s)",
+ syslog(priority, "fatal exception: %s:%d: %s %s: %s (%s)",
program_name,
ec_status.lineno,
ec_status.statement,
pec->name,
pec->description);
} else {
- syslog(priority, "fatal exception: %s:%zu: %s: %s (%s)",
+ syslog(priority, "fatal exception: %s:%d: %s: %s (%s)",
program_name,
ec_status.lineno,
ec_status.statement,
break;
case ec_category_nonfatal_e:
case uc_category_nonfatal_e:
- syslog(priority, "%s:%zu: %s: %s (%s)",
+ syslog(priority, "%s:%d: %s: %s (%s)",
program_name,
ec_status.lineno,
ec_status.statement,
warnx("%s: ec_status is %s", __func__, ec_status.unset()? "unset" : "set");
if( ec_status.copy_environment().unset() )
+ {
ec_status.update(); // __gg__match_exception was not called first
+ // This is a good time to set the exception code back to zero
+ __gg__exception_code = 0;
+ }
if( ec_status.done() ) { // false for part-handled fatal
if( MATCH_DECLARATIVE )
{
ec_stack.push(ec_status);
if( MATCH_DECLARATIVE )
- warnx("%s: %s: %zu ECs, %zu declaratives", __func__,
- __gg__exception_statement, enabled_ECs.size(), declaratives.size());
+ warnx("%s: %s: %u ECs, %u declaratives", __func__,
+ __gg__exception_statement,
+ static_cast<unsigned int>(enabled_ECs.size()),
+ static_cast<unsigned int>(declaratives.size()));
}
/*
ec_stack.pop();
ec_status.reset_environment();
if( MATCH_DECLARATIVE )
- warnx("%s: %s: %zu ECs, %zu declaratives", __func__,
- __gg__exception_statement, enabled_ECs.size(), declaratives.size());
+ warnx("%s: %s: %u ECs, %u declaratives", __func__,
+ __gg__exception_statement,
+ static_cast<unsigned int>(enabled_ECs.size()),
+ static_cast<unsigned int>(declaratives.size()));
__gg__check_fatal_exception();
}
void
cbl_enabled_exception_t::dump( int i ) const {
- warnx("cbl_enabled_exception_t: %2d {%s, %s, %zu}",
+ warnx("cbl_enabled_exception_t: %2d {%s, %s, %u}",
i,
location? "location" : " none",
local_ec_type_str(ec),
- file );
+ static_cast<unsigned int>(file) );
}
/*
* Format 1 may be restricted to a particular mode (for all files).
* Format 1 and 3 may be restricted to a set of files.
*/
+
+ // This is a good time to set the actual exception code back to zero.
+ __gg__exception_code = 0;
+
auto f = ec_status.file_status();
cbl_exception_t raised = { /*0,*/ f.ifile, ec, f.mode };
bool enabled = enabled_ECs.match(ec);
if( p == declaratives.end() ) {
if( MATCH_DECLARATIVE ) {
warnx("__gg__match_exception:%d: raised exception "
- "%s not matched (%zu enabled)", __LINE__,
- local_ec_type_str(ec), enabled_ECs.size());
+ "%s not matched (%u enabled)", __LINE__,
+ local_ec_type_str(ec),
+ static_cast<unsigned int>(enabled_ECs.size()));
}
} else {
isection = p->section;
if( MATCH_DECLARATIVE ) {
warnx("__gg__match_exception:%d: matched "
- "%s against mask %s for section #%zu",
+ "%s against mask %s for section #%u",
__LINE__,
local_ec_type_str(ec),
local_ec_type_str(p->type),
- p->section);
+ static_cast<unsigned int>(p->section));
}
}
assert(ec != ec_none_e);
}
int i = 1;
for( auto& elem : *this ) {
- warnx("%s: %2d {%s, %04x %s, %ld}", tag,
- i++,
- elem.location? "with location" : " no location",
- elem.ec,
- local_ec_type_str(elem.ec),
- elem.file );
+ warnx("%s: %2d {%s, %04x %s, %u}", tag,
+ i++,
+ elem.location? "with location" : " no location",
+ elem.ec,
+ local_ec_type_str(elem.ec),
+ static_cast<unsigned int>(elem.file) );
}
}
if( prior.ecs != ecs ) {
uint64_t *ecs_begin = ecs + 1, *ecs_end = ecs_begin + ecs[0];
if( MATCH_DECLARATIVE ) {
- warnx("%zu elements implies %zu ECs", ecs[0], ecs[0] / 3);
+ warnx("%u elements implies %u ECs",
+ static_cast<unsigned int>(ecs[0]),
+ static_cast<unsigned int>(ecs[0] / 3));
}
cbl_enabled_exceptions_t enabled;
enabled_ECs = enabled.decode( std::vector<uint64_t>(ecs_begin, ecs_end) );
if( prior.dcls != dcls ) {
uint64_t *dcls_begin = dcls + 1, *dcls_end = dcls_begin + dcls[0];
if( MATCH_DECLARATIVE ) {
- warnx("%zu elements implies %zu declaratives", dcls[0], dcls[0] / 21);
+ warnx("%u elements implies %u declaratives",
+ static_cast<unsigned int>(dcls[0]),
+ static_cast<unsigned int>(dcls[0] / 21));
}
declaratives.clear();
declaratives << std::vector<uint64_t>( dcls_begin, dcls_end );