cobol: Diagnostic messages, Flex build, and some cppcheck reports. [PR120328, PR119695]

Remove %0x and similar from diagnostic framework messages.  Remove %zu
from printf messages because it is not supported on some
platforms. Corrections in response to cppcheck.  Sundry small fixes.

gcc/cobol/ChangeLog:

	PR cobol/120328
	* Make-lang.in: Success with non-English locale.
	PR cobol/119695
	* cbldiag.h (cbl_unimplemented_at): Comment:
	* cdf-copy.cc (copybook_elem_t::open_file): Indentation.
	* cdf.y: YYABORT on certain errors.
	* cdfval.h (cdf_value): Const parameter.
	* copybook.h (class copybook_elem_t): Initialization.
	(class uppername_t): Explicit constructor.
	* except.cc (ec_type_descr): Remove %04s.
	(cbl_enabled_exceptions_t::dump): Remove %zu.
	* exceptg.h (class exception_turn_t): Explicit constructor.
	* genapi.cc (parser_perform_conditional): Remove %zu.
	(set_exception_environment): Formatting.
	(parser_statement_begin): Exception overhead.
	(parser_perform_conditional): Formatting:
	(parser_perform_conditional_end): Eliminate size_t.
	(parser_check_fatal_exception): Exception overhead.
	(parser_perform_conditional_end): Remove %zu.
	* inspect.h (struct cbx_inspect_match_t): Const reference.
	(struct cbx_inspect_t): Const parameter.
	* lexio.cc (cdftext::process_file): Remove %zu.
	* lexio.h (struct YYLTYPE): Remove unneeded struct.
	(YYLTYPE_IS_DECLARED): Likewise.
	(YYLTYPE_IS_TRIVIAL): Likewise.
	* parse.y: Comment; change DOT.
	* scan.l: Scan function names without swallowing whitespace.
	* scan_ante.h (scanner_parsing): Remove %zu.
	(scanner_parsing_pop): Remove %zu.
	(binary_integer_usage): Remove %zu.
	* scan_post.h (prelex): Correct post-CDF resumption.
	(yylex): Clearer message.
	* symbols.cc (symbol_table_extend): Explicit constructor.
	(elementize): Const parameter.
	(is_variable_length): Correct always-false.
	(symbols_update): Remove unnecessary shadow variable.
	(struct symbol_elem_t): Const parameter.
	(symbol_alphabet_add): Const parameter.
	(new_literal_add): Initialization.
	* symbols.h (class cbl_domain_elem_t): Correct assignment.
	(struct cbl_span_t): Improve constructor.
	(struct cbl_refer_t): Initialization.
	(struct cbl_alphabet_t): Rename shadow variable.
	(struct cbl_file_key_t): Remove unused constructor.
	(struct symbol_elem_t): Initialization.
	(struct cbl_until_addresses_t): Use unsigned int, for messages.
	(struct cbl_prog_hier_t): Initialization.
	(struct cbl_perform_tgt_t): Repair constructor.
	(struct cbl_label_t): Const parameter.
	(symbol_typedef_add): Const parameter.
	(symbol_field_add): Explicit constructor.
	(symbol_label_add): Explicit constructor.
	(symbol_program_add): Remove C-style "struct" use.
	(symbol_special_add): Remove C-style "struct" use.
	(symbol_alphabet_add): Const parameter.
	(symbol_file_add): Remove C-style "struct" use.
	(symbol_section_add): Remove C-style "struct" use.
	* symfind.cc: Const parameter.
	* util.cc (gb4): New function.
	* util.h (gb4): New function.
	* TODO: New file.

libgcobol/ChangeLog:

	* common-defs.h (enum cbl_file_mode_t): Whitespace.
	(enum file_stmt_t): Likewise.
	(ec_cmp): Likewise.
	(struct cbl_declarative_t): Add "explicit" keyword.
	(class cbl_enabled_exceptions_t): Whitespace.
	* gfileio.cc: Remove cppcheck comment.
	* libgcobol.cc (class ec_status_t): Add "explicit" keyword.
	(match_declarative): Remove %zu.
	(default_exception_handler): Likwise.
	(__gg__check_fatal_exception): Exception overhead.
	(__gg__exception_push): Remove %zu.
	(__gg__exception_pop): Likewise.
	(cbl_enabled_exception_t::dump): Likewise.
	(__gg__match_exception): Exception overhead; remove %zu.
	(cbl_enabled_exceptions_t::dump): Remove %zu.
	(__gg__set_exception_environment): Likewise.

