Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug #948: make HIGH/LOW-VALUE sensitive to program collating sequence #136

Open
wants to merge 3 commits into
base: gcos4gnucobol-3.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/windows-msvc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,18 +178,14 @@ jobs:
# sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at
sed -i '/run_misc/{N;/write to internal storage (1)/{N;N;N;N;s/traceon/traceon; echo "workflow:1">"$at_check_line_file"; at_fn_check_skip 77/;}}' tests/testsuite

# Fail two tests that behave differently under MSVC Debug
# Fail tests that behave differently under MSVC Debug
# - System routine CBL_GC_HOSTED: fails because libcob is linked with the debug version
# of the C runtime while the generated module is linked with the release version
# - PROGRAM COLLATING SEQUENCE: fails because of a data loss in a cast, due
# to lack of specific handling of LOW/HIGH-VALUE for NATIONAL alphabets
# (see typeck.c:cb_validate_collating)
- name: Adjust testsuite for Debug target
if: ${{ matrix.target == 'Debug' }}
shell: C:\shells\msys2bash.cmd {0}
run: |
sed -i '/run_extensions/{N;/System routine CBL_GC_HOSTED/{N;s/at_xfail=no/at_xfail=yes/;}}' tests/testsuite
sed -i '/syn_definition/{N;/PROGRAM COLLATING SEQUENCE/{N;s/at_xfail=no/at_xfail=yes/;}}' tests/testsuite

- name: Run testsuite
run: |
Expand Down
19 changes: 19 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,25 @@
also forces -E, -foneline-deps, -MT=copybooks, disables errors on
missing copybooks and removes output on stdout

2024-02-26 David Declerck <[email protected]>

BUG #948: comparison with HIGH-VALUE in presence of collating sequences
* tree.h: add low_value and high_value fields to hold the low
and high values used by the program collating sequence
* tree.c: initialize the low_value and high_value fields
to reasonable default values
* typeck.c: replace cob_refer_ascii and cob_refer_ebcdic by
ebcdic_to_ascii and ascii_to_ebcdic; add load_collating_table
to load the tables; modify cb_validate_collating to call
load_collating_table and set low_value and high_value
fields modify validate_alphabet to use the new tables
* cobc.h: export the new symbols defined in typeck.c
* codegen.c: replace hard-coded 0 and 255 / 0xff contants with
the low_value and high_value fields where appropriate; move
the cob_all_low and cob_all_high fields from global to local;
adjust the output_collating_tables function to use the tables and
functions defined in typeck.c; set the new module field low_value

2024-02-19 Boris Eng <[email protected]>

* parser.y (screen_value_clause): replaced basic literals by literals
Expand Down
4 changes: 4 additions & 0 deletions cobc/cobc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4230,6 +4230,10 @@ process_command_line (const int argc, char **argv)
cb_flag_alt_ebcdic ? "alternate" : "default");
}

if (cob_load_collation (cb_ebcdic_table, ebcdic_to_ascii, ascii_to_ebcdic) < 0) {
cobc_err_exit (_("invalid parameter: %s"), "-febcdic-table");
}

