diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 0c2f7f40..b03c08cb 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,9 @@ +2024-12-11 Emilien Lemaire + + * fileio.c: fixed Bug #1032 by always using global thread-static variable + bdb_app_data pointer to access the collating sequence function + 2024-12-08 Simon Sobisch * screenio.c [WITH_PANELS]: replace use of ncurses extension ceiling_panel() diff --git a/libcob/fileio.c b/libcob/fileio.c index 50962345..df7cc89c 100644 --- a/libcob/fileio.c +++ b/libcob/fileio.c @@ -690,12 +690,14 @@ static unsigned int bdb_lock_id = 0; key.data = fld->data; \ key.size = (cob_dbtsize_t) fld->size -#if (DB_VERSION_MAJOR > 4) || ((DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR > 0)) +#if 0 /* while the fields are part of DBT since 4.1, and were made part of the + public API with 6.0 (DB_VERSION_FAMILY 12) this field is not always + copied when passed to custom compare functions, see bug 1032 */ #define DBT_SET_APP_DATA(key,data) ((key)->app_data = (data)) #define DBT_GET_APP_DATA(key) ((key)->app_data) #else -/* Workaround for older BDB versions that do not have app_data in DBT */ -static void *bdb_app_data = NULL; +/* Used to save the collating sequence function */ +COB_TLS void *bdb_app_data = NULL; #define DBT_SET_APP_DATA(key,data) ((void)(key), bdb_app_data = (data)) #define DBT_GET_APP_DATA(key) ((void)(key), bdb_app_data) #endif diff --git a/tests/testsuite.src/run_file.at b/tests/testsuite.src/run_file.at index f7fbbfe8..0093e1df 100644 --- a/tests/testsuite.src/run_file.at +++ b/tests/testsuite.src/run_file.at @@ -14653,3 +14653,98 @@ AT_CHECK([$COBCRUN_DIRECT ./prog2 > prog2.txt]) AT_CHECK([diff expected.txt prog2.txt]) AT_CLEANUP + + +AT_SETUP([DELETE WITH COLLATING SEQUENCE]) +AT_KEYWORDS([runfile WRITE DELETE READ EBCDIC]) + +AT_SKIP_IF([test "$COB_HAS_ISAM" != "db"]) +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. READDEL. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + + SELECT READDEL ASSIGN EXTERNAL READDEL + ORGANIZATION INDEXED + ACCESS MODE DYNAMIC + RECORD KEY READDEL-KEY + FILE STATUS STA-READDEL. + + DATA DIVISION. + FILE SECTION. + + FD READDEL. + 01 READDEL-REC. + 02 READDEL-KEY. + 05 READDEL-KEY-NUM PIC S9(15). + 02 READDEL-VALUE. + 05 READDEL-STRING PIC X(10). + 05 READDEL-NUM PIC S9(27) OCCURS 10 TIMES. + *> + + *>----------------------* + WORKING-STORAGE SECTION. + *>----------------------* + + 01 STA-READDEL PIC X(2). + 01 END-READDEL PIC 9(1). + 01 WS-COUNT PIC S9(2) VALUE 0. + + *>------------------* + PROCEDURE DIVISION. + *>------------------* + MOVE 0 TO END-READDEL. + OPEN OUTPUT READDEL. + PERFORM 20 TIMES + MOVE WS-COUNT TO READDEL-KEY-NUM + MOVE "READDELNUM" TO READDEL-STRING + MOVE WS-COUNT TO READDEL-NUM(1) + MOVE WS-COUNT TO READDEL-NUM(2) + MOVE WS-COUNT TO READDEL-NUM(3) + MOVE WS-COUNT TO READDEL-NUM(4) + MOVE WS-COUNT TO READDEL-NUM(5) + MOVE WS-COUNT TO READDEL-NUM(6) + MOVE WS-COUNT TO READDEL-NUM(7) + MOVE WS-COUNT TO READDEL-NUM(8) + MOVE WS-COUNT TO READDEL-NUM(9) + MOVE WS-COUNT TO READDEL-NUM(10) + WRITE READDEL-REC + INVALID KEY + DISPLAY "INVALID KEY " READDEL-KEY + STOP RUN + END-WRITE + ADD 1 TO WS-COUNT + END-PERFORM. + CLOSE READDEL. + MOVE LOW-VALUE TO READDEL-KEY. + OPEN I-O READDEL. + START READDEL KEY IS > READDEL-KEY + INVALID KEY + DISPLAY "ERR START READDEL=" STA-READDEL + MOVE 1 TO END-READDEL + END-START. + PERFORM UNTIL END-READDEL = 1 + READ READDEL NEXT RECORD + AT END + MOVE 1 TO END-READDEL + NOT AT END + DELETE READDEL + INVALID KEY + DISPLAY "ERR DELETE KEY=" READDEL-KEY + " / STATUS=" STA-READDEL + END-DELETE + END-READ + END-PERFORM. + CLOSE READDEL. + STOP RUN. + + +]) + +AT_CHECK([$COMPILE -fdefault-file-colseq=EBCDIC prog.cob]) +AT_CHECK([$COBCRUN_DIRECT ./prog]) + +AT_CLEANUP