Co-authored-by: James K. Lowden <jklowden@cobolworx.com>
Co-authored-by: Robert Dubner <rdubner@symas.com>
(cherry picked from commit 37f5fdd008)
This commit is contained in:
Robert Dubner 2025-06-06 16:32:22 -04:00
parent 6c214d4e45
commit cd1fd18402
25 changed files with 437 additions and 353 deletions

View File

@ -159,8 +159,7 @@ FLEX_WARNING = warning, dangerous trailing context
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 $@~

33
gcc/cobol/TODO Normal file
View File

@ -0,0 +1,33 @@
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

View File

@ -93,9 +93,9 @@ void cbl_unimplemented(const char *gmsgid, ...); // error
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;

View File

@ -304,9 +304,9 @@ copybook_elem_t::open_file( const char directory[], bool literally ) {
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;

View File

@ -263,7 +263,7 @@ top: partials { YYACCEPT; }
}
| copy error {
error_msg(@error, "COPY directive must end in a '.'");
YYACCEPT;
YYABORT;
}
| completes { YYACCEPT; }
;
@ -584,7 +584,7 @@ copybook_name: COPY name_one[src]
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]
@ -593,7 +593,7 @@ copybook_name: COPY name_one[src]
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;
}
}
;
@ -864,7 +864,7 @@ static int ydflex(void) {
}
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;

View File

@ -116,6 +116,6 @@ const cdfval_t *
cdf_value( const char name[] );
bool
cdf_value( const char name[], cdfval_t value );
cdf_value( const char name[], const cdfval_t& value );
#endif

View File

@ -62,7 +62,7 @@ class copybook_elem_t {
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;
@ -74,12 +74,11 @@ class copybook_elem_t {
copybook_elem_t()
: suppress(false)
, literally()
, fd(-1)
, nsubexpr(0)
, regex_text(NULL)
{
literally = {};
}
{}
void clear() {
suppress = false;
@ -130,7 +129,7 @@ private:
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); } );
}

View File

@ -51,7 +51,7 @@ static const ec_descr_t *
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;
}

View File

@ -58,8 +58,8 @@ class exception_turn_t {
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);
}
@ -74,7 +74,7 @@ class exception_turn_t {
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));

View File

@ -1019,10 +1019,63 @@ parser_compile_dcls( const std::vector<uint64_t>& dcls )
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
{
@ -1052,6 +1105,35 @@ parser_statement_begin( const cbl_name_t statement_name, tree ecs, tree dcls )
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
@ -1064,23 +1146,17 @@ parser_statement_begin( const cbl_name_t statement_name, tree ecs, tree dcls )
// 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;
}
@ -7833,12 +7909,13 @@ parser_perform_conditional( struct cbl_perform_tgt_t *tgt )
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);
@ -7882,7 +7959,7 @@ parser_perform_conditional_end( struct cbl_perform_tgt_t *tgt )
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
@ -13427,48 +13504,6 @@ parser_set_numeric(struct cbl_field_t *tgt, ssize_t value)
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()
{
@ -13548,9 +13583,17 @@ parser_check_fatal_exception()
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

View File

@ -102,8 +102,8 @@ struct cbx_inspect_match_t {
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)
@ -192,7 +192,7 @@ typedef cbx_inspect_oper_t<cbl_refer_t> cbl_inspect_oper_t;
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() )
@ -200,7 +200,7 @@ struct cbx_inspect_t {
, 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)

View File