/* Exit on missing options */
#ifdef COB_INTERNAL_XREF
if (cb_listing_xref && !cb_listing_outputfile) {
Expand Down
5 changes: 5 additions & 0 deletions cobc/cobc.h
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,11 @@ extern int yyparse (void);
/* typeck.c */
extern size_t suppress_warn; /* no warnings for internal generated stuff */

extern cob_u8_t ebcdic_to_ascii[256];
extern cob_u8_t ascii_to_ebcdic[256];

void load_collating_tables (void);

/* error.c */
#define CB_MSG_STYLE_GCC 0
#define CB_MSG_STYLE_MSC 1U
Expand Down
52 changes: 22 additions & 30 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -2515,23 +2515,23 @@ static void
output_low_value (void)
{
if (gen_figurative & CB_NEED_LOW) {
output ("static cob_field cob_all_low\t= ");
output ("{1, ");
output ("(cob_u8_ptr)\"\\0\", ");
output ("&cob_all_attr};");
output_newline ();
output_local ("static cob_field cob_all_low\t= ");
output_local ("{1, ");
output_local ("(cob_u8_ptr)\"\\x%02x\", ", current_prog->low_value);
output_local ("&cob_all_attr};");
output_local ("\n");
}
}

static void
output_high_value (void)
{
if (gen_figurative & CB_NEED_HIGH) {
output ("static cob_field cob_all_high\t= ");
output ("{1, ");
output ("(cob_u8_ptr)\"\\xff\", ");
output ("&cob_all_attr};");
output_newline ();
output_local ("static cob_field cob_all_high\t= ");
output_local ("{1, ");
output_local ("(cob_u8_ptr)\"\\x%02x\", ", current_prog->high_value);
output_local ("&cob_all_attr};");
output_local ("\n");
}
}

Expand Down Expand Up @@ -2615,8 +2615,6 @@ output_literals_figuratives_and_constants (void)

if (gen_figurative) {
output_newline ();
output_low_value ();
output_high_value ();
output_quote ();
output_space ();
output_zero ();
Expand Down Expand Up @@ -2654,18 +2652,6 @@ output_colseq_table_field (const char * field_name, const char * table_name)
static void
output_collating_tables (void)
{
cob_u8_t ebcdic_to_ascii[256];
cob_u8_t ascii_to_ebcdic[256];

/* Load the collating tables if needed */
if (gen_ascii_ebcdic || gen_ebcdic_ascii) {
if (cob_load_collation (cb_ebcdic_table,
gen_ebcdic_ascii ? ebcdic_to_ascii : NULL,
gen_ascii_ebcdic ? ascii_to_ebcdic : NULL) < 0) {
cobc_err_exit (_("invalid parameter: %s"), "-febcdic-table");
}
}

if (gen_native) {
output_storage ("\n/* NATIVE table */\n");
output_colseq_table ("cob_native", NULL);
Expand Down Expand Up @@ -4277,9 +4263,9 @@ output_funcall_typed (struct cb_funcall *p, const char type)
} else if (p->argv[1] == cb_zero) {
output (") - '0')");
} else if (p->argv[1] == cb_low) {
output ("))");
output (") - %d)", current_prog->low_value);
} else if (p->argv[1] == cb_high) {
output (") - 255)");
output (") - %d)", current_prog->high_value);
} else if (CB_LITERAL_P (p->argv[1])) {
output_char (") - ", CB_LITERAL (p->argv[1])->data[0], ")");
} else {
Expand Down Expand Up @@ -5064,10 +5050,10 @@ output_initialize_to_value (struct cb_field *f, cb_tree x,
output_figurative (x, f, ' ', init_occurs);
return;
} else if (value == cb_low) {
output_figurative (x, f, 0, init_occurs);
output_figurative (x, f, current_prog->low_value, init_occurs);
return;
} else if (value == cb_high) {
output_figurative (x, f, 255, init_occurs);
output_figurative (x, f, current_prog->high_value, init_occurs);
return;
} else if (value == cb_quote) {
if (cb_flag_apostrophe) {
Expand Down Expand Up @@ -10810,9 +10796,9 @@ output_class_name_definition (struct cb_class_name *p)
} else if (x == cb_null) {
vals[0] = 1;
} else if (x == cb_low) {
vals[0] = 1;
vals[current_prog->low_value] = 1;
} else if (x == cb_high) {
vals[255] = 1;
vals[current_prog->high_value] = 1;
} else {
size = CB_LITERAL (x)->size;
data = CB_LITERAL (x)->data;
Expand Down Expand Up @@ -14157,6 +14143,12 @@ codegen_internal (struct cb_program *prog, const int subsequent_call)
output_local ("\n");
}
}

/* Low and high values */
if (gen_figurative) {
output_low_value ();
output_high_value ();
}
}

void
Expand Down
19 changes: 1 addition & 18 deletions cobc/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -1347,10 +1347,6 @@ static cob_u8_t
scan_ebcdic_char (int c)
{
char buff[10]; /* Arbitrary limit, mostly for error-reporting */
#ifndef COB_EBCDIC_MACHINE
static cob_u8_t ebcdic_to_ascii[256] ;
static int ebcdic_to_ascii_initialized = 0 ;
#endif
unsigned int j = 0;
do {
buff[j++] = (char)c;
Expand All @@ -1367,20 +1363,7 @@ scan_ebcdic_char (int c)
#ifdef COB_EBCDIC_MACHINE
return (cob_u8_t) c;
#else
if (!ebcdic_to_ascii_initialized ) {
if (cob_load_collation (cb_ebcdic_table, ebcdic_to_ascii, NULL) < 0) {
cb_error (_("invalid parameter: %s"), "-febcdic-table");
ebcdic_to_ascii_initialized = -1;
} else {
ebcdic_to_ascii_initialized = 1;
}
}

if (ebcdic_to_ascii_initialized > 0) {
return ebcdic_to_ascii[c];
} else {
return '?';
}
return ebcdic_to_ascii[c];
#endif
}

Expand Down
4 changes: 4 additions & 0 deletions cobc/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,10 @@ cb_build_program (struct cb_program *last_program, const int nest_level)
p->decimal_point = '.';
p->currency_symbol = '$';
p->numeric_separator = ',';
p->low_value = 0;
p->high_value = 255;
p->low_value_n = 0;
p->high_value_n = 65535;
if (cb_call_extfh) {
p->extfh = cobc_parse_strdup (cb_call_extfh);
}
Expand Down
4 changes: 4 additions & 0 deletions cobc/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1916,6 +1916,10 @@ struct cb_program {
unsigned char decimal_point; /* '.' or ',' */
unsigned char currency_symbol; /* '$' or user-specified */
unsigned char numeric_separator; /* ',' or '.' */
cob_u8_t low_value; /* Low-value for this program */
cob_u8_t high_value; /* High-value for this program */
cob_u16_t low_value_n; /* National Low-value */
cob_u16_t high_value_n; /* National High-value */
enum cob_module_type prog_type; /* Program type (program = 0, function = 1) */
cb_tree entry_convention; /* ENTRY convention / PROCEDURE convention */
struct literal_list *decimal_constants;
Expand Down
Loading
Loading