Skip to content

Commit

Permalink
Fix bug 1008
Browse files Browse the repository at this point in the history
  • Loading branch information
ddeclerck committed Nov 29, 2024
1 parent 04916dd commit 65cefb0
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:

- name: Install packages
run: |
brew install pkg-config automake libtool help2man texinfo bison berkeley-db@4 json-c
brew install automake libtool help2man texinfo bison berkeley-db@4 json-c
opt="/opt/homebrew/opt"
echo "$opt/pkg-config/bin" >> $GITHUB_PATH
echo "LDFLAGS=-L$opt/berkeley-db@4/lib ${LDFLAGS}" >> $GITHUB_ENV
Expand Down
9 changes: 9 additions & 0 deletions libcob/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@

2024-11-22 Chuck Haatvedt <[email protected]>

* move.c (optimized_move_display_to_edited): fixed
Bug #1008: regression in move to numeric edited
items with insertion symbols B, 0 and /
* move.c (optimized_move_display_to_edited): minor refactoring
* system.def, move.c: added definition for COBOL2025
COB_EC_DATA_NULL + COB_EC_DATA_TRUNCATION (currently not used)

2024-10-22 Chuck Haatvedt <[email protected]>

* screenio.c (cob_screen_get_all): fixed Bug #999
Expand Down
9 changes: 9 additions & 0 deletions libcob/exception.def
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ COB_EXCEPTION (0305, COB_EC_DATA_OVERFLOW,
COB_EXCEPTION (0306, COB_EC_DATA_PTR_NULL,
"EC-DATA-PTR-NULL", 1)

/* Attempt to use a null valued data item in a context where not permitted (COBOL2025) */
COB_EXCEPTION (0307, COB_EC_DATA_NULL,
"EC-DATA-NULL", 1)

/* A non-space or significant-digit was truncated during MOVE (COBOL2025) */
COB_EXCEPTION (0308, COB_EC_DATA_TRUNCATION,
"EC-DATA-TRUNCATION", 0)



/* EXTERNAL item mismatch (COBOL 202x) */
COB_EXCEPTION (1900, COB_EC_EXTERNAL,
Expand Down
105 changes: 66 additions & 39 deletions libcob/move.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,19 @@ store_common_region (cob_field *f, const unsigned char *data,
const int hf2 = fsize + lf2;
const int gcf = cob_min_int (hf1, hf2);

#if 0 /* TODO: globally add support for COB_EC_DATA_TRUNCATION */
const unsigned char *p = data;
const unsigned char *end = data + hf1 - gcf;
while (p < end) {
if ((COB_FIELD_IS_NUMERIC (f) && (*p != '0'))
|| (COB_FIELD_IS_ANY_ALNUM (f) && (*p != ' '))) {
cob_set_exception (COB_EC_DATA_TRUNCATION);
break;
}
++p;
}
#endif

/* the target may have leading/trailing additional zeroes
and in rare cases, we may be out of scale competely;
we pre-set all positions as this saves a bunch of
Expand Down Expand Up @@ -1011,18 +1024,15 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
int suppress_zero = 1;
int have_decimal_point = 0;
int have_check_protect = 0;
int n;
int cntr_currency = 0;
int cntr_sign_neg = 0;
int cntr_sign_pos = 0;
int cntr_sign = 0;
unsigned char pad = ' ';
unsigned char c;
unsigned char float_char = 0x00;
const unsigned char dec_symbol = COB_MODULE_PTR->decimal_point == ','
? ',' : '.';
const unsigned char dec_symbol = COB_MODULE_PTR->decimal_point == ',' ? ',' : '.';
const unsigned char currency = COB_MODULE_PTR->currency_symbol;

#if 1 /* Sanity check to ensure that the data types of both the fields have the
#if 1 /* Sanity check to ensure that the data types of both the fields have the
correct attributes, if not then something is brokend and needs to be fixed */
if (!(COB_FIELD_TYPE (f2) == COB_TYPE_NUMERIC_EDITED
&& COB_FIELD_DIGITS (f1) == COB_FIELD_DIGITS (f2)
Expand All @@ -1048,21 +1058,17 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)

for (p = COB_FIELD_PIC (f2); p->symbol; ++p) {
c = p->symbol;
n = p->times_repeated;
if ((c == '9')
|| (c == 'Z')
|| (c == '*')
|| (c == 'C')
|| (c == 'D')) {
break;
} else if (c == '-') {
cntr_sign_neg += n;
if (cntr_sign_neg > 1) break;
} else if (c == '+') {
cntr_sign_pos += n;
if (cntr_sign_pos > 1) break;
} else if ((c == '-') || (c == '+')) {
cntr_sign += p->times_repeated;
if (cntr_sign > 1) break;
} else if (c == currency) {
cntr_currency += n;
cntr_currency += p->times_repeated;
if (cntr_currency > 1) break;
}
}
Expand All @@ -1079,26 +1085,32 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
}

/* first check for BLANK WHEN ZERO attribute */
if (COB_FIELD_BLANK_ZERO(f2)) {
for(; (src <= src_end) ; src++) {
if (COB_FIELD_BLANK_ZERO (f2)) {
for (; (src <= src_end) ; src++) {
if (*src != '0') break;
}
if (src > src_end) {
memset(dst, (int)' ', (size_t)f2->size);
memset (dst, (int)' ', (size_t)f2->size);
return;
}
src = f1->data;
}

if (COB_FIELD_HAVE_SIGN(f1))
if (COB_FIELD_HAVE_SIGN (f1)) {
neg = (*src_end == '-') ? 1 : 0;
}

for (p = COB_FIELD_PIC (f2); p->symbol; ++p) {
int n;
c = p->symbol;
n = p->times_repeated;
if (c == 'P')
if (c == 'P') {
continue;
for (; n > 0; n--) {
}
if (c == 'V') {
have_decimal_point = 1;
continue;
}
for (n = p->times_repeated; n > 0; n--) {
if (dst >= dst_end) {
cob_runtime_error ("optimized_move_display_to_edited: overflow in destination field");
break;
Expand All @@ -1121,8 +1133,9 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
if (*src != '0') {
is_zero = suppress_zero = 0;
} else {
if (suppress_zero && (!have_decimal_point))
if (suppress_zero && (!have_decimal_point)) {
*dst = pad;
}
}
src++;
dst++;
Expand All @@ -1134,8 +1147,9 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
if (*src != '0') {
is_zero = suppress_zero = 0;
} else {
if (suppress_zero && (!have_decimal_point))
if (suppress_zero && (!have_decimal_point)) {
*dst = pad;
}
}
src++;
dst++;
Expand Down Expand Up @@ -1184,11 +1198,13 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
*dst = *prev_float_char;
*prev_float_char = pad;
prev_float_char = dst;
if (*dst == '-' || *dst == '+')
if (*dst == '-' || *dst == '+') {
sign_position = dst;
}
}
else
else {
*dst = pad;
}
} else {
*dst = c;
}
Expand All @@ -1197,12 +1213,20 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
break;

case 'V':
have_decimal_point = 1;
break;

case '0':
case '/':
*dst = c;
if (suppress_zero && prev_float_char) {
*dst = *prev_float_char;
*prev_float_char = pad;
prev_float_char = dst;
if (*dst != currency) {
sign_position = dst;
}
} else {
*dst = c;
}
dst++;
break;

Expand All @@ -1211,6 +1235,9 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)
*dst = *prev_float_char;
*prev_float_char = pad;
prev_float_char = dst;
if (*dst != currency) {
sign_position = dst;
}
} else if (have_check_protect) {
*dst = pad;
} else {
Expand Down Expand Up @@ -1283,36 +1310,36 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2)

/* if we have not printed any digits set destination to spaces and return */

if (suppress_zero){
if (pad == '*'){
for(dst = f2->data; dst < dst_end; dst++) {
if (*dst != dec_symbol){
if (suppress_zero) {
if (pad == '*') {
for (dst = f2->data; dst < dst_end; dst++) {
if (*dst != dec_symbol) {
*dst = '*';
}
}
} else {
memset(f2->data, ' ', f2->size);
memset (f2->data, ' ', f2->size);
return;
}
}

if (sign_position == NULL)
if (sign_position == NULL) {
return;
}

if ((neg) && (*sign_position == '+')){
if ((neg) && (*sign_position == '+')) {
*sign_position = (is_zero) ? '+' : '-';
return;
}

if ((neg) && (*sign_position == '-')){
if ((neg) && (*sign_position == '-')) {
*sign_position = (is_zero) ? ' ' : '-';
return;
}

}

if ((*sign_position == '-') && (!neg))
if ((*sign_position == '-') && (!neg)) {
*sign_position = ' ';

}
}


Expand Down
107 changes: 104 additions & 3 deletions tests/testsuite.src/run_fundamental.at
Original file line number Diff line number Diff line change
Expand Up @@ -1980,13 +1980,13 @@ AT_DATA([prog.cob], [

MOVE 10 TO identifier-1
MOVE identifier-1 TO EX-13
IF EX-13 EQUAL " $//00//10 "
IF EX-13 EQUAL " $00//10 "
MOVE "PASS" TO MSG-1
D DISPLAY " $//00//10 IS WHAT I EXPECTED"
D DISPLAY " $00//10 IS WHAT I EXPECTED"
ELSE
ADD 1 TO WS-COUNT
MOVE "FAIL" TO MSG-1
DISPLAY "EX-13.02 EXPECTING ==>' $//00//10 ' "
DISPLAY "EX-13.02 EXPECTING ==>' $00//10 ' "
"WHAT I GOT WAS ==>'"
EX-13 "'<=="
D DISPLAY "------------------" MSG-1
Expand Down Expand Up @@ -2510,6 +2510,107 @@ AT_CHECK([$COBCRUN_DIRECT ./prog], [0],
AT_CLEANUP


AT_SETUP([MOVE to item with +, -, B, 0, / and ,])
AT_KEYWORDS([fundamental edited editing])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 W-P4 PIC S9 VALUE +4.
01 W-M4 PIC S9 VALUE -4.
01 W-M PIC -B- VALUE SPACES.
01 W-P PIC +B+ VALUE SPACES.

01 W-P123 PIC S9(3) VALUE +123.
01 W-M123 PIC S9(3) VALUE -123.
01 W-MM PIC ---B--9 VALUE SPACES.
01 W-PP PIC +++B++9 VALUE SPACES.

01 W-X PIC -//00BB,,- VALUE SPACES.

PROCEDURE DIVISION.
MOVE W-P4 TO W-M.
DISPLAY W-M.
MOVE W-M4 TO W-M.
DISPLAY W-M.
MOVE W-P4 TO W-P.
DISPLAY W-P.
MOVE W-M4 TO W-P.
DISPLAY W-P.

MOVE W-P123 TO W-MM.
DISPLAY W-MM.
MOVE W-M123 TO W-MM.
DISPLAY W-MM.
MOVE W-P123 TO W-PP.
DISPLAY W-PP.
MOVE W-M123 TO W-PP.
DISPLAY W-PP.

MOVE W-P4 TO W-X.
DISPLAY W-X.
MOVE W-M4 TO W-X.
DISPLAY W-X.

MOVE W-P123 TO W-X.
DISPLAY W-X.
MOVE W-M123 TO W-X.
DISPLAY W-X.

STOP RUN.
])

AT_CHECK([$COMPILE prog.cob], [0], [], [])
AT_CHECK([$COBCRUN_DIRECT ./prog], [0],
[ 4
-4
+4
-4
123
-123
+123
-123
4
-4
3
-3
])

AT_CLEANUP


AT_SETUP([MOVE to shorter edited item (truncation)])
AT_KEYWORDS([fundamental edited editing])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 W-SRC1 PIC 999V99 VALUE 123.45.
01 W-SRC2 PIC 9999V9 VALUE 1234.5.
01 W-DST PIC ZZZV.

PROCEDURE DIVISION.
MOVE W-SRC1 TO W-DST.
DISPLAY W-DST.
MOVE W-SRC2 TO W-DST.
DISPLAY W-DST WITH NO ADVANCING.
STOP RUN.
])

AT_CHECK([$COMPILE prog.cob], [0], [], [])
AT_CHECK([$COBCRUN_DIRECT ./prog], [0],
[123
234])

AT_CLEANUP


AT_SETUP([MOVE to JUSTIFIED item])
AT_KEYWORDS([fundamental])

Expand Down

0 comments on commit 65cefb0

Please sign in to comment.