@ -1905,9 +1905,12 @@ cdftext::process_file( filespan_t mfile, int output, bool second_pass ) {
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 ) {

View File

@ -110,19 +110,7 @@ struct bytespan_t {
}
};
/* 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;

View File

@ -1453,6 +1453,7 @@ id_div: cdf_words IDENTIFICATION_DIV '.' program_id
cdf_words: %empty
| cobol_words
/* | error { error_msg(@1, "not a COBOL-WORD"); } */
;
cobol_words: cobol_words1
| cobol_words cobol_words1
@ -2298,8 +2299,8 @@ config_paragraph:
}
}
}
| REPOSITORY '.'
| REPOSITORY '.' repo_members '.'
| REPOSITORY dot
| REPOSITORY dot repo_members '.'
;
repo_members: repo_member
@ -2950,7 +2951,7 @@ fd_clause: record_desc
f->attr |= external_e;
cbl_unimplemented("AS LITERAL");
}
| fd_linage
| fd_linage { cbl_unimplemented("LINAGE"); }
| fd_report {
cbl_unimplemented("REPORT WRITER");
YYERROR;
@ -3888,10 +3889,11 @@ data_clauses: data_clause
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();

View File

@ -79,6 +79,8 @@ nonseq (([''][[:alnum:]]+][''])|([""][[:alnum:]]+[""]))
INTEGER 0*[1-9][[:digit:]]*
INTEGERZ [[:digit:]]+
NONWORD [^[:alnum:]$_-]+
SPC [[:space:]]+
OSPC [[:space:]]*
EOL \r?\n
@ -1795,126 +1797,128 @@ USE({SPC}FOR)? { return USE; }
}
<function>{
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; }
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; }
EXP/{NONWORD} { pop_return EXP; }
EXP10/{NONWORD} { pop_return EXP10; }
FACTORIAL/{NONWORD} { pop_return FACTORIAL; }
FIND-STRING/{NONWORD} { pop_return FIND_STRING; }
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; }
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; }
EXP{OSPC}/[(]? { pop_return EXP; }
EXP10{OSPC}/[(]? { pop_return EXP10; }
FACTORIAL{OSPC}/[(]? { pop_return FACTORIAL; }
FIND-STRING{OSPC}/[(]? { pop_return FIND_STRING; }
HEX-OF/{NONWORD} { pop_return HEX_OF; }
HEX-TO-CHAR/{NONWORD} { pop_return HEX_TO_CHAR; }
HIGHEST-ALGEBRAIC/{NONWORD} { pop_return HIGHEST_ALGEBRAIC; }
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; }
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));

View File

@ -313,8 +313,9 @@ bool scanner_normal() { return parsing.normal(); }
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();
}
}
@ -336,8 +337,9 @@ void scanner_parsing_pop() {
}
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();
}
}
@ -577,7 +579,8 @@ binary_integer_usage( const char name[]) {
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);

View File

@ -260,13 +260,12 @@ prelex() {
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.
@ -375,7 +374,7 @@ yylex(void) {
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",

View File

@ -56,7 +56,7 @@ class symbol_pair_t
{
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)
{}
@ -160,8 +160,8 @@ symbol_table_extend() {
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));
}
/*
@ -280,7 +280,7 @@ class group_size_t {
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;
@ -907,7 +907,7 @@ end_of_group( const cbl_field_t *group, const cbl_field_t *field ) {
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));
@ -1339,19 +1339,18 @@ immediately_follows( const cbl_field_t *field ) {
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;
}
@ -1704,7 +1703,6 @@ symbols_update( size_t first, bool parsed_ok ) {
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();
}
@ -2102,7 +2100,7 @@ class parent_elem_set
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 ) {
@ -2419,9 +2417,9 @@ symbol_file_add( size_t program, cbl_file_t *file ) {
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);
}
@ -3230,7 +3228,6 @@ parser_symbol_add2( cbl_field_t *field ) {
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) )
{
@ -3240,6 +3237,7 @@ new_literal_add( const char initial[], uint32_t len, enum cbl_field_attr_t attr
}
else
{
static char empty[2] = "\0";
field = new_temporary_impl(FldLiteralA);
field->attr |= attr;
field->data.initial = len > 0? initial : empty;

View File

@ -173,7 +173,7 @@ class cbl_domain_elem_t {
{
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; }
@ -641,7 +641,7 @@ struct cbl_refer_t;
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 ); }
@ -660,12 +660,12 @@ struct cbl_refer_t {
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)
{}
@ -675,14 +675,14 @@ struct cbl_refer_t {
, 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)
@ -690,7 +690,7 @@ struct cbl_refer_t {
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))
{}
@ -1419,10 +1419,10 @@ struct cbl_alphabet_t {
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++);
}
}
@ -1430,10 +1430,10 @@ struct cbl_alphabet_t {
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++);
}
}
@ -1524,15 +1524,6 @@ struct cbl_file_key_t {
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,
@ -1636,10 +1627,7 @@ struct symbol_elem_t {
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 )
@ -1926,7 +1914,7 @@ struct cbl_until_addresses_t {
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
@ -1990,7 +1978,7 @@ struct cbl_prog_hier_t {
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;
@ -2008,13 +1996,11 @@ struct cbl_prog_hier_t {
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));
@ -2252,21 +2238,21 @@ size_t symbols_update( size_t first, bool parsed_ok = true );
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 );

View File

@ -275,8 +275,8 @@ update_symbol_map( symbol_elem_t *e ) {
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;
}
@ -298,7 +298,7 @@ class reduce_ancestry {
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(),
@ -331,7 +331,7 @@ public:
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);
}
@ -346,7 +346,7 @@ class in_scope {
}
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 {
@ -561,7 +561,7 @@ symbol_find( size_t program, std::list<const char *> names ) {
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(),

View File

@ -95,6 +95,22 @@ get_current_dir_name ()
}
#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 )
{

View File

@ -48,5 +48,6 @@ void cobol_set_pp_option(int opt);
const char * cobol_filename_restore();
const char * cobol_lineno_save();
unsigned long gb4( size_t input );
#endif

View File

@ -237,7 +237,7 @@ enum cbl_file_mode_t {
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 {
@ -288,15 +288,15 @@ enum bitop_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,
@ -412,14 +412,14 @@ ec_cmp( ec_type_t raised, ec_type_t ec )
{
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)
&
@ -464,8 +464,7 @@ struct cbl_declarative_t {
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)
@ -474,8 +473,7 @@ struct cbl_declarative_t {
{
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)
@ -512,7 +510,7 @@ struct cbl_declarative_t {
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;
@ -539,7 +537,7 @@ struct cbl_declarative_t {
// 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);
}
@ -568,7 +566,7 @@ class cbl_enabled_exceptions_t : protected std::set<cbl_enabled_exception_t>
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,

View File

@ -105,11 +105,6 @@
*/
/* 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)
@ -1812,7 +1807,7 @@ relative_file_rewrite_varying( cblc_file_t *file, bool is_random )
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);
}
@ -1913,7 +1908,7 @@ relative_file_rewrite( cblc_file_t *file, size_t length, bool is_random )
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);
}

View File

@ -266,8 +266,7 @@ class ec_status_t {
, 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))
@ -296,7 +295,7 @@ class ec_status_t {
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"
@ -325,7 +324,8 @@ class ec_status_t {
}
ec_status_t& clear() {
handled = type = ec_none_e;
isection = lineno = 0;
isection = 0;
lineno = 0;
msg[0] = statement[0] = '\0';
return *this;
}
@ -345,7 +345,7 @@ class ec_status_t {
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;
}
};
@ -11222,9 +11222,9 @@ match_declarative( bool enabled,
}
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));
}
}
@ -11312,7 +11312,7 @@ default_exception_handler( ec_type_t ec )
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,
@ -11320,7 +11320,7 @@ default_exception_handler( ec_type_t ec )
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,
@ -11331,7 +11331,7 @@ default_exception_handler( ec_type_t ec )
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,
@ -11393,7 +11393,11 @@ __gg__check_fatal_exception()
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 )
@ -11460,8 +11464,10 @@ __gg__exception_push()
{
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()));
}
/*
@ -11475,8 +11481,10 @@ __gg__exception_pop()
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();
}
@ -11490,11 +11498,11 @@ __gg__clear_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) );
}
/*
@ -11530,6 +11538,10 @@ __gg__match_exception( cblc_field_t *index )
* 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);
@ -11544,8 +11556,9 @@ __gg__match_exception( cblc_field_t *index )
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;
@ -11553,11 +11566,11 @@ __gg__match_exception( cblc_field_t *index )
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);
@ -13082,12 +13095,12 @@ cbl_enabled_exceptions_t::dump( const char tag[] ) const {
}
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) );
}
}
@ -13137,7 +13150,9 @@ __gg__set_exception_environment( uint64_t *ecs, uint64_t *dcls )
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) );
@ -13151,7 +13166,9 @@ __gg__set_exception_environment( uint64_t *ecs, uint64_t *dcls )
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 );