Skip to content

Commit

Permalink
Add support for collating sequences on indexed files
Browse files Browse the repository at this point in the history
  • Loading branch information
ddeclerck committed Jan 26, 2024
1 parent f059c84 commit f840670
Show file tree
Hide file tree
Showing 12 changed files with 386 additions and 40 deletions.
11 changes: 11 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@

2024-01-25 David Declerck <[email protected]>

FR #459: support COLLATING SEQUENCE clause on SELECT / INDEXED files
* codegen.c (output_file_initialization): output the indexed
file collating sequence (was already present in the AST)
* parser.y (collating_sequence_clause): remove the
CB_PENDING warning on file collating sequence
* flag.def, tree.h, cobc.c, parser.y: add and handle a new
-fdefault-file-colseq flag to specify the default collating
sequence to use for files without a collating sequence clause

2023-10-17 David Declerck <[email protected]>

BUG #923: generated modules init/clear unused decimal constants
Expand Down
42 changes: 25 additions & 17 deletions cobc/cobc.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,23 @@ enum compile_level {
CB_LEVEL_EXECUTABLE = 7
};

#define CB_FLAG_GETOPT_STACK_SIZE 1
#define CB_FLAG_GETOPT_IF_CUTOFF 2
#define CB_FLAG_GETOPT_SIGN 3
#define CB_FLAG_GETOPT_FOLD_COPY 4
#define CB_FLAG_GETOPT_FOLD_CALL 5
#define CB_FLAG_GETOPT_TTITLE 6
#define CB_FLAG_GETOPT_MAX_ERRORS 7
#define CB_FLAG_GETOPT_DUMP 8
#define CB_FLAG_GETOPT_CALLFH 9
#define CB_FLAG_GETOPT_INTRINSICS 10
#define CB_FLAG_GETOPT_EC 11
#define CB_FLAG_GETOPT_NO_EC 12
#define CB_FLAG_GETOPT_NO_DUMP 13
#define CB_FLAG_GETOPT_EBCDIC_TABLE 14
#define CB_FLAG_GETOPT_DEFAULT_COLSEQ 15
#define CB_FLAG_MEMORY_CHECK 16
#define CB_FLAG_GETOPT_STACK_SIZE 1
#define CB_FLAG_GETOPT_IF_CUTOFF 2
#define CB_FLAG_GETOPT_SIGN 3
#define CB_FLAG_GETOPT_FOLD_COPY 4
#define CB_FLAG_GETOPT_FOLD_CALL 5
#define CB_FLAG_GETOPT_TTITLE 6
#define CB_FLAG_GETOPT_MAX_ERRORS 7
#define CB_FLAG_GETOPT_DUMP 8
#define CB_FLAG_GETOPT_CALLFH 9
#define CB_FLAG_GETOPT_INTRINSICS 10
#define CB_FLAG_GETOPT_EC 11
#define CB_FLAG_GETOPT_NO_EC 12
#define CB_FLAG_GETOPT_NO_DUMP 13
#define CB_FLAG_GETOPT_EBCDIC_TABLE 14
#define CB_FLAG_GETOPT_DEFAULT_COLSEQ 15
#define CB_FLAG_GETOPT_DEFAULT_FILE_COLSEQ 16
#define CB_FLAG_MEMORY_CHECK 17


/* Info display limits */
Expand Down Expand Up @@ -3809,6 +3810,13 @@ process_command_line (const int argc, char **argv)
}
break;

case CB_FLAG_GETOPT_DEFAULT_FILE_COLSEQ: /* 16 */
/* -fdefault-file-colseq=<ASCII/EBCDIC/NATIVE> */
if (cb_deciph_default_file_colseq_name (cob_optarg)) {
cobc_err_exit (COBC_INV_PAR, "-fdefault-file-colseq");
}
break;

case CB_FLAG_GETOPT_FOLD_COPY: /* 4 */
/* -ffold-copy=<UPPER/LOWER> : COPY fold case */
if (!cb_strcasecmp (cob_optarg, "UPPER")) {
Expand Down Expand Up @@ -3888,7 +3896,7 @@ process_command_line (const int argc, char **argv)
}
break;

