diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 00cd916fe..1d10aab1e 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,11 @@ +2024-07-09 Boris Eng + + * fileio.c (bdb_bt_compare, indexed_open): handle BDB keys of different + length with a flag USE_BDB_KEYDIFF (passed with preparser flag CPPFLAGS) + * common.c (cob_cmp_strings), coblocal.h (cob_cmp_strings): + extracted from (cob_cmp_alnum) + 2024-05-15 Simon Sobisch * profiling.c: fix compile warnings diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 46dfcc576..ebbcd023b 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -494,6 +494,9 @@ COB_HIDDEN const char *cob_get_last_exception_name (void); COB_HIDDEN void cob_parameter_check (const char *, const int); COB_HIDDEN char* cob_get_strerror (void); +COB_HIDDEN int cob_cmp_strings (unsigned char*, unsigned char*, + size_t, size_t, const unsigned char*); + enum cob_case_modifier { CCM_NONE, CCM_LOWER, diff --git a/libcob/common.c b/libcob/common.c index 427995006..f528c763c 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -1975,16 +1975,14 @@ cob_cmp_all (cob_field *f1, cob_field *f2) return ret; } -/* compare content of field 'f1' to content of 'f2', space padded, - using the optional collating sequence of the program */ -static int -cob_cmp_alnum (cob_field *f1, cob_field *f2) +/* compare string 'data1' to string 'data2', of size 'size1' and 'size2' + respectively, space padded, using a given collating sequence */ +int +cob_cmp_strings ( + unsigned char* data1, unsigned char* data2, + size_t size1, size_t size2, + const unsigned char *col) { - const unsigned char *col = COB_MODULE_PTR->collating_sequence; - const unsigned char *data1 = COB_FIELD_DATA (f1); - const unsigned char *data2 = COB_FIELD_DATA (f2); - const size_t size1 = COB_FIELD_SIZE (f1); - const size_t size2 = COB_FIELD_SIZE (f2); const size_t min = (size1 < size2) ? size1 : size2; int ret; @@ -2025,6 +2023,20 @@ cob_cmp_alnum (cob_field *f1, cob_field *f2) return 0; } +/* compare content of field 'f1' to content of 'f2', space padded, + using the optional collating sequence of the program */ +static int +cob_cmp_alnum (cob_field *f1, cob_field *f2) +{ + const unsigned char *col = COB_MODULE_PTR->collating_sequence; + const unsigned char *data1 = COB_FIELD_DATA (f1); + const unsigned char *data2 = COB_FIELD_DATA (f2); + const size_t size1 = COB_FIELD_SIZE (f1); + const size_t size2 = COB_FIELD_SIZE (f2); + return cob_cmp_strings ((unsigned char *)data1, (unsigned char *)data2, + size1, size2, col); +} + /* comparision of all key fields for SORT (without explicit collation) in records pointed to by 'data1' and 'data2' */ static int diff --git a/libcob/fileio.c b/libcob/fileio.c index ec8dcb88e..1ec33c55e 100644 --- a/libcob/fileio.c +++ b/libcob/fileio.c @@ -920,19 +920,24 @@ bdb_bt_compare (DB *db, const DBT *k1, const DBT *k2 { const unsigned char *col = (unsigned char *)DBT_GET_APP_DATA (k1); COB_UNUSED (db); - +#ifdef USE_BDB_KEYDIFF /* flag passed with CPPFLAGS */ + return cob_cmp_strings (k1->data, k2->data, (size_t)k1->size, (size_t)k2->size, col); +#else /* LCOV_EXCL_START */ if (col == NULL) { cob_runtime_error ("bdb_bt_compare was set but no collating sequence was stored in DBT"); + cob_hard_failure (); } if (k1->size != k2->size) { cob_runtime_error ("bdb_bt_compare was given keys of different length"); + cob_hard_failure (); } /* LCOV_EXCL_STOP */ #if DB_VERSION_MAJOR >= 6 locp = NULL; /* docs: must be set to NULL or corruption can occur ... */ #endif return indexed_key_compare (k1->data, k2->data, k2->size, col); +#endif /* USE_BDB_KEYDIFF */ } #endif /* WITH_DB */ @@ -4671,9 +4676,14 @@ indexed_open (cob_file *f, char *filename, if (f->keys[i].tf_duplicates) { p->db[i]->set_flags (p->db[i], DB_DUP); } + /* TODO: add national compare function later */ +#ifdef USE_BDB_KEYDIFF + p->db[i]->set_bt_compare(p->db[i], bdb_bt_compare); +#else if (f->keys[i].collating_sequence) { p->db[i]->set_bt_compare(p->db[i], bdb_bt_compare); } +#endif } } else { handle_created = 0;