case CB_FLAG_MEMORY_CHECK: /* 16 */
case CB_FLAG_MEMORY_CHECK: /* 17 */
/* -fmemory-check=<scope> : */
if (!cob_optarg) {
cb_flag_memory_check = CB_MEMCHK_ALL;
Expand Down
15 changes: 14 additions & 1 deletion cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -9434,6 +9434,19 @@ output_file_initialization (struct cb_file *f)
output_line ("lingptr->lin_bot = 0;");
}

if (f->organization == COB_ORG_INDEXED) {
cb_tree col = f->collating_sequence;
output_prefix ();
output ("%s%s->sort_collating = ", CB_PREFIX_FILE, f->cname);
if ((col != NULL) && CB_REFERENCE_P (col)) {
output_param (cb_ref(col), -1);
output (";");
} else {
output ("NULL;");
}
output_newline ();
}

if (f->organization != COB_ORG_SORT
&& f->code_set) {
/* pass CODE-SET as collation */
Expand All @@ -9457,7 +9470,7 @@ output_file_initialization (struct cb_file *f)
break;
}

output_line ("%s%s->sort_collating = %s;", CB_PREFIX_FILE, f->cname, alph_write);
output_line ("%s%s->code_set_write = %s;", CB_PREFIX_FILE, f->cname, alph_write);
output_line ("%s%s->code_set_read = %s;", CB_PREFIX_FILE, f->cname, alph_read);
if (f->code_set_items) {
const unsigned int items = cb_list_length (CB_TREE (f->code_set_items));
Expand Down
4 changes: 4 additions & 0 deletions cobc/flag.def
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ CB_FLAG_NQ (1, "default-colseq", CB_FLAG_GETOPT_DEFAULT_COLSEQ,
_(" -fdefault-colseq=[ASCII|EBCDIC|NATIVE]\tdefine default collating sequence\n"
" * default: NATIVE"))

CB_FLAG_NQ (1, "default-file-colseq", CB_FLAG_GETOPT_DEFAULT_FILE_COLSEQ,
_(" -fdefault-file-colseq=[ASCII|EBCDIC|NATIVE]\tdefine default file collating sequence\n"
" * default: NATIVE"))

/* Binary flags */

/* Flags with suppressed help */
Expand Down
39 changes: 31 additions & 8 deletions cobc/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -342,23 +342,35 @@ enum cb_colseq {
CB_COLSEQ_ASCII,
CB_COLSEQ_EBCDIC,
};

enum cb_colseq cb_default_colseq = CB_COLSEQ_NATIVE;
enum cb_colseq cb_default_file_colseq = CB_COLSEQ_NATIVE;

/* Decipher character conversion table names */
int cb_deciph_default_colseq_name (const char * const name)
int cb_deciph_colseq_name (const char * const name, enum cb_colseq *colseq)
{
if (!cb_strcasecmp (name, "ASCII")) {
cb_default_colseq = CB_COLSEQ_ASCII;
*colseq = CB_COLSEQ_ASCII;
} else if (!cb_strcasecmp (name, "EBCDIC")) {
cb_default_colseq = CB_COLSEQ_EBCDIC;
*colseq = CB_COLSEQ_EBCDIC;
} else if (!cb_strcasecmp (name, "NATIVE")) {
cb_default_colseq = CB_COLSEQ_NATIVE;
*colseq = CB_COLSEQ_NATIVE;
} else {
return 1;
}
return 0;
}

int cb_deciph_default_colseq_name (const char * const name)
{
return cb_deciph_colseq_name (name, &cb_default_colseq);
}

int cb_deciph_default_file_colseq_name (const char * const name)
{
return cb_deciph_colseq_name (name, &cb_default_file_colseq);
}

static cb_tree
build_colseq_tree (const char *alphabet_name,
int alphabet_type,
Expand Down Expand Up @@ -901,23 +913,34 @@ check_relaxed_syntax (const cob_flags_t lev)
}

static void
setup_default_collation (struct cb_program *program) {
switch (cb_default_colseq) {
prepare_default_collation (enum cb_colseq colseq) {
switch (colseq) {
#ifdef COB_EBCDIC_MACHINE
case CB_COLSEQ_ASCII:
#else
case CB_COLSEQ_EBCDIC:
#endif
alphanumeric_collation = build_colseq (cb_default_colseq);
alphanumeric_collation = build_colseq (colseq);
break;
default:
alphanumeric_collation = NULL;
}
national_collation = NULL; /* TODO: default national collation */
}

static void
setup_default_collation (struct cb_program *program) {
prepare_default_collation (cb_default_colseq);
program->collating_sequence = alphanumeric_collation;
program->collating_sequence_n = national_collation;
}

static void
setup_default_file_collation (struct cb_file *file) {
prepare_default_collation (cb_default_file_colseq);
file->collating_sequence = alphanumeric_collation;
}

static void
program_init_without_program_id (void)
{
Expand Down Expand Up @@ -5365,6 +5388,7 @@ file_control_entry:

}
key_type = NO_KEY;
setup_default_file_collation (current_file);
}
_select_clauses_or_error
{
Expand Down Expand Up @@ -5752,7 +5776,6 @@ collating_sequence_clause:
check_repeated ("COLLATING", SYN_CLAUSE_3, &check_duplicate);
current_file->collating_sequence = alphanumeric_collation;
current_file->collating_sequence_n = national_collation;
CB_PENDING ("FILE COLLATING SEQUENCE");
}
;

Expand Down
1 change: 1 addition & 0 deletions cobc/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -2343,6 +2343,7 @@ extern cb_tree cb_debug_sub_3;
extern cb_tree cb_debug_contents;

extern int cb_deciph_default_colseq_name (const char *const);
extern int cb_deciph_default_file_colseq_name (const char *const);

extern struct cb_program *cb_build_program (struct cb_program *,
const int);
Expand Down
10 changes: 10 additions & 0 deletions libcob/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@

2024-01-25 David Declerck <[email protected]>

FR #459: support COLLATING SEQUENCE clause on SELECT / INDEXED files
* fileio.c (bdb_setkeycol, bdb_bt_compare, indexed_open, ...):
take the file collating sequence into account when comparing keys
* common.h, common.c, coblocal.h: make common_cmps available locally
* common.h, common.c, fileio.c: split the sort_collating field to
distinguish actual collating sequence and code-set for writing
(new field for the latter: code_set_write, to match code_set_read)

2023-12-14 David Declerck <[email protected]>

* common.c (cob_terminate_routines, cob_call_with_exception_check):
Expand Down
3 changes: 3 additions & 0 deletions libcob/coblocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ cob_max_int (const int x, const int y)
return y;
}

COB_HIDDEN int common_cmps (const unsigned char *, const unsigned char *,
const size_t, const unsigned char *);

#undef COB_HIDDEN

#endif /* COB_LOCAL_H */
2 changes: 1 addition & 1 deletion libcob/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1822,7 +1822,7 @@ common_cmpc (const unsigned char *p, const unsigned int c,

/* compare up to 'size' characters in 's1' to 's2'
using collation 'col' */
static int
int
common_cmps (const unsigned char *s1, const unsigned char *s2,
const size_t size, const unsigned char *col)
{
Expand Down
3 changes: 2 additions & 1 deletion libcob/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1395,7 +1395,7 @@ typedef struct __cob_file {
cob_file_key *keys; /* ISAM/RANDOM/SORT keys */
void *file; /* File specific pointer */
void *linorkeyptr; /* LINAGE or SPLIT KEY */
const unsigned char *sort_collating; /* SORT collating / CODE-SET (used for RE-/WRITE) */
const unsigned char *sort_collating; /* SORT collating */
void *extfh_ptr; /* For EXTFH usage */
size_t record_min; /* Record min size */
size_t record_max; /* Record max size */
Expand Down Expand Up @@ -1432,6 +1432,7 @@ typedef struct __cob_file {
char *nxt_filename; /* Next position in org_filename */
unsigned int flag_is_concat:1; /* SEQUENTIAL concatenated file names */

const unsigned char* code_set_write; /* CODE-SET conversion for RE-/WRITE) */
const unsigned char* code_set_read; /* CODE-SET conversion for READs */
size_t nconvert_fields; /* Number of logical fields to convert */
cob_field *convert_field; /* logical fields to convert for CODE-SET */
Expand Down
Loading

0 comments on commit f840670

Please sign in to comment.