From 24ff1a9c93355660fecce5a44400459a51e24b62 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Fri, 12 Jul 2024 09:01:08 +0000 Subject: [PATCH 01/51] Allow keys of different length in the BDB backend (optional, flag-controlled) libcob: 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) Co-authored-by: Boris Eng --- libcob/ChangeLog | 6 ++++++ libcob/coblocal.h | 3 +++ libcob/common.c | 30 +++++++++++++++++++++--------- libcob/fileio.c | 12 +++++++++++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 7fdcb3a72..7235df1ba 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -20,6 +20,12 @@ (indirect_move): fixed bug when calculating scale of the intermediate cob field +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-07-02 Chuck Haatvedt 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..a58bd6d18 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) +{ + return cob_cmp_strings ( + (unsigned char *)COB_FIELD_DATA (f1), + (unsigned char *)COB_FIELD_DATA (f2), + COB_FIELD_SIZE (f1), + COB_FIELD_SIZE (f2), + COB_MODULE_PTR->collating_sequence + ); +} + /* 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 870a4de42..e3d8a51b0 100644 --- a/libcob/fileio.c +++ b/libcob/fileio.c @@ -921,19 +921,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 */ @@ -4672,9 +4677,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; From 7a173e6da655bee696bd22315b0ae51f6898dc9b Mon Sep 17 00:00:00 2001 From: chaat Date: Sat, 13 Jul 2024 17:04:27 +0000 Subject: [PATCH 02/51] adjustment for Sanitizer warning libcob/move.c (indirect_move) fixed Sanitizer warning by moving 1 line of code --- libcob/ChangeLog | 6 ++++++ libcob/move.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 7235df1ba..3cfbbf099 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,10 @@ +2024-07-13 Chuck Haatvedt + + * move.c (indirect_move) fixed sanitizer warnings by moving + one line of code + + 2024-07-11 Chuck Haatvedt * screenio.c (cob_sys_scr_dump, cob_sys_scr_restore) fixed C90 warnings diff --git a/libcob/move.c b/libcob/move.c index 36e820f84..095a5ea13 100644 --- a/libcob/move.c +++ b/libcob/move.c @@ -1458,9 +1458,9 @@ indirect_move (void (*func) (cob_field *src, cob_field *dst), cob_field_attr attr; size_t temp_size; unsigned short digits; - unsigned char buff[COB_MAX_DIGITS + 1] = { 0 }; if (COB_FIELD_TYPE(dst) == COB_TYPE_NUMERIC_EDITED) { + unsigned char buff[COB_MAX_DIGITS + 1] = { 0 }; temp_size = COB_FIELD_DIGITS(dst) + 1; digits = (unsigned short)temp_size - 1; if (COB_FIELD_HAVE_SIGN(dst)) { From 9f1a64c32e11b60b6c157c2552905723882f1b76 Mon Sep 17 00:00:00 2001 From: engboris Date: Tue, 23 Jul 2024 17:11:59 +0000 Subject: [PATCH 03/51] [feature-requests:#448] using state structures instead of state vars for strings libcob * coblocal.h (COB_TLS): add a new attribute for thread local static * common.h, common.c (cob_cleanup_thread): add a cleanup function for threads * strings.c: moved static variables to structures tests: * testsuite.at, testsuite.src/backcomp.at, Makefile.am: added a new test suite to test the backward compatibility of strings functions (INSPECT, STRING, UNSTRING) --- cobc/codegen.c | 3 + libcob/ChangeLog | 9 + libcob/coblocal.h | 15 +- libcob/common.c | 5 + libcob/common.h | 2 + libcob/strings.c | 773 +++--- tests/ChangeLog | 5 + tests/Makefile.am | 3 +- tests/testsuite.at | 6 +- tests/testsuite.src/backcomp.at | 3873 +++++++++++++++++++++++++++++++ 10 files changed, 4384 insertions(+), 310 deletions(-) create mode 100644 tests/testsuite.src/backcomp.at diff --git a/cobc/codegen.c b/cobc/codegen.c index a9ba045b0..011f6be40 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -1287,6 +1287,9 @@ output_data (cb_tree x) output (")->data"); } break; + case CB_TAG_DIRECT: + output ("%s", CB_DIRECT (x)->line); + break; /* LCOV_EXCL_START */ default: CB_TREE_TAG_UNEXPECTED_ABORT (x); diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 3cfbbf099..98d51264e 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -90,6 +90,11 @@ * termio.c (pretty_display_numeric), mlio.c (get_num): changed to use the attributes of the receiving field +2024-07-19 Simon Sobisch + + * coblocal.h (COB_TLS): add a new attribute for thread local static. + * common.h, common.c (cob_cleanup_thread): add a cleanup function for threads + 2024-05-15 Simon Sobisch * profiling.c: fix compile warnings @@ -129,6 +134,10 @@ * common.c: add missing include libxml/parser.h +2024-02-26 Boris Eng + FR #488: using state structures instead of state vars for strings + * strings.c: moved static variables to structures + 2024-01-25 David Declerck FR #459: support COLLATING SEQUENCE clause on SELECT / INDEXED files diff --git a/libcob/coblocal.h b/libcob/coblocal.h index ebbcd023b..8471722dd 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -258,6 +258,20 @@ Note: also defined together with __clang__ in both frontends: #define COB_MOUSE_INTERVAL cobsetptr->cob_mouse_interval #define COB_USE_ESC cobsetptr->cob_use_esc +#if defined(COB_TLS) + /* already defined, for example as static to explicit disable TLS */ +#elif defined(_WIN32) + #define COB_TLS __declspec(thread) +#elif defined(__GNUC__) && (__GNUC__ >= 4) || defined(__clang__) || \ + defined(__hpux) || defined(_AIX) || defined(__sun) + #define COB_TLS static __thread +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #include + #define COB_TLS thread_local +#else + #define COB_TLS static /* fallback definition */ +#endif + /* Global settings structure */ typedef struct __cob_settings { @@ -324,7 +338,6 @@ typedef struct __cob_settings { unsigned int cob_exit_wait; /* wait on program exit if no ACCEPT came after last DISPLAY */ const char *cob_exit_msg; /* message for cob_exit_wait */ - /* reportio.c */ unsigned int cob_col_just_lrc; /* Justify data in column LEFT/RIGHT/CENTER */ diff --git a/libcob/common.c b/libcob/common.c index a58bd6d18..4b428ecee 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -11218,3 +11218,8 @@ init_statement_list (void) #undef COB_STATEMENT } #endif + +void cob_cleanup_thread () +{ + cob_exit_strings (); +} diff --git a/libcob/common.h b/libcob/common.h index b24458ac8..cbdbadff6 100644 --- a/libcob/common.h +++ b/libcob/common.h @@ -1682,6 +1682,8 @@ COB_EXPIMP void cob_runtime_hint (const char *, ...) COB_A_FORMAT12; COB_EXPIMP void cob_runtime_error (const char *, ...) COB_A_FORMAT12; COB_EXPIMP void cob_runtime_warning (const char *, ...) COB_A_FORMAT12; +COB_EXPIMP void cob_cleanup_thread (); + /* General functions */ COB_EXPIMP int cob_is_initialized (void); diff --git a/libcob/strings.c b/libcob/strings.c index 0db2c8f23..f107cfdb0 100644 --- a/libcob/strings.c +++ b/libcob/strings.c @@ -1,6 +1,7 @@ /* Copyright (C) 2002-2014, 2016-2020, 2022-2024 Free Software Foundation, Inc. - Written by Keisuke Nishida, Roger While, Edward Hart, Simon Sobisch + Written by Keisuke Nishida, Roger While, Edward Hart, Simon Sobisch, Boris + Eng This file is part of GnuCOBOL. @@ -33,10 +34,11 @@ #include "coblocal.h" enum inspect_type { - INSPECT_ALL = 0, - INSPECT_LEADING = 1, - INSPECT_FIRST = 2, - INSPECT_TRAILING = 3 + INSPECT_UNSET = 0, + INSPECT_ALL, + INSPECT_LEADING, + INSPECT_FIRST, + INSPECT_TRAILING }; #define DLM_DEFAULT_NUM 8U @@ -45,6 +47,45 @@ struct dlm_struct { cob_u32_t uns_all; }; +struct cob_inspect_state { + cob_field *var; + unsigned char *data; + unsigned char *start; + unsigned char *end; + unsigned char *mark; /* buffer to marker only: 0/1 */ + size_t mark_size; /* size of internal marker elements, increased up to + the maximum needed (biggest target field size) */ + size_t mark_min; /* min. position of the marker set by the last initialize */ + size_t mark_max; /* max. position of the marker set by the last initialize */ + unsigned char *repdata; /* contains data for REPLACING which is applied at end */ + size_t repdata_size; /* size of internal repdata buffer, increased up to + the maximum needed (biggest target field size) */ + size_t size; + cob_u32_t replacing; /* marker about current operation being INSPECT REPLACING */ + int sign; + enum inspect_type type; +}; + +struct cob_string_state { + cob_field *dst; + cob_field *ptr; + cob_field *dlm; + int offset; /* value associated with WITH POINTER clauses */ +}; + +struct cob_unstring_state { + struct dlm_struct *dlm_list; + cob_field *src; + cob_field *ptr; + size_t dlm_list_size; /* size of internal delimiter elements, increased up to + the maximum needed (amount of DELIMITED BY), + actual size of dlm_list is calculated by + dlm_list_size * sizeof(dlm_struct) */ + int offset; + unsigned int count; + unsigned int ndlms; +}; + /* Local variables */ static cob_global *cobglobptr = NULL; @@ -54,43 +95,10 @@ static const cob_field_attr const_alpha_attr = static const cob_field_attr const_strall_attr = {COB_TYPE_ALPHANUMERIC_ALL, 0, 0, 0, NULL}; -static cob_field *inspect_var; -static unsigned char *inspect_data; -static unsigned char *inspect_start; -static unsigned char *inspect_end; -static unsigned char *inspect_mark; /* buffer to marker only: 0/1 */ -static size_t inspect_mark_size; /* size of internal marker elements, increased up to - the maximum needed (biggest target field size) */ -static size_t inspect_mark_min; /* min. position of the marker set by the last initialize */ -static size_t inspect_mark_max; /* max. position of the marker set by the last initialize */ -static unsigned char *inspect_repdata; /* contains data for REPLACING which is applied at end */ -static size_t inspect_repdata_size; /* size of internal repdata buffer, increased up to - the maximum needed (biggest target field size) */ -static size_t inspect_size; -static cob_u32_t inspect_replacing; /* marker about current operation being INSPECT REPLACING */ -static int inspect_sign; -static cob_field inspect_var_copy; - -static cob_field *string_dst; -static cob_field *string_ptr; -static cob_field *string_dlm; -static cob_field string_dst_copy; -static cob_field string_ptr_copy; -static cob_field string_dlm_copy; -static int string_offset; - -static struct dlm_struct *dlm_list; -static cob_field *unstring_src; -static cob_field *unstring_ptr; -static size_t dlm_list_size; /* size of internal delimiter elements, increased up to - the maximum needed (amount of DELIMITED BY), - actual size of dlm_list is calculated by - dlm_list_size * sizeof(dlm_struct) */ -static cob_field unstring_src_copy; -static cob_field unstring_ptr_copy; -static int unstring_offset; -static int unstring_count; -static int unstring_ndlms; +/* Static structures for backward compatibility */ +COB_TLS struct cob_inspect_state share_inspect_state; +COB_TLS struct cob_string_state share_string_state; +COB_TLS struct cob_unstring_state share_unstring_state; static unsigned char *figurative_ptr; static size_t figurative_size; @@ -169,40 +177,40 @@ alloc_figurative (const cob_field *f1, const cob_field *f2) changed to correctly handle multiple replacements with BEFORE/AFTER clauses */ static COB_INLINE COB_A_INLINE void -setup_repdata (void) +setup_repdata (struct cob_inspect_state *st) { /* implementation note: - A version that memcpy'd the complete inspect_data to inspect_repdata + A version that memcpy'd the complete data to repdata on first use, then memcpy back in cob_inspect_finish was tested but dropped. While it has the benefit that memory breakpoints in the COBOL data are only triggered once and always shows the result-to-be and uses an optimized memcpy instead of a manual loop it involves much more memory operations than commonly necessary - because normally only a small percentage of the data is actually replaced. - A version that used inspect_repdata for CONVERTING was also dropped as + A version that used repdata for CONVERTING was also dropped as we don't need the additional memory there. */ - if (inspect_size > inspect_repdata_size) { - if (inspect_repdata) { - cob_free (inspect_repdata); - inspect_repdata_size = inspect_size; - } else if (inspect_size < COB_NORMAL_BUFF) { - inspect_repdata_size = COB_NORMAL_BUFF; + if (st->size > st->repdata_size) { + if (st->repdata) { + cob_free (st->repdata); + st->repdata_size = st->size; + } else if (st->size < COB_NORMAL_BUFF) { + st->repdata_size = COB_NORMAL_BUFF; } else { - inspect_repdata_size = inspect_size; + st->repdata_size = st->size; } /* data content does not matter as we only used marked positions at end */ - inspect_repdata = cob_fast_malloc (inspect_repdata_size + 1); + st->repdata = cob_fast_malloc (st->repdata_size + 1); } } static COB_INLINE COB_A_INLINE unsigned char * -inspect_find_data (const cob_field *str) +inspect_find_data (struct cob_inspect_state *st, const cob_field *str) { const unsigned char *data = str->data; const size_t len = str->size; - register unsigned char *p = inspect_start; - unsigned char *const end_p = inspect_end - len + 1; + register unsigned char *p = st->start; + unsigned char *const end_p = st->end - len + 1; if (p > end_p) { return NULL; @@ -218,32 +226,36 @@ inspect_find_data (const cob_field *str) } static COB_INLINE COB_A_INLINE void -set_inspect_mark (const size_t pos, const size_t length) +set_inspect_mark ( + struct cob_inspect_state *st, + const size_t pos, + const size_t length +) { const size_t pos_end = pos + length - 1; - memset (inspect_mark + pos, 1, length); - if ((inspect_mark_min == 0 && inspect_mark[inspect_mark_min] == 0) - || pos < inspect_mark_min) { - inspect_mark_min = pos; + memset (st->mark + pos, 1, length); + if ((st->mark_min == 0 && st->mark[st->mark_min] == 0) + || pos < st->mark_min) { + st->mark_min = pos; } - if (pos_end > inspect_mark_max) { - inspect_mark_max = pos_end; + if (pos_end > st->mark_max) { + st->mark_max = pos_end; } } /* check for an area in the marker to be non-zero */ static COB_INLINE COB_A_INLINE int -is_marked (size_t pos, size_t length) +is_marked (struct cob_inspect_state *st, size_t pos, size_t length) { /* no need to check further if there's no mark or no possible overlap ... */ - if (inspect_mark[inspect_mark_min] == 0 - || inspect_mark_max < pos - || inspect_mark_min >= pos + length) { + if (st->mark[st->mark_min] == 0 + || st->mark_max < pos + || st->mark_min >= pos + length) { return 0; } /* ... or if the minimal/max mark are within the range to check */ - if (inspect_mark_min >= pos - || inspect_mark_max < pos + length) { + if (st->mark_min >= pos + || st->mark_max < pos + length) { return 1; } @@ -252,7 +264,7 @@ is_marked (size_t pos, size_t length) register size_t i; for (i = 0; i < length; ++i) { - if (inspect_mark[pos + i] != 0) { + if (st->mark[pos + i] != 0) { return 1; } } @@ -261,20 +273,25 @@ is_marked (size_t pos, size_t length) } static void -inspect_common_no_replace (cob_field *f1, cob_field *f2, - const enum inspect_type type, const size_t pos, const size_t inspect_len) +inspect_common_no_replace ( + struct cob_inspect_state *st, + cob_field *f1, + cob_field *f2, + const size_t pos, + const size_t len +) { register size_t i; int n = 0; - if (type == INSPECT_TRAILING) { - const size_t i_max = inspect_len - f2->size; /* no + 1 here */ + if (st->type == INSPECT_TRAILING) { + const size_t i_max = len - f2->size; /* no + 1 here */ size_t first_marker = 0; for (i = i_max; ; --i) { /* Find matching substring */ - if (memcmp (i + inspect_start, f2->data, f2->size) == 0) { + if (memcmp (i + st->start, f2->data, f2->size) == 0) { /* when not marked yet: count, mark and skip handled positions */ - if (!is_marked (pos + i, f2->size)) { + if (!is_marked (st, pos + i, f2->size)) { n++; first_marker = i; i -= f2->size - 1; @@ -288,16 +305,16 @@ inspect_common_no_replace (cob_field *f1, cob_field *f2, } /* set the marker so we won't iterate over this area again */ if (n) { - set_inspect_mark (pos + first_marker, inspect_len - first_marker); + set_inspect_mark (st, pos + first_marker, len - first_marker); } - } else if (type == INSPECT_LEADING) { - const size_t i_max = inspect_len - f2->size + 1; + } else if (st->type == INSPECT_LEADING) { + const size_t i_max = len - f2->size + 1; size_t last_marker = 0; for (i = 0; i < i_max; ++i) { /* Find matching substring */ - if (memcmp (i + inspect_start, f2->data, f2->size) == 0) { + if (memcmp (i + st->start, f2->data, f2->size) == 0) { /* when not marked yet: count, skip handled positions and set mark pos */ - if (!is_marked (pos + i, f2->size)) { + if (!is_marked (st, pos + i, f2->size)) { n++; i += f2->size - 1; last_marker = i; @@ -308,22 +325,22 @@ inspect_common_no_replace (cob_field *f1, cob_field *f2, } /* set the marker so we won't iterate over this area again */ if (n) { - set_inspect_mark (pos, last_marker); + set_inspect_mark (st, pos, last_marker); } /* note: same code as for LEADING, moved out as we don't need to check LEADING for _every_ byte in that tight loop */ } else { - const size_t i_max = inspect_len - f2->size + 1; + const size_t i_max = len - f2->size + 1; for (i = 0; i < i_max; ++i) { /* Find matching substring */ - if (memcmp (i + inspect_start, f2->data, f2->size) == 0) { + if (memcmp (i + st->start, f2->data, f2->size) == 0) { const size_t checked_pos = pos + i; /* when not marked yet: count, mark and skip handled positions */ - if (!is_marked (checked_pos, f2->size)) { + if (!is_marked (st, checked_pos, f2->size)) { n++; /* set the marker so we won't iterate over this area again */ - set_inspect_mark (checked_pos, f2->size); - if (type == INSPECT_FIRST) { + set_inspect_mark (st, checked_pos, f2->size); + if (st->type == INSPECT_FIRST) { break; } i += f2->size - 1; @@ -338,37 +355,47 @@ inspect_common_no_replace (cob_field *f1, cob_field *f2, } static COB_INLINE COB_A_INLINE int -do_mark (const size_t pos, const size_t length, unsigned char *replace_data) +do_mark ( + struct cob_inspect_state *st, + const size_t pos, + const size_t length, + unsigned char *replace_data +) { - if (is_marked (pos, length)) { + if (is_marked (st, pos, length)) { return 0; /* it is, nothing to do here */ } /* nothing done there yet, so: */ /* 1 - handle possible replacing */ - setup_repdata (); - memcpy (inspect_repdata + pos, replace_data, length); + setup_repdata (st); + memcpy (st->repdata + pos, replace_data, length); /* 2 - set the marker so we won't iterate over this area again */ - set_inspect_mark (pos, length); + set_inspect_mark (st, pos, length); /* 3 - let the caller handle pos adjustment */ return 1; } static void -inspect_common_replacing (cob_field *f1, cob_field *f2, - const enum inspect_type type, const size_t pos, const size_t inspect_len) +inspect_common_replacing ( + struct cob_inspect_state *st, + cob_field *f1, + cob_field *f2, + const size_t pos, + const size_t len +) { register size_t i; - if (type == INSPECT_TRAILING) { - const size_t i_max = inspect_len - f2->size; /* no + 1 here */ + if (st->type == INSPECT_TRAILING) { + const size_t i_max = len - f2->size; /* no + 1 here */ for (i = i_max; ; --i) { /* Find matching substring */ - if (memcmp (i + inspect_start, f2->data, f2->size) == 0) { + if (memcmp (i + st->start, f2->data, f2->size) == 0) { /* when not marked yet: count, mark and skip handled positions */ - if (do_mark (pos + i, f2->size, f1->data)) { + if (do_mark (st, pos + i, f2->size, f1->data)) { i -= f2->size - 1; } if (i == 0) { @@ -378,13 +405,13 @@ inspect_common_replacing (cob_field *f1, cob_field *f2, break; } } - } else if (type == INSPECT_LEADING) { - const size_t i_max = inspect_len - f2->size + 1; + } else if (st->type == INSPECT_LEADING) { + const size_t i_max = len - f2->size + 1; for (i = 0; i < i_max; ++i) { /* Find matching substring */ - if (memcmp (i + inspect_start, f2->data, f2->size) == 0) { + if (memcmp (i + st->start, f2->data, f2->size) == 0) { /* when not marked yet: count, mark and skip handled positions */ - if (do_mark (pos + i, f2->size, f1->data)) { + if (do_mark (st, pos + i, f2->size, f1->data)) { i += f2->size - 1; } } else { @@ -394,13 +421,13 @@ inspect_common_replacing (cob_field *f1, cob_field *f2, /* note: same code as for LEADING, moved out as we don't need to check LEADING for _every_ byte in that tight loop */ } else { - const size_t i_max = inspect_len - f2->size + 1; + const size_t i_max = len - f2->size + 1; for (i = 0; i < i_max; ++i) { /* Find matching substring */ - if (memcmp (i + inspect_start, f2->data, f2->size) == 0) { + if (memcmp (i + st->start, f2->data, f2->size) == 0) { /* when not marked yet: count, mark and skip handled positions */ - if (do_mark (pos + i, f2->size, f1->data)) { - if (type == INSPECT_FIRST) { + if (do_mark (st, pos + i, f2->size, f1->data)) { + if (st->type == INSPECT_FIRST) { break; } i += f2->size - 1; @@ -411,12 +438,16 @@ inspect_common_replacing (cob_field *f1, cob_field *f2, } static void -inspect_common (cob_field *f1, cob_field *f2, const enum inspect_type type) +inspect_common ( + struct cob_inspect_state *st, + cob_field *f1, + cob_field *f2 +) { - const size_t pos = inspect_start - inspect_data; - const size_t inspect_len = inspect_end - inspect_start; + const size_t pos = st->start - st->data; + const size_t len = st->end - st->start; - if (inspect_len == 0) { + if (len == 0) { /* inspecting either a zero-length field or AFTER ... has not found a place to start the conversion */ return; @@ -433,11 +464,11 @@ inspect_common (cob_field *f1, cob_field *f2, const enum inspect_type type) of its code; still moved out as this allows for further optimizations; only optimization left: separate entry function and codegen for single target as this does not need a marker at all */ - if (!inspect_replacing) { - if (f2->size > inspect_len) { + if (!st->replacing) { + if (f2->size > len) { return; } - inspect_common_no_replace (f1, f2, type, pos, inspect_len); + inspect_common_no_replace (st, f1, f2, pos, len); } else { if (f1->size != f2->size) { if (COB_FIELD_TYPE (f1) == COB_TYPE_ALPHANUMERIC_ALL) { @@ -448,10 +479,10 @@ inspect_common (cob_field *f1, cob_field *f2, const enum inspect_type type) return; } } - if (f2->size > inspect_len) { + if (f2->size > len) { return; } - inspect_common_replacing (f1, f2, type, pos, inspect_len); + inspect_common_replacing (st, f1, f2, pos, len); } } @@ -461,122 +492,146 @@ inspect_common (cob_field *f1, cob_field *f2, const enum inspect_type type) /* an INSPECT is split into multiple parts: one-time cob_inspect_init (setting up memory and markers) multiple: - cob_inspect_start (setting inspect_start/end) - cob_inspect_before (optional, adjusting inspect_end) - cob_inspect_after (optional, adjusting inspect_start) + cob_inspect_start (setting start/end) + cob_inspect_before (optional, adjusting end) + cob_inspect_after (optional, adjusting start) one of: cob_inspect_characters/cob_inspect_converting (until 3.2)/cob_inspect_all/ cob_inspect_leading/cob_inspect_trailing/cob_inspect_first one-time cob_inspect_finish (copying the REPLACING characters back) */ static COB_INLINE COB_A_INLINE void -cob_inspect_init_common (cob_field *var) +cob_inspect_init_common_intern (struct cob_inspect_state *st, cob_field *var) { if (COB_FIELD_HAVE_SIGN (var) && !COB_FIELD_SIGN_SEPARATE(var)) { /* it is allowed to TRANSFORM / INSPECT a numeric display signed element; if it isn't stored separately we need to "remove" it here and add it back in inspect_finish; note: we only handle NUMERIC DISPLAY here */ - inspect_var_copy = *var; - inspect_var = &inspect_var_copy; - inspect_sign = cob_real_get_sign (var, 0); + st->var = var; + st->sign = cob_real_get_sign (var, 0); } else { - inspect_var = NULL; + st->var = NULL; } - inspect_size = COB_FIELD_SIZE (var); - inspect_data = COB_FIELD_DATA (var); - inspect_start = NULL; - inspect_end = NULL; + st->size = COB_FIELD_SIZE (var); + st->data = COB_FIELD_DATA (var); + st->start = NULL; + st->end = NULL; + st->mark_size = 0; + st->repdata_size = 0; cobglobptr->cob_exception_code = 0; } -void -cob_inspect_init (cob_field *var, const cob_u32_t replacing) +static void +cob_inspect_init_intern (struct cob_inspect_state *st, cob_field *var, const cob_u32_t replacing) { - cob_inspect_init_common (var); - inspect_replacing = replacing; - - if (inspect_size > inspect_mark_size) { - if (inspect_mark) { - cob_free (inspect_mark); - inspect_mark_size = inspect_size; - } else if (inspect_size < COB_NORMAL_BUFF) { - inspect_mark_size = COB_NORMAL_BUFF; + cob_inspect_init_common_intern (st, var); + st->replacing = replacing; + + if (st->size > st->mark_size) { + if (st->mark) { + cob_free (st->mark); + st->mark_size = st->size; + } else if (st->size < COB_NORMAL_BUFF) { + st->mark_size = COB_NORMAL_BUFF; } else { - inspect_mark_size = inspect_size; + st->mark_size = st->size; } /* initialize to zero */ - inspect_mark = cob_malloc (inspect_mark_size + 1); - } else if (inspect_mark_size != 0 && inspect_mark[inspect_mark_min] != 0) { - const size_t init_len = inspect_mark_max - inspect_mark_min + 1; - memset (inspect_mark + inspect_mark_min, 0, init_len); + st->mark = cob_malloc (st->mark_size + 1); + } else if (st->mark_size != 0 && st->mark[st->mark_min] != 0) { + const size_t init_len = st->mark_max - st->mark_min + 1; + memset (st->mark + st->mark_min, 0, init_len); } - inspect_mark_min = inspect_mark_max = 0; + st->mark_min = st->mark_max = 0; +} +void +cob_inspect_init (cob_field *var, const cob_u32_t replacing) +{ + cob_inspect_init_intern (&share_inspect_state, var, replacing); } /* an INSPECT CONVERTING / TRANSFORM is split into multiple parts: one-time cob_inspect_init_converting --> cob_inspect_init_common (setting up memory) multiple: - cob_inspect_start (setting inspect_start/end) - cob_inspect_before (optional, adjusting inspect_end) - cob_inspect_after (optional, adjusting inspect_start) + cob_inspect_start (setting start/end) + cob_inspect_before (optional, adjusting end) + cob_inspect_after (optional, adjusting start) one-time cob_inspect_converting/cob_inspect_translating (actual converstion) */ +static void +cob_inspect_init_converting_intern (struct cob_inspect_state *st, cob_field *var) +{ + cob_inspect_init_common_intern (st, var); + st->replacing = 0; /* only set for pre 3.2 compat because of cob_inspect_finish */ +} void cob_inspect_init_converting (cob_field *var) { - cob_inspect_init_common (var); - inspect_replacing = 0; /* only set for pre 3.2 compat because of cob_inspect_finish */ + cob_inspect_init_converting_intern (&share_inspect_state, var); } +static void +cob_inspect_start_intern (struct cob_inspect_state *st) +{ + st->start = st->data; + st->end = st->data + st->size; +} void cob_inspect_start (void) { - inspect_start = inspect_data; - inspect_end = inspect_data + inspect_size; + cob_inspect_start_intern (&share_inspect_state); } +static void +cob_inspect_before_intern (struct cob_inspect_state *st, const cob_field *str) +{ + unsigned char *data_pos = inspect_find_data (st, str); + if (data_pos) + st->end = data_pos; +} void cob_inspect_before (const cob_field *str) { - unsigned char *data_pos = inspect_find_data (str); - if (data_pos) { - inspect_end = data_pos; - } + cob_inspect_before_intern (&share_inspect_state, str); } +static void +cob_inspect_after_intern (struct cob_inspect_state *st, const cob_field *str) +{ + unsigned char *data_pos = inspect_find_data (st, str); + if (data_pos) + st->start = data_pos + str->size; + else + st->start = st->end; +} void cob_inspect_after (const cob_field *str) { - unsigned char *data_pos = inspect_find_data (str); - if (data_pos) { - inspect_start = data_pos + str->size; - } else { - inspect_start = inspect_end; - } + cob_inspect_after_intern (&share_inspect_state, str); } -void -cob_inspect_characters (cob_field *f1) +static void +cob_inspect_characters_intern (struct cob_inspect_state *st, cob_field *f1) { - const size_t pos = inspect_start - inspect_data; - const size_t inspect_len = inspect_end - inspect_start; - const unsigned char *mark_pos = inspect_mark + pos; - const unsigned char * const mark_end = mark_pos + inspect_len; + const size_t pos = st->start - st->data; + const size_t len = st->end - st->start; + const unsigned char *mark_pos = st->mark + pos; + const unsigned char * const mark_end = mark_pos + len; - if (inspect_len == 0) { + if (len == 0) { /* inspecting either a zero-length field or AFTER ... has not found a place to start the conversion */ return; } - if (inspect_replacing) { + if (st->replacing) { /* INSPECT REPLACING CHARACTERS BY f1 (= size 1) */ const unsigned char repl_by = *f1->data; unsigned char *repdata; - setup_repdata (); - repdata = inspect_repdata + pos; - if (is_marked (pos, inspect_len)) { + setup_repdata (st); + repdata = st->repdata + pos; + if (is_marked (st, pos, len)) { /* at least a partial marking - so iterate */ while (mark_pos != mark_end) { /* replace all positions in the original data where @@ -588,11 +643,11 @@ cob_inspect_characters (cob_field *f1) } } else { /* that area is "free to go", so memset */ - memset (repdata, repl_by, inspect_len); + memset (repdata, repl_by, len); } } else { /* INSPECT TALLYING f1 CHARACTERS */ - if (is_marked (pos, inspect_len)) { + if (is_marked (st, pos, len)) { /* at least a partial marking - so iterate */ int n = 0; /* Note: field->size and therefore INSPECT target's size are @@ -607,42 +662,75 @@ cob_inspect_characters (cob_field *f1) } } else { /* common case: no markers in the length to check */ - cob_add_int (f1, (int)inspect_len, 0); + cob_add_int (f1, (int)len, 0); } } - set_inspect_mark (pos, inspect_len); + set_inspect_mark (st, pos, len); +} +void +cob_inspect_characters (cob_field *f1) +{ + cob_inspect_characters_intern(&share_inspect_state, f1); } +static void +cob_inspect_all_intern (struct cob_inspect_state *st, cob_field *f1, cob_field *f2) +{ + st->type = INSPECT_ALL; + inspect_common (st, f1, f2); +} void cob_inspect_all (cob_field *f1, cob_field *f2) { - inspect_common (f1, f2, INSPECT_ALL); + cob_inspect_all_intern (&share_inspect_state, f1, f2); } +static void +cob_inspect_leading_intern (struct cob_inspect_state *st, cob_field *f1, cob_field *f2) +{ + st->type = INSPECT_LEADING; + inspect_common (st, f1, f2); +} void cob_inspect_leading (cob_field *f1, cob_field *f2) { - inspect_common (f1, f2, INSPECT_LEADING); + cob_inspect_leading_intern (&share_inspect_state, f1, f2); } +static void +cob_inspect_first_intern (struct cob_inspect_state *st, cob_field *f1, cob_field *f2) +{ + st->type = INSPECT_FIRST; + inspect_common (st, f1, f2); +} void cob_inspect_first (cob_field *f1, cob_field *f2) { - inspect_common (f1, f2, INSPECT_FIRST); + cob_inspect_first_intern (&share_inspect_state, f1, f2); } +static void +cob_inspect_trailing_intern (struct cob_inspect_state *st, cob_field *f1, cob_field *f2) +{ + st->type = INSPECT_TRAILING; + inspect_common (st, f1, f2); +} void cob_inspect_trailing (cob_field *f1, cob_field *f2) { - inspect_common (f1, f2, INSPECT_TRAILING); + cob_inspect_trailing_intern (&share_inspect_state, f1, f2); } -void -cob_inspect_converting (const cob_field *f1, const cob_field *f2) +static void +cob_inspect_converting_intern ( + struct cob_inspect_state *st, + const cob_field *f1, + const cob_field *f2 +) { - const size_t inspect_len = inspect_end - inspect_start; + const size_t len = st->end - st->start; - if (inspect_len == 0) { + if (len == 0) { /* our task is to convert either a zero-length field or AFTER ... has not found a place to start the conversion */ goto end; @@ -667,8 +755,8 @@ cob_inspect_converting (const cob_field *f1, const cob_field *f2) /* test _all_ positions of the inspect target against all entries of CONVERTING position by position */ { - unsigned char * cur_data = inspect_data + (inspect_start - inspect_data); - unsigned char * const cur_data_end = cur_data + inspect_len; + unsigned char * cur_data = st->data + (st->start - st->data); + unsigned char * const cur_data_end = cur_data + len; #if 1 /* table-approach, _much faster_, _should_ be portable */ /* pre-filled conversion table */ @@ -737,28 +825,33 @@ cob_inspect_converting (const cob_field *f1, const cob_field *f2) end: /* note: copied here for 3.2+ as cob_inspect_finish is not generated for TRANSFORM/INSPECT CONVERTING any more */ - if (inspect_var) { + if (st->var) { /* FIXME: needs test cases for all "goto end" cases above, ideally with a SIGN SEPARATE variable */ - cob_real_put_sign (inspect_var, inspect_sign); + cob_real_put_sign (st->var, st->sign); } } +void +cob_inspect_converting (const cob_field *f1, const cob_field *f2) +{ + cob_inspect_converting_intern (&share_inspect_state, f1, f2); +} /* note: currently not used by cobc (disabled unfinished prototype) */ -void -cob_inspect_translating (const unsigned char *conv_table) +static void +cob_inspect_translating_intern (struct cob_inspect_state *st, const unsigned char *conv_table) { - const size_t inspect_len = inspect_end - inspect_start; + const size_t len = st->end - st->start; - if (inspect_len == 0) { + if (len == 0) { /* our task is to convert either a zero-length field or AFTER ... has not found a place to start the conversion --> nothing to do here */ } else { /* directly convert _all_ positions of the inspect target using the pre-generated conversion table */ - unsigned char * cur_data = inspect_data + (inspect_start - inspect_data); - unsigned char * const cur_data_end = cur_data + inspect_len; + unsigned char * cur_data = st->data + (st->start - st->data); + unsigned char * const cur_data_end = cur_data + len; /* iterate over target converting with full table */ while (cur_data < cur_data_end) { @@ -767,40 +860,51 @@ cob_inspect_translating (const unsigned char *conv_table) } } - if (inspect_var) { - cob_real_put_sign (inspect_var, inspect_sign); + if (st->var) { + cob_real_put_sign (st->var, st->sign); } } - void -cob_inspect_finish (void) +cob_inspect_translating (const unsigned char* conv_table) +{ + cob_inspect_translating_intern (&share_inspect_state, conv_table); +} + +static void +cob_inspect_finish_intern (struct cob_inspect_state *st) { /* Note: this is not called any more for TRANSFORM/INSPECT CONVERTING since GnuCOBOL 3.2 codegen (only for "old modules")! */ - if (inspect_replacing - && inspect_repdata_size != 0 /* check for first INSPECT REPLACING having zero length */ - && inspect_mark[inspect_mark_min] != 0) { + if (st->replacing + && st->repdata_size != 0 /* check for first INSPECT REPLACING having zero length */ + && st->mark[st->mark_min] != 0) { /* copy over replace data from first to last changed position */ size_t i; - for (i = inspect_mark_min; i <= inspect_mark_max; ++i) { - if (inspect_mark[i] != 0) { - inspect_data[i] = inspect_repdata[i]; + for (i = st->mark_min; i <= st->mark_max; ++i) { + if (st->mark[i] != 0) { + st->data[i] = st->repdata[i]; } } #if 0 /* drop data copy because of security issues [may only be done upon request]; if not active and that contains sensitive data do an INSPECT against a field of the same size to overwrite the buffer */ - memset (inspect_repdata + inspect_mark_min, 0, - inspect_mark_max - inspect_mark_min + 1); + memset (st->repdata + st->mark_min, 0, + st->mark_max - st->mark_min + 1); #endif } - if (inspect_var) { - cob_real_put_sign (inspect_var, inspect_sign); + if (st->var) { + cob_real_put_sign (st->var, st->sign); } } +void +cob_inspect_finish (void) +{ + cob_inspect_finish_intern (&share_inspect_state); +} + /* STRING */ /* a STRING is split into multiple parts: @@ -811,41 +915,44 @@ cob_inspect_finish (void) cob_string_append (to handle a single source) one-time cob_string_finish (setting the string pointer) */ -void -cob_string_init (cob_field *dst, cob_field *ptr) +static void +cob_string_init_intern (struct cob_string_state *st, cob_field *dst, cob_field *ptr) { - string_dst_copy = *dst; - string_dst = &string_dst_copy; - string_ptr = NULL; - if (ptr) { - string_ptr_copy = *ptr; - string_ptr = &string_ptr_copy; - } - string_offset = 0; + st->dst = dst; + st->ptr = ptr; + st->offset = 0; cobglobptr->cob_exception_code = 0; - if (string_ptr) { - string_offset = cob_get_int (string_ptr) - 1; - if (string_offset < 0 - || string_offset >= (int)string_dst->size) { + if (st->ptr) { + st->offset = cob_get_int (st->ptr) - 1; + if (st->offset < 0 || st->offset >= (int)st->dst->size) { cob_set_exception (COB_EC_OVERFLOW_STRING); } } } - void -cob_string_delimited (cob_field *dlm) +cob_string_init (cob_field *dst, cob_field *ptr) +{ + cob_string_init_intern (&share_string_state, dst, ptr); +} + +static void +cob_string_delimited_intern (struct cob_string_state *st, cob_field *dlm) { if (dlm) { - string_dlm_copy = *dlm; - string_dlm = &string_dlm_copy; + st->dlm = dlm; } else { - string_dlm = NULL; + st->dlm = NULL; } } - void -cob_string_append (cob_field *src) +cob_string_delimited (cob_field *dlm) +{ + cob_string_delimited_intern (&share_string_state, dlm); +} + +static void +cob_string_append_intern (struct cob_string_state *st, cob_field *src) { size_t src_size; int i; @@ -859,34 +966,44 @@ cob_string_append (cob_field *src) if (!src_size) { return; } - if (string_dlm) { - size = (int)(src_size - string_dlm->size + 1); + if (st->dlm) { + size = (int)(src_size - st->dlm->size + 1); for (i = 0; i < size; ++i) { - if (memcmp (src->data + i, string_dlm->data, - string_dlm->size) == 0) { + if (memcmp (src->data + i, st->dlm->data, + st->dlm->size) == 0) { src_size = i; break; } } } - if (src_size <= string_dst->size - string_offset) { - memcpy (string_dst->data + string_offset, src->data, src_size); - string_offset += (int) src_size; + if (src_size <= st->dst->size - st->offset) { + memcpy (st->dst->data + st->offset, src->data, src_size); + st->offset += (int) src_size; } else { - size = (int)(string_dst->size - string_offset); - memcpy (string_dst->data + string_offset, src->data, (size_t)size); - string_offset += size; + size = (int)(st->dst->size - st->offset); + memcpy (st->dst->data + st->offset, src->data, (size_t)size); + st->offset += size; cob_set_exception (COB_EC_OVERFLOW_STRING); } } +void +cob_string_append (cob_field *src) +{ + cob_string_append_intern (&share_string_state, src); +} +static void +cob_string_finish_intern (struct cob_string_state *st) +{ + if (st->ptr) { + cob_set_int (st->ptr, st->offset + 1); + } +} void cob_string_finish (void) { - if (string_ptr) { - cob_set_int (string_ptr, string_offset + 1); - } + cob_string_finish_intern (&share_string_state); } /* UNSTRING */ @@ -901,51 +1018,71 @@ cob_string_finish (void) cob_unstring_tallying setting TALLYING (amount of targets set) one-time cob_unstring_finish (setting the string pointer / overflow exception) */ -void -cob_unstring_init (cob_field *src, cob_field *ptr, const size_t num_dlm) +static void +cob_unstring_init_intern ( + struct cob_unstring_state *st, + cob_field *src, + cob_field *ptr, + const size_t num_dlm +) { - unstring_src_copy = *src; - unstring_src = &unstring_src_copy; - unstring_ptr = NULL; - if (ptr) { - unstring_ptr_copy = *ptr; - unstring_ptr = &unstring_ptr_copy; - } + st->src = src; + st->ptr = ptr; - unstring_offset = 0; - unstring_count = 0; - unstring_ndlms = 0; + st->offset = 0; + st->count = 0; + st->ndlms = 0; + st->dlm_list_size = 0; cobglobptr->cob_exception_code = 0; - if (num_dlm > dlm_list_size) { - if (dlm_list) { - cob_free (dlm_list); - dlm_list_size = num_dlm; + if (num_dlm > st->dlm_list_size) { + if (st->dlm_list) { + cob_free (st->dlm_list); + st->dlm_list_size = num_dlm; } else if (num_dlm < DLM_DEFAULT_NUM) { - dlm_list_size = DLM_DEFAULT_NUM; + st->dlm_list_size = DLM_DEFAULT_NUM; } else { - dlm_list_size = num_dlm; + st->dlm_list_size = num_dlm; } - dlm_list = cob_malloc (dlm_list_size * sizeof(struct dlm_struct)); + st->dlm_list = cob_malloc (st->dlm_list_size * sizeof(struct dlm_struct)); } - if (unstring_ptr) { - unstring_offset = cob_get_int (unstring_ptr) - 1; - if (unstring_offset < 0 || unstring_offset >= (int)unstring_src->size) { + if (st->ptr) { + st->offset = cob_get_int (st->ptr) - 1; + if (st->offset < 0 || st->offset >= (int)st->src->size) { cob_set_exception (COB_EC_OVERFLOW_UNSTRING); } } } +void +cob_unstring_init ( + cob_field *src, + cob_field *ptr, + const size_t num_dlm +) +{ + cob_unstring_init_intern (&share_unstring_state, src, ptr, num_dlm); +} +static void +cob_unstring_delimited_intern (struct cob_unstring_state *st, cob_field *dlm, const cob_u32_t all) +{ + st->dlm_list[st->ndlms].uns_dlm = *dlm; + st->dlm_list[st->ndlms].uns_all = all; + st->ndlms++; +} void cob_unstring_delimited (cob_field *dlm, const cob_u32_t all) { - dlm_list[unstring_ndlms].uns_dlm = *dlm; - dlm_list[unstring_ndlms].uns_all = all; - unstring_ndlms++; + cob_unstring_delimited_intern (&share_unstring_state, dlm, all); } -void -cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) +static void +cob_unstring_into_intern ( + struct cob_unstring_state *st, + cob_field *dst, + cob_field *dlm, + cob_field *cnt +) { unsigned char *dlm_data; unsigned char *start; @@ -960,45 +1097,45 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) return; } - if (unstring_offset >= (int)unstring_src->size) { + if (st->offset >= (int)st->src->size) { /* overflow from the last iteration (multiple INTO targets) */ return; } dlm_data = NULL; - start = unstring_src->data + unstring_offset; + start = st->src->data + st->offset; /* no delimiter - just split into DELIMITED BY SIZE */ - if (unstring_ndlms == 0) { + if (st->ndlms == 0) { /* necessary for correct unstring offset: minimal size */ /* Note: field->size and therefore offset are guaranteed to be < INT_MAX by cobc */ match_size = cob_min_int ((int)COB_FIELD_SIZE (dst), - (int)unstring_src->size - unstring_offset); + (int)st->src->size - st->offset); cob_str_memcpy (dst, start, match_size); - unstring_offset += match_size; + st->offset += match_size; /* DELIMITED BY [ALL] x [.. OR [ALL] z] */ } else { - const int srsize = (int)unstring_src->size; + const int srsize = (int)st->src->size; unsigned char *p; unsigned char *dp; int found = 0; /* note: duplicate code for performance as most cases have either none or a single delimiter */ - if (unstring_ndlms == 1) { - const struct dlm_struct dlms = dlm_list[0]; + if (st->ndlms == 1) { + const struct dlm_struct dlms = st->dlm_list[0]; const int dlsize = (int) dlms.uns_dlm.size; - const unsigned char *s = unstring_src->data + srsize - dlsize + 1; + const unsigned char *s = st->src->data + srsize - dlsize + 1; dp = dlms.uns_dlm.data; for (p = start; p < s; ++p) { if (!memcmp (p, dp, (size_t)dlsize)) { /* delimiter matches */ match_size = (int)(p - start); /* count in */ cob_str_memcpy (dst, start, match_size); /* into */ - unstring_offset += match_size + dlsize; /* with pointer */ + st->offset += match_size + dlsize; /* with pointer */ dlm_data = dp; dlm_size = dlsize; if (dlms.uns_all) { /* delimited by all */ @@ -1006,7 +1143,7 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) if (memcmp (p, dp, (size_t)dlsize)) { break; } - unstring_offset += dlsize; + st->offset += dlsize; } } found = 1; @@ -1014,11 +1151,11 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) } } } else { - const unsigned char *s = unstring_src->data + srsize; + const unsigned char *s = st->src->data + srsize; int i; for (p = start; p < s; ++p) { - for (i = 0; i < unstring_ndlms; ++i) { - const struct dlm_struct dlms = dlm_list[i]; + for (i = 0; i < st->ndlms; ++i) { + const struct dlm_struct dlms = st->dlm_list[i]; const int dlsize = (int)dlms.uns_dlm.size; const unsigned char *s2 = s - dlsize + 1; if (p > s2) { @@ -1028,7 +1165,7 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) if (!memcmp (p, dp, (size_t)dlsize)) { /* delimiter matches */ match_size = (int)(p - start); /* count in */ cob_str_memcpy (dst, start, match_size); /* into */ - unstring_offset += match_size + dlsize; /* with pointer */ + st->offset += match_size + dlsize; /* with pointer */ dlm_data = dp; dlm_size = dlsize; if (dlms.uns_all) { /* delimited by all */ @@ -1036,7 +1173,7 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) if (memcmp (p, dp, (size_t)dlsize)) { break; } - unstring_offset += dlsize; + st->offset += dlsize; } } found = 1; @@ -1051,12 +1188,12 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) /* if none of the delimiters matched, match to end */ if (!found) { - match_size = (int)(unstring_src->size - unstring_offset); + match_size = (int)(st->src->size - st->offset); cob_str_memcpy (dst, start, match_size); - unstring_offset = (int) unstring_src->size; + st->offset = (int) st->src->size; } } - unstring_count++; + st->count++; /* note: per any known dialect both DELIMITER IN and COUNT IN are only allowed if there is a DELIMITED BY phrase; the GnuCOBOL parser @@ -1078,47 +1215,69 @@ cob_unstring_into (cob_field *dst, cob_field *dlm, cob_field *cnt) cob_set_int (cnt, match_size); } } +void +cob_unstring_into ( + cob_field *dst, + cob_field *dlm, + cob_field *cnt +) +{ + cob_unstring_into_intern (&share_unstring_state, dst, dlm, cnt); +} +static void +cob_unstring_tallying_intern (struct cob_unstring_state *st, cob_field *f) +{ + cob_add_int (f, st->count, 0); +} void cob_unstring_tallying (cob_field *f) { - cob_add_int (f, unstring_count, 0); + cob_unstring_tallying_intern (&share_unstring_state, f); } -void -cob_unstring_finish (void) +static void +cob_unstring_finish_intern (struct cob_unstring_state *st) { - if (unstring_offset < (int)unstring_src->size) { + if (st->offset < (int)st->src->size) { /* overflow from any iteration -> overflow exception */ cob_set_exception (COB_EC_OVERFLOW_UNSTRING); } - if (unstring_ptr) { - cob_set_int (unstring_ptr, unstring_offset + 1); + if (st->ptr) { + cob_set_int (st->ptr, st->offset + 1); } } +void +cob_unstring_finish (void) +{ + cob_unstring_finish_intern (&share_unstring_state); +} /* Initialization/Termination */ void -cob_exit_strings (void) +cob_exit_strings () { - if (inspect_mark) { - cob_free (inspect_mark); - inspect_mark = NULL; + struct cob_inspect_state *sti = &share_inspect_state; + struct cob_unstring_state *stu = &share_unstring_state; + + if (sti->mark) { + cob_free (sti->mark); + sti->mark = NULL; } - inspect_mark_size = inspect_mark_min = inspect_mark_max = 0; - if (inspect_repdata) { - cob_free (inspect_repdata); - inspect_repdata = NULL; + sti->mark_size = sti->mark_min = sti->mark_max = 0; + if (sti->repdata) { + cob_free (sti->repdata); + sti->repdata = NULL; } - inspect_repdata_size = 0; + sti->repdata_size = 0; - if (dlm_list) { - cob_free (dlm_list); - dlm_list = NULL; + if (stu->dlm_list) { + cob_free (stu->dlm_list); + stu->dlm_list = NULL; } - dlm_list_size = 0; + stu->dlm_list_size = 0; if (figurative_ptr) { cob_free (figurative_ptr); diff --git a/tests/ChangeLog b/tests/ChangeLog index 767e43a2c..94eb7191a 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -27,6 +27,11 @@ or if --enable-debug was specified during configure * testsuite.src: adjusted several tests to use that option +2024-02-26 Boris Eng + + * testsuite.at: added a new test suite to test the backward compatibility + of strings functions (INSPECT, STRING, UNSTRING) + 2023-02-21 Fabrice Le Fessant * testsuite.src/syn_literals.at: move syntax checks on literals diff --git a/tests/Makefile.am b/tests/Makefile.am index c4acdbff9..002be9b2c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ # # Makefile gnucobol/tests # -# Copyright (C) 2003-2012, 2014-2019, 2022-2023 Free Software Foundation, Inc. +# Copyright (C) 2003-2012, 2014-2019, 2022-2024 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch # # This file is part of GnuCOBOL. @@ -63,6 +63,7 @@ testsuite_sources = \ testsuite.src/data_display.at \ testsuite.src/data_packed.at \ testsuite.src/data_pointer.at \ + testsuite.src/backcomp.at \ testsuite.src/numeric-dump.cob \ testsuite.src/numeric-display.cob diff --git a/tests/testsuite.at b/tests/testsuite.at index 1b1c2baf7..3b8e4c35b 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -1,4 +1,4 @@ -## Copyright (C) 2003-2012, 2014-2023 Free Software Foundation, Inc. +## Copyright (C) 2003-2012, 2014-2024 Free Software Foundation, Inc. ## Written by Keisuke Nishida, Roger While, Simon Sobisch ## ## This file is part of GnuCOBOL. @@ -81,3 +81,7 @@ m4_include([data_binary.at]) # USAGE BINARY m4_include([data_display.at]) # USAGE DISPLAY m4_include([data_packed.at]) # USAGE PACKED-DECIMAL m4_include([data_pointer.at]) # USAGE POINTER + +## Test for backward compatibility +AT_BANNER([Backward compatibility]) +m4_include([backcomp.at]) diff --git a/tests/testsuite.src/backcomp.at b/tests/testsuite.src/backcomp.at new file mode 100644 index 000000000..f20f08ba7 --- /dev/null +++ b/tests/testsuite.src/backcomp.at @@ -0,0 +1,3873 @@ +## Copyright (C) 2024 Free Software Foundation, Inc. +## Written by Boris Eng +## +## This file is part of GnuCOBOL. +## +## The GnuCOBOL compiler is free software: you can redistribute it +## and/or modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation, either version 3 of the +## License, or (at your option) any later version. +## +## GnuCOBOL is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with GnuCOBOL. If not, see . + +### GnuCOBOL Test Suite for backward compatibility +## +## Tests in this file are used to check that the C code coming from COBOL +## programs compiled with previous versions of GnuCOBOL are still executed +## correctly with newer versions of the compiler. +## It is useful when implementing new features in order to prevent the loss of +## compatibility with programs compiled with previous versions. +## +## To add new tests, +## 1. Choose a COBOL program; +## 2. Compile it with GnuCOBOL 2.2 (minimal compatibility ensured) and the +## flags -Cx and -fno-computed-goto (to generated more portable C code). +## Additional flags may be added if needed. +## - If it does not work for compatibility reasons (unsupported feature), +## return to step 2 with the next version of the compiler; +## - If it does not work because of some unrecognized or conflicting code, +## it may be necessary to inline some functions (typically, specialized +## comparison functions such as cob_cmp_s32 which can be replaced by the +## general comparison function cob_cmp_int); +## 3. For more convenience, if the generated program is prog.c, inline the +## headers by replacing #include "prog.c.h" and #include "prog.c.l.h" +## by the content of the files prog.c.h and prog.c.l.h respectively; +## 4. Although not mandatory, it is wiser to polish the code by removing +## useless headers or portions of code. + +AT_SETUP([STRING WITH POINTER ON OVERFLOW with DELIMITER]) +AT_KEYWORDS([backcomp runmisc exceptions]) + +AT_DATA([prog.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at avril 23 2024 11:21:18 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "avril 23 2024 11:21:18" +#define COB_MODULE_DATE 20240423 +#define COB_MODULE_TIME 112118 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at avril 23 2024 11:21:18 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x10, 2, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + +static const cob_field_attr cob_all_attr = {0x22, 0, 0, 0, NULL}; + + +/* Constants */ +static const cob_field c_1 = {1, (cob_u8_ptr)"A", &a_3}; +static const cob_field c_2 = {1, (cob_u8_ptr)"B", &a_3}; +static const cob_field c_3 = {1, (cob_u8_ptr)"C", &a_3}; +static const cob_field c_4 = {27, (cob_u8_ptr)"Case A: Should not overflow", &a_3}; +static const cob_field c_5 = {16, (cob_u8_ptr)"A: TRTG-STRING <", &a_3}; +static const cob_field c_6 = {10, (cob_u8_ptr)"> != ", &a_3}; +static const cob_field c_7 = {16, (cob_u8_ptr)"A: STR-POINTER <", &a_3}; +static const cob_field c_8 = {9, (cob_u8_ptr)"> != <04>", &a_3}; +static const cob_field c_9 = {23, (cob_u8_ptr)"Case B: Should overflow", &a_3}; +static const cob_field c_10 = {16, (cob_u8_ptr)"B: TRTG-STRING <", &a_3}; +static const cob_field c_11 = {11, (cob_u8_ptr)"> != SPACES", &a_3}; +static const cob_field c_12 = {16, (cob_u8_ptr)"B: STR-POINTER <", &a_3}; +static const cob_field c_13 = {9, (cob_u8_ptr)"> != <00>", &a_3}; +static const cob_field c_14 = {23, (cob_u8_ptr)"Case C: Should overflow", &a_3}; +static const cob_field c_15 = {16, (cob_u8_ptr)"C: TRTG-STRING <", &a_3}; +static const cob_field c_16 = {16, (cob_u8_ptr)"C: STR-POINTER <", &a_3}; +static const cob_field c_17 = {3, (cob_u8_ptr)"1|2", &a_3}; +static const cob_field c_18 = {3, (cob_u8_ptr)"A|B", &a_3}; +static const cob_field c_19 = {3, (cob_u8_ptr)"C|D", &a_3}; +static const cob_field c_20 = {16, (cob_u8_ptr)"D: TRGT-STRING <", &a_3}; +static const cob_field c_21 = {10, (cob_u8_ptr)"> != <1AC>", &a_3}; + +static cob_field cob_all_space = {1, (cob_u8_ptr)" ", &cob_all_attr}; + +/* Function prototypes */ + +static int StringTest (); +static int StringTest_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (StringTest ()); +} + +/* Functions */ + +/* PROGRAM-ID 'StringTest' */ + +/* ENTRY 'StringTest' */ + +static int +StringTest () +{ + return StringTest_ (0); +} + +static int +StringTest_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at avril 23 2024 11:21:18 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + /* Program local variables for 'StringTest' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[3] __attribute__((aligned)); /* TRGT-STRING */ + static cob_u8_t b_7[2] __attribute__((aligned)); /* STR-POINTER */ + static cob_u8_t b_8[1] __attribute__((aligned)); /* SRC-DELIM */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_6 = {3, b_6, &a_1}; /* TRGT-STRING */ + static cob_field f_7 = {2, b_7, &a_2}; /* STR-POINTER */ + static cob_field f_8 = {1, b_8, &a_1}; /* SRC-DELIM */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 21 : Entry StringTest : prog.cob */ + l_2:; + + /* Line: 21 : MOVE : prog.cob */ + memcpy (b_7, "01", 2); + + /* Line: 22 : STRING : prog.cob */ + cob_glob_ptr->cob_exception_code = 0; + cob_string_init (&f_6, &f_7); + cob_string_delimited (NULL); + cob_string_append ((cob_field *)&c_1); + cob_string_append ((cob_field *)&c_2); + cob_string_append ((cob_field *)&c_3); + cob_string_finish (); + if (unlikely ((cob_glob_ptr->cob_exception_code & 0xff00) == 0x0a00)) + { + + /* Line: 26 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_4); + } + + /* Line: 28 : IF : prog.cob */ + if (((int)memcmp (b_6, (cob_u8_ptr)"ABC", 3) != 0)) + { + + /* Line: 29 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_5, &f_6, &c_6); + } + + /* Line: 30 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_7, 2, 4LL, 0) != 0)) + { + + /* Line: 31 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_7, &f_7, &c_8); + } + + /* Line: 34 : MOVE : prog.cob */ + memset (b_7, 48, 2); + + /* Line: 35 : MOVE : prog.cob */ + memset (b_6, 32, 3); + + /* Line: 36 : STRING : prog.cob */ + cob_glob_ptr->cob_exception_code = 0; + cob_string_init (&f_6, &f_7); + cob_string_delimited (NULL); + cob_string_append ((cob_field *)&c_1); + cob_string_append ((cob_field *)&c_2); + cob_string_append ((cob_field *)&c_3); + cob_string_finish (); + if (!cob_glob_ptr->cob_exception_code) + { + + /* Line: 40 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_9); + } + + /* Line: 42 : IF : prog.cob */ + if (((int)cob_cmp (&f_6, &cob_all_space) != 0)) + { + + /* Line: 43 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_10, &f_6, &c_11); + } + + /* Line: 44 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_7, 2, 0LL, 0) != 0)) + { + + /* Line: 45 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_12, &f_7, &c_13); + } + + /* Line: 48 : MOVE : prog.cob */ + memcpy (b_7, "04", 2); + + /* Line: 49 : MOVE : prog.cob */ + memset (b_6, 32, 3); + + /* Line: 50 : STRING : prog.cob */ + cob_glob_ptr->cob_exception_code = 0; + cob_string_init (&f_6, &f_7); + cob_string_delimited (NULL); + cob_string_append ((cob_field *)&c_1); + cob_string_append ((cob_field *)&c_2); + cob_string_append ((cob_field *)&c_3); + cob_string_finish (); + if (!cob_glob_ptr->cob_exception_code) + { + + /* Line: 54 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_14); + } + + /* Line: 56 : IF : prog.cob */ + if (((int)cob_cmp (&f_6, &cob_all_space) != 0)) + { + + /* Line: 57 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_15, &f_6, &c_11); + } + + /* Line: 58 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_7, 2, 4LL, 0) != 0)) + { + + /* Line: 59 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_16, &f_7, &c_8); + } + + /* Line: 62 : MOVE : prog.cob */ + memcpy (b_7, "01", 2); + + /* Line: 63 : MOVE : prog.cob */ + *(b_8) = 124; + + /* Line: 64 : MOVE : prog.cob */ + memset (b_6, 32, 3); + + /* Line: 65 : STRING : prog.cob */ + cob_string_init (&f_6, &f_7); + cob_string_delimited (&f_8); + cob_string_append ((cob_field *)&c_17); + cob_string_append ((cob_field *)&c_18); + cob_string_append ((cob_field *)&c_19); + cob_string_finish (); + + /* Line: 69 : IF : prog.cob */ + if (((int)memcmp (b_6, (cob_u8_ptr)"1AC", 3) != 0)) + { + + /* Line: 70 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_20, &f_6, &c_21); + } + + /* Line: 72 : GOBACK : prog.cob */ + goto exit_program; + + /* Program exit */ + + exit_program: + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "StringTest"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())StringTest; + module->module_cancel.funcptr = (void *(*)())StringTest_; + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memset (b_6, 32, 3); + memset (b_7, 48, 2); + *(cob_u8_ptr)(b_8) = 32; + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'StringTest' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE prog.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP + + +AT_SETUP([UNSTRING DELIMITED POINTER]) +AT_KEYWORDS([backcomp runmisc]) + +AT_DATA([prog.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at avril 23 2024 11:30:26 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "avril 23 2024 11:30:26" +#define COB_MODULE_DATE 20240423 +#define COB_MODULE_TIME 113026 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at avril 23 2024 11:30:26 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x1000, NULL}; +static const cob_field_attr a_2 = {0x10, 2, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x0000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {18, (cob_u8_ptr)"Expected 48 - Got ", &a_1}; +static const cob_field c_2 = {18, (cob_u8_ptr)"Expected 62 - Got ", &a_1}; +static const cob_field c_3 = {18, (cob_u8_ptr)"Expected 63 - Got ", &a_1}; +static const cob_field c_4 = {5, (cob_u8_ptr)" PIC ", &a_1}; +static const cob_field c_5 = {7, (cob_u8_ptr)" COMP-3", &a_1}; +static const cob_field c_6 = {1, (cob_u8_ptr)".", &a_1}; + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at avril 23 2024 11:30:26 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[66] __attribute__((aligned)); /* WS-LAY-RECORD */ + static cob_u8_t b_7[50] __attribute__((aligned)); /* WS-DUMMY */ + static cob_u8_t b_8[32] __attribute__((aligned)); /* WS-KEYWORD */ + static cob_u8_t b_9[2] __attribute__((aligned)); /* WS-POINTER */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_6 = {66, b_6, &a_3}; /* WS-LAY-RECORD */ + static cob_field f_7 = {50, b_7, &a_3}; /* WS-DUMMY */ + static cob_field f_8 = {32, b_8, &a_3}; /* WS-KEYWORD */ + static cob_field f_9 = {2, b_9, &a_2}; /* WS-POINTER */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 11 : Entry prog : prog.cob */ + l_2:; + + /* Line: 11 : MOVE : prog.cob */ + memcpy (b_6, " 10 AF-RECORD-TYPE-SEQUENCE-04 PIC 9(05) COMP-3. ", 66); + + /* Line: 14 : MOVE : prog.cob */ + memcpy (b_9, "01", 2); + + /* Line: 15 : PERFORM : prog.cob */ + /* PERFORM 0001-SUB */ + frame_ptr++; + frame_ptr->perform_through = 5; + frame_ptr->return_address_num = 0; + goto l_5; + l_6: + frame_ptr--; + + /* Line: 16 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_9, 2, 48LL, 0) != 0)) + { + + /* Line: 17 : DISPLAY : prog.cob */ + cob_display (0, 1, 2, &c_1, &f_9); + } + + /* Line: 18 : ADD : prog.cob */ + cob_add_int (&f_9, 7, 0); + + /* Line: 20 : PERFORM : prog.cob */ + /* PERFORM 0001-SUB */ + frame_ptr++; + frame_ptr->perform_through = 5; + frame_ptr->return_address_num = 1; + goto l_5; + l_7: + frame_ptr--; + + /* Line: 21 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_9, 2, 62LL, 0) != 0)) + { + + /* Line: 22 : DISPLAY : prog.cob */ + cob_display (0, 1, 2, &c_2, &f_9); + } + + /* Line: 23 : PERFORM : prog.cob */ + /* PERFORM 0001-SUB */ + frame_ptr++; + frame_ptr->perform_through = 5; + frame_ptr->return_address_num = 2; + goto l_5; + l_8: + frame_ptr--; + + /* Line: 24 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_9, 2, 63LL, 0) != 0)) + { + + /* Line: 25 : DISPLAY : prog.cob */ + cob_display (0, 1, 2, &c_3, &f_9); + } + + /* Line: 26 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Line: 27 : Paragraph 0001-SUB : prog.cob */ + l_5:; + + /* Line: 28 : UNSTRING : prog.cob */ + cob_unstring_init (&f_6, &f_9, 3); + cob_unstring_delimited ((cob_field *)&c_4, 0); + cob_unstring_delimited ((cob_field *)&c_5, 0); + cob_unstring_delimited ((cob_field *)&c_6, 0); + cob_unstring_into (&f_7, &f_8, 0); + cob_unstring_finish (); + + /* Implicit PERFORM return */ + if (frame_ptr->perform_through == 5) + goto P_switch; + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + switch (frame_ptr->return_address_num) { + case 2: + goto l_8; + case 1: + goto l_7; + case 0: + goto l_6; + } + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memset (b_6, 32, 66); + memset (b_7, 32, 50); + memset (b_8, 32, 32); + memset (b_9, 48, 2); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE prog.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP + + +AT_SETUP([UNSTRING with FUNCTION / literal]) +AT_KEYWORDS([backcomp runmisc]) + +AT_DATA([prog.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at avril 23 2024 11:33:04 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "avril 23 2024 11:33:04" +#define COB_MODULE_DATE 20240423 +#define COB_MODULE_TIME 113304 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at avril 23 2024 11:33:04 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x1000, NULL}; +static const cob_field_attr a_2 = {0x21, 0, 0, 0x0000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {19, (cob_u8_ptr)"The,Quick,Brown,Fox", &a_1}; +static const cob_field c_2 = {1, (cob_u8_ptr)",", &a_1}; +static const cob_field c_3 = {10, (cob_u8_ptr)"PRM(1) is ", &a_1}; +static const cob_field c_4 = {1, (cob_u8_ptr)":", &a_1}; +static const cob_field c_5 = {10, (cob_u8_ptr)"PRM(2) is ", &a_1}; +static const cob_field c_6 = {10, (cob_u8_ptr)"PRM(3) is ", &a_1}; +static const cob_field c_7 = {10, (cob_u8_ptr)"PRM(4) is ", &a_1}; +static const cob_field c_8 = {20, (cob_u8_ptr)"Now using UPPER-CASE", &a_1}; +static const cob_field c_9 = {25, (cob_u8_ptr)"Daddy,was,a,Rolling stone", &a_1}; +static const cob_field c_10 = {17, (cob_u8_ptr)"Now using Literal", &a_1}; +static const cob_field c_11 = {30, (cob_u8_ptr)"Now using Literal + LOWER-CASE", &a_1}; + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at avril 23 2024 11:33:04 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Local cob_field items */ + cob_field f0; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[543] __attribute__((aligned)); /* FILLER 1 */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_7 = {479, b_6, &a_2}; /* TSTUNS */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 9 : Entry prog : prog.cob */ + l_2:; + + /* Line: 9 : MOVE : prog.cob */ + cob_move ((cob_field *)&c_1, &f_7); + + /* Line: 10 : UNSTRING : prog.cob */ + cob_unstring_init (&f_7, NULL, 1); + cob_unstring_delimited ((cob_field *)&c_2, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), 0, 0); + cob_unstring_finish (); + + /* Line: 12 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_3, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), &c_4); + + /* Line: 13 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_5, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), &c_4); + + /* Line: 14 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_6, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), &c_4); + + /* Line: 15 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_7, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), &c_4); + + /* Line: 16 : UNSTRING : prog.cob */ + cob_unstring_init (cob_intr_upper_case (0, 0, &f_7), NULL, 1); + cob_unstring_delimited ((cob_field *)&c_2, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), 0, 0); + cob_unstring_finish (); + + /* Line: 18 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_8); + + /* Line: 19 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_3, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), &c_4); + + /* Line: 20 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_5, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), &c_4); + + /* Line: 21 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_6, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), &c_4); + + /* Line: 22 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_7, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), &c_4); + + /* Line: 23 : UNSTRING : prog.cob */ + cob_unstring_init ((cob_field *)&c_9, NULL, 1); + cob_unstring_delimited ((cob_field *)&c_2, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), 0, 0); + cob_unstring_finish (); + + /* Line: 25 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_10); + + /* Line: 26 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_3, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), &c_4); + + /* Line: 27 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_5, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), &c_4); + + /* Line: 28 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_6, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), &c_4); + + /* Line: 29 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_7, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), &c_4); + + /* Line: 30 : UNSTRING : prog.cob */ + cob_unstring_init (cob_intr_lower_case (0, 0, (cob_field *)&c_9), NULL, 1); + cob_unstring_delimited ((cob_field *)&c_2, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), 0, 0); + cob_unstring_into (COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), 0, 0); + cob_unstring_finish (); + + /* Line: 33 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_11); + + /* Line: 34 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_3, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 0, &a_2), &c_4); + + /* Line: 35 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_5, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 1, &a_2), &c_4); + + /* Line: 36 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_6, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 2, &a_2), &c_4); + + /* Line: 37 : DISPLAY : prog.cob */ + cob_display (0, 1, 3, &c_7, COB_SET_FLD(f0, 16, b_6 + 479 + 16 * 3, &a_2), &c_4); + + /* Line: 38 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memset (b_6, 32, 543); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE prog.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], +[PRM(1) is The : +PRM(2) is Quick : +PRM(3) is Brown : +PRM(4) is Fox : +Now using UPPER-CASE +PRM(1) is THE : +PRM(2) is QUICK : +PRM(3) is BROWN : +PRM(4) is FOX : +Now using Literal +PRM(1) is Daddy : +PRM(2) is was : +PRM(3) is a : +PRM(4) is Rolling stone : +Now using Literal + LOWER-CASE +PRM(1) is daddy : +PRM(2) is was : +PRM(3) is a : +PRM(4) is rolling stone : +], []) + +AT_CLEANUP + + +AT_SETUP([SORT: EBCDIC table]) +AT_KEYWORDS([runmisc SORT ALPHABET OBJECT-COMPUTER]) + +AT_DATA([prog.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 16:25:46 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 16:25:46" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 162546 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 16:25:46 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x01, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {10, (cob_u8_ptr)"abcde12345", &a_3}; +static const cob_field c_2 = {10, (cob_u8_ptr)"54321edcba", &a_3}; + + +/* ASCII to EBCDIC table */ +static const unsigned char cob_ascii_ebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x07, + 0x68, 0xDC, 0x51, 0x42, 0x43, 0x44, 0x47, 0x48, + 0x52, 0x53, 0x54, 0x57, 0x56, 0x58, 0x63, 0x67, + 0x71, 0x9C, 0x9E, 0xCB, 0xCC, 0xCD, 0xDB, 0xDD, + 0xDF, 0xEC, 0xFC, 0xB0, 0xB1, 0xB2, 0x3E, 0xB4, + 0x45, 0x55, 0xCE, 0xDE, 0x49, 0x69, 0x9A, 0x9B, + 0xAB, 0x9F, 0xBA, 0xB8, 0xB7, 0xAA, 0x8A, 0x8B, + 0xB6, 0xB5, 0x62, 0x4F, 0x64, 0x65, 0x66, 0x20, + 0x21, 0x22, 0x70, 0x23, 0x72, 0x73, 0x74, 0xBE, + 0x76, 0x77, 0x78, 0x80, 0x24, 0x15, 0x8C, 0x8D, + 0x8E, 0x41, 0x06, 0x17, 0x28, 0x29, 0x9D, 0x2A, + 0x2B, 0x2C, 0x09, 0x0A, 0xAC, 0x4A, 0xAE, 0xAF, + 0x1B, 0x30, 0x31, 0xFA, 0x1A, 0x33, 0x34, 0x35, + 0x36, 0x59, 0x08, 0x38, 0xBC, 0x39, 0xA0, 0xBF, + 0xCA, 0x3A, 0xFE, 0x3B, 0x04, 0xCF, 0xDA, 0x14, + 0xE1, 0x8F, 0x46, 0x75, 0xFD, 0xEB, 0xEE, 0xED, + 0x90, 0xEF, 0xB3, 0xFB, 0xB9, 0xEA, 0xBB, 0xFF +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 16:25:46 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Local cob_field items */ + cob_field f0; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[10] __attribute__((aligned)); /* Z */ + static cob_u8_t b_7[10] __attribute__((aligned)); /* G */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_7 = {10, b_7, &a_2}; /* G */ + static cob_field f_9 = {1, b_7, &a_1}; /* X */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 15 : Entry prog : prog.cob */ + l_2:; + + /* Line: 15 : MOVE : prog.cob */ + memcpy (b_7, b_6, 10); + + /* Line: 17 : SORT : prog.cob */ + cob_table_sort_init (1, cob_ascii_ebcdic); + cob_table_sort_init_key (&f_9, 0, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_7 + 0, &a_2), 10); + + /* Line: 18 : IF : prog.cob */ + if (((int)cob_cmp (&f_7, (cob_field *)&c_1) != 0)) + { + + /* Line: 19 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 20 : MOVE : prog.cob */ + memcpy (b_7, b_6, 10); + + /* Line: 22 : SORT : prog.cob */ + cob_table_sort_init (1, cob_ascii_ebcdic); + cob_table_sort_init_key (&f_9, 1, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_7 + 0, &a_2), 10); + + /* Line: 23 : IF : prog.cob */ + if (((int)cob_cmp (&f_7, (cob_field *)&c_2) != 0)) + { + + /* Line: 24 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 25 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memcpy (b_6, "d4b2e1a3c5", 10); + memset (b_7, 32, 10); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_DATA([prog2.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 13:58:56 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 13:58:56" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 135856 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 13:58:56 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x01, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {10, (cob_u8_ptr)"abcde12345", &a_3}; +static const cob_field c_2 = {10, (cob_u8_ptr)"54321edcba", &a_3}; + + +/* ASCII to EBCDIC table */ +static const unsigned char cob_ascii_ebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x07, + 0x68, 0xDC, 0x51, 0x42, 0x43, 0x44, 0x47, 0x48, + 0x52, 0x53, 0x54, 0x57, 0x56, 0x58, 0x63, 0x67, + 0x71, 0x9C, 0x9E, 0xCB, 0xCC, 0xCD, 0xDB, 0xDD, + 0xDF, 0xEC, 0xFC, 0xB0, 0xB1, 0xB2, 0x3E, 0xB4, + 0x45, 0x55, 0xCE, 0xDE, 0x49, 0x69, 0x9A, 0x9B, + 0xAB, 0x9F, 0xBA, 0xB8, 0xB7, 0xAA, 0x8A, 0x8B, + 0xB6, 0xB5, 0x62, 0x4F, 0x64, 0x65, 0x66, 0x20, + 0x21, 0x22, 0x70, 0x23, 0x72, 0x73, 0x74, 0xBE, + 0x76, 0x77, 0x78, 0x80, 0x24, 0x15, 0x8C, 0x8D, + 0x8E, 0x41, 0x06, 0x17, 0x28, 0x29, 0x9D, 0x2A, + 0x2B, 0x2C, 0x09, 0x0A, 0xAC, 0x4A, 0xAE, 0xAF, + 0x1B, 0x30, 0x31, 0xFA, 0x1A, 0x33, 0x34, 0x35, + 0x36, 0x59, 0x08, 0x38, 0xBC, 0x39, 0xA0, 0xBF, + 0xCA, 0x3A, 0xFE, 0x3B, 0x04, 0xCF, 0xDA, 0x14, + 0xE1, 0x8F, 0x46, 0x75, 0xFD, 0xEB, 0xEE, 0xED, + 0x90, 0xEF, 0xB3, 0xFB, 0xB9, 0xEA, 0xBB, 0xFF +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog2 (); +static int prog2_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog2 ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog2' */ + +/* ENTRY 'prog2' */ + +static int +prog2 () +{ + return prog2_ (0); +} + +static int +prog2_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 13:58:56 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + /* Program local variables for 'prog2' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Local cob_field items */ + cob_field f0; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[10] __attribute__((aligned)); /* Z */ + static cob_u8_t b_7[10] __attribute__((aligned)); /* G */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_7 = {10, b_7, &a_2}; /* G */ + static cob_field f_9 = {1, b_7, &a_1}; /* X */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 16 : Entry prog2 : prog.cob */ + l_2:; + + /* Line: 16 : MOVE : prog.cob */ + memcpy (b_7, b_6, 10); + + /* Line: 17 : SORT : prog.cob */ + cob_table_sort_init (1, 0); + cob_table_sort_init_key (&f_9, 0, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_7 + 0, &a_2), 10); + + /* Line: 18 : IF : prog.cob */ + if (((int)cob_cmp (&f_7, (cob_field *)&c_1) != 0)) + { + + /* Line: 19 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 20 : MOVE : prog.cob */ + memcpy (b_7, b_6, 10); + + /* Line: 21 : SORT : prog.cob */ + cob_table_sort_init (1, 0); + cob_table_sort_init_key (&f_9, 1, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_7 + 0, &a_2), 10); + + /* Line: 22 : IF : prog.cob */ + if (((int)cob_cmp (&f_7, (cob_field *)&c_2) != 0)) + { + + /* Line: 23 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 24 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog2"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog2; + module->module_cancel.funcptr = (void *(*)())prog2_; + module->collating_sequence = cob_ascii_ebcdic; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memcpy (b_6, "d4b2e1a3c5", 10); + memset (b_7, 32, 10); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog2' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE prog.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) +AT_CHECK([$COMPILE prog2.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog2], [0], [], []) + +AT_CLEANUP + + +AT_SETUP([COLLATING SEQUENCE alphanum comparison]) +AT_KEYWORDS([runmisc EBCDIC ASCII]) + +AT_DATA([ascii.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:37:21 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 17:37:21" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 173721 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:37:21 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x1000, NULL}; +static const cob_field_attr a_2 = {0x21, 0, 0, 0x0000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {1, (cob_u8_ptr)"1", &a_1}; +static const cob_field c_2 = {1, (cob_u8_ptr)"a", &a_1}; +static const cob_field c_3 = {5, (cob_u8_ptr)"ERROR", &a_1}; + + +/* NATIVE table */ +static const unsigned char cob_native[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 17:37:21 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + + /* End of data storage */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 11 : Entry prog : prog.cob */ + l_2:; + + /* Line: 11 : IF : prog.cob */ + if (((int)cob_cmp ((cob_field *)&c_1, (cob_field *)&c_2) >= 0)) + { + + /* Line: 15 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_3); + } + + /* Line: 17 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = cob_native; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + + +AT_DATA([ebcdic.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:34:27 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 17:34:27" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 173427 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:34:27 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x1000, NULL}; +static const cob_field_attr a_2 = {0x21, 0, 0, 0x0000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {1, (cob_u8_ptr)"a", &a_1}; +static const cob_field c_2 = {1, (cob_u8_ptr)"1", &a_1}; +static const cob_field c_3 = {5, (cob_u8_ptr)"ERROR", &a_1}; + + +/* ASCII to EBCDIC table */ +static const unsigned char cob_ascii_ebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x07, + 0x68, 0xDC, 0x51, 0x42, 0x43, 0x44, 0x47, 0x48, + 0x52, 0x53, 0x54, 0x57, 0x56, 0x58, 0x63, 0x67, + 0x71, 0x9C, 0x9E, 0xCB, 0xCC, 0xCD, 0xDB, 0xDD, + 0xDF, 0xEC, 0xFC, 0xB0, 0xB1, 0xB2, 0x3E, 0xB4, + 0x45, 0x55, 0xCE, 0xDE, 0x49, 0x69, 0x9A, 0x9B, + 0xAB, 0x9F, 0xBA, 0xB8, 0xB7, 0xAA, 0x8A, 0x8B, + 0xB6, 0xB5, 0x62, 0x4F, 0x64, 0x65, 0x66, 0x20, + 0x21, 0x22, 0x70, 0x23, 0x72, 0x73, 0x74, 0xBE, + 0x76, 0x77, 0x78, 0x80, 0x24, 0x15, 0x8C, 0x8D, + 0x8E, 0x41, 0x06, 0x17, 0x28, 0x29, 0x9D, 0x2A, + 0x2B, 0x2C, 0x09, 0x0A, 0xAC, 0x4A, 0xAE, 0xAF, + 0x1B, 0x30, 0x31, 0xFA, 0x1A, 0x33, 0x34, 0x35, + 0x36, 0x59, 0x08, 0x38, 0xBC, 0x39, 0xA0, 0xBF, + 0xCA, 0x3A, 0xFE, 0x3B, 0x04, 0xCF, 0xDA, 0x14, + 0xE1, 0x8F, 0x46, 0x75, 0xFD, 0xEB, 0xEE, 0xED, + 0x90, 0xEF, 0xB3, 0xFB, 0xB9, 0xEA, 0xBB, 0xFF +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 17:34:27 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + + /* End of data storage */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 13 : Entry prog : prog.cob */ + l_2:; + + /* Line: 13 : IF : prog.cob */ + if (((int)cob_cmp ((cob_field *)&c_1, (cob_field *)&c_2) >= 0)) + { + + /* Line: 15 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_3); + } + + /* Line: 17 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = cob_ascii_ebcdic; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE -o ascii ascii.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./ascii], [0], [], []) + +AT_CHECK([$COMPILE -o ebcdic ebcdic.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./ebcdic], [0], [], []) + +AT_CLEANUP + + +AT_SETUP([SORT: table with default COLLATING SEQUENCE]) +AT_KEYWORDS([runmisc SORT EBCDIC ASCII]) + +AT_DATA([ascii.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:47:39 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 17:47:39" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 174739 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:47:39 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x01, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {10, (cob_u8_ptr)"12345abcde", &a_3}; + + +/* NATIVE table */ +static const unsigned char cob_native[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 17:47:39 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Local cob_field items */ + cob_field f0; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[10] __attribute__((aligned)); /* Z */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_7 = {10, b_6, &a_2}; /* G */ + static cob_field f_9 = {1, b_6, &a_1}; /* X */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 16 : Entry prog : prog.cob */ + l_2:; + + /* Line: 16 : SORT : prog.cob */ + cob_table_sort_init (1, 0); + cob_table_sort_init_key (&f_9, 0, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_6 + 0, &a_2), 10); + + /* Line: 18 : IF : prog.cob */ + if (((int)cob_cmp (&f_7, (cob_field *)&c_1) != 0)) + { + + /* Line: 24 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 26 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = cob_native; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memcpy (b_6, "d4b2e1a3c5", 10); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_DATA([ebcdic.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:48:46 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 17:48:46" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 174846 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:48:46 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x01, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {10, (cob_u8_ptr)"abcde12345", &a_3}; + + +/* ASCII to EBCDIC table */ +static const unsigned char cob_ascii_ebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x07, + 0x68, 0xDC, 0x51, 0x42, 0x43, 0x44, 0x47, 0x48, + 0x52, 0x53, 0x54, 0x57, 0x56, 0x58, 0x63, 0x67, + 0x71, 0x9C, 0x9E, 0xCB, 0xCC, 0xCD, 0xDB, 0xDD, + 0xDF, 0xEC, 0xFC, 0xB0, 0xB1, 0xB2, 0x3E, 0xB4, + 0x45, 0x55, 0xCE, 0xDE, 0x49, 0x69, 0x9A, 0x9B, + 0xAB, 0x9F, 0xBA, 0xB8, 0xB7, 0xAA, 0x8A, 0x8B, + 0xB6, 0xB5, 0x62, 0x4F, 0x64, 0x65, 0x66, 0x20, + 0x21, 0x22, 0x70, 0x23, 0x72, 0x73, 0x74, 0xBE, + 0x76, 0x77, 0x78, 0x80, 0x24, 0x15, 0x8C, 0x8D, + 0x8E, 0x41, 0x06, 0x17, 0x28, 0x29, 0x9D, 0x2A, + 0x2B, 0x2C, 0x09, 0x0A, 0xAC, 0x4A, 0xAE, 0xAF, + 0x1B, 0x30, 0x31, 0xFA, 0x1A, 0x33, 0x34, 0x35, + 0x36, 0x59, 0x08, 0x38, 0xBC, 0x39, 0xA0, 0xBF, + 0xCA, 0x3A, 0xFE, 0x3B, 0x04, 0xCF, 0xDA, 0x14, + 0xE1, 0x8F, 0x46, 0x75, 0xFD, 0xEB, 0xEE, 0xED, + 0x90, 0xEF, 0xB3, 0xFB, 0xB9, 0xEA, 0xBB, 0xFF +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 17:48:46 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Local cob_field items */ + cob_field f0; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[10] __attribute__((aligned)); /* Z */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_7 = {10, b_6, &a_2}; /* G */ + static cob_field f_9 = {1, b_6, &a_1}; /* X */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 16 : Entry prog : prog.cob */ + l_2:; + + /* Line: 16 : SORT : prog.cob */ + cob_table_sort_init (1, 0); + cob_table_sort_init_key (&f_9, 0, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_6 + 0, &a_2), 10); + + /* Line: 20 : IF : prog.cob */ + if (((int)cob_cmp (&f_7, (cob_field *)&c_1) != 0)) + { + + /* Line: 24 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 26 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = cob_ascii_ebcdic; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memcpy (b_6, "d4b2e1a3c5", 10); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_DATA([native.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:49:26 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 17:49:26" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 174926 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 17:49:26 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x01, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + + +/* Constants */ +static const cob_field c_1 = {10, (cob_u8_ptr)"12345abcde", &a_3}; +static const cob_field c_2 = {10, (cob_u8_ptr)"abcde12345", &a_3}; + + +/* NATIVE table */ +static const unsigned char cob_native[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int prog (); +static int prog_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (prog ()); +} + +/* Functions */ + +/* PROGRAM-ID 'prog' */ + +/* ENTRY 'prog' */ + +static int +prog () +{ + return prog_ (0); +} + +static int +prog_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 17:49:26 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto -fno-constant-folding prog.cob */ + + /* Program local variables for 'prog' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Local cob_field items */ + cob_field f0; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[10] __attribute__((aligned)); /* Z */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_7 = {10, b_6, &a_2}; /* G */ + static cob_field f_9 = {1, b_6, &a_1}; /* X */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 16 : Entry prog : prog.cob */ + l_2:; + + /* Line: 16 : SORT : prog.cob */ + cob_table_sort_init (1, 0); + cob_table_sort_init_key (&f_9, 0, 0); + cob_table_sort (COB_SET_FLD(f0, 1, b_6 + 0, &a_2), 10); + + /* Line: 22 : IF : prog.cob */ + if ((!((int)cob_cmp (&f_7, (cob_field *)&c_1) == 0) || + ((int)cob_cmp (&f_7, (cob_field *)&c_2) == 0))) + { + + /* Line: 24 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &f_7); + } + + /* Line: 26 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "prog"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())prog; + module->module_cancel.funcptr = (void *(*)())prog_; + module->collating_sequence = cob_native; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memcpy (b_6, "d4b2e1a3c5", 10); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'prog' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE -o ascii ascii.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./ascii], [0], [], []) +AT_CHECK([$COMPILE -o ebcdic ebcdic.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./ebcdic], [0], [], []) +AT_CHECK([$COMPILE -o native native.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./native], [0], [], []) + +AT_CLEANUP + + +AT_SETUP([INSPECT/STRING/UNSTRING statements]) +AT_KEYWORDS([backcomp INSPECT STRING UNSTRING]) + +AT_DATA([prog.c], [[ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 16:22:10 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + +#include +#include +#include +#include +#include +#define COB_KEYWORD_INLINE __inline +#include + +#define COB_SOURCE_FILE "prog.cob" +#define COB_PACKAGE_VERSION "2.2" +#define COB_PATCH_LEVEL 0 +#define COB_MODULE_FORMATTED_DATE "juil. 23 2024 16:22:10" +#define COB_MODULE_DATE 20240723 +#define COB_MODULE_TIME 162210 + +/* Global variables */ +/* Generated by cobc 2.2.0 */ +/* Generated from prog.cob */ +/* Generated at juil. 23 2024 16:22:10 */ +/* GnuCOBOL build date Apr 10 2024 16:39:16 */ +/* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ +/* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + +/* Module path */ +static const char *cob_module_path = NULL; + +/* Number of call parameters */ +static int cob_call_params = 0; + +/* Attributes */ + +static const cob_field_attr a_1 = {0x21, 0, 0, 0x0000, NULL}; +static const cob_field_attr a_2 = {0x10, 2, 0, 0x0000, NULL}; +static const cob_field_attr a_3 = {0x21, 0, 0, 0x1000, NULL}; + +static const cob_field_attr cob_all_attr = {0x22, 0, 0, 0, NULL}; + + +/* Constants */ +static const cob_field c_1 = {1, (cob_u8_ptr)"u", &a_3}; +static const cob_field c_2 = {1, (cob_u8_ptr)"2", &a_3}; +static const cob_field c_3 = {1, (cob_u8_ptr)"S", &a_3}; +static const cob_field c_4 = {1, (cob_u8_ptr)"3", &a_3}; +static const cob_field c_5 = {1, (cob_u8_ptr)"4", &a_3}; +static const cob_field c_6 = {1, (cob_u8_ptr)"5", &a_3}; +static const cob_field c_7 = {1, (cob_u8_ptr)"6", &a_3}; +static const cob_field c_8 = {1, (cob_u8_ptr)"s", &a_3}; +static const cob_field c_9 = {1, (cob_u8_ptr)"7", &a_3}; +static const cob_field c_10 = {1, (cob_u8_ptr)"U", &a_3}; +static const cob_field c_11 = {1, (cob_u8_ptr)"8", &a_3}; +static const cob_field c_12 = {1, (cob_u8_ptr)"a", &a_3}; +static const cob_field c_13 = {1, (cob_u8_ptr)"9", &a_3}; +static const cob_field c_14 = {2, (cob_u8_ptr)"aa", &a_3}; +static const cob_field c_15 = {2, (cob_u8_ptr)"AA", &a_3}; +static const cob_field c_16 = {2, (cob_u8_ptr)"10", &a_3}; +static const cob_field c_17 = {2, (cob_u8_ptr)"11", &a_3}; +static const cob_field c_18 = {2, (cob_u8_ptr)"12", &a_3}; + +static cob_field cob_all_space = {1, (cob_u8_ptr)" ", &cob_all_attr}; + + /* Decimal constants */ + + +/* Function prototypes */ + +static int strings__stmt (); +static int strings__stmt_ (const int); + +/* Main function */ +int +main (int argc, char **argv) +{ + cob_init (argc, argv); + cob_stop_run (strings__stmt ()); +} + +/* Functions */ + +/* PROGRAM-ID 'strings-stmt' */ + +/* ENTRY 'strings__stmt' */ + +static int +strings__stmt () +{ + return strings__stmt_ (0); +} + +static int +strings__stmt_ (const int entry) +{ + /* Program local variables */ + /* Generated by cobc 2.2.0 */ + /* Generated from prog.cob */ + /* Generated at juil. 23 2024 16:22:10 */ + /* GnuCOBOL build date Apr 10 2024 16:39:16 */ + /* GnuCOBOL package date Sep 06 2017 18:45:29 UTC */ + /* Compile command /opt/gnucobol/gnucobol-2.2/bin/cobc -Cx -fno-computed-goto prog.cob */ + + /* Program local variables for 'strings-stmt' */ + + /* Module initialization indicator */ + static unsigned int initialized = 0; + + /* Module structure pointer */ + static cob_module *module = NULL; + + /* Global variable pointer */ + cob_global *cob_glob_ptr; + + + /* Call parameters */ + cob_field *cob_procedure_params[1]; + + /* Perform frame stack */ + struct cob_frame *frame_ptr; + struct cob_frame frame_stack[255]; + + + /* Data storage */ + static int b_2; /* RETURN-CODE */ + static cob_u8_t b_6[30] __attribute__((aligned)); /* ws-0 */ + static cob_u8_t b_7[10] __attribute__((aligned)); /* ws-1 */ + static cob_u8_t b_8[40] __attribute__((aligned)); /* ws-2 */ + static cob_u8_t b_9[28] __attribute__((aligned)); /* ws-words */ + static cob_u8_t b_13[2] __attribute__((aligned)); /* ws-count */ + + /* End of data storage */ + + + /* Fields */ + static cob_field f_6 = {30, b_6, &a_1}; /* ws-0 */ + static cob_field f_7 = {10, b_7, &a_1}; /* ws-1 */ + static cob_field f_8 = {40, b_8, &a_1}; /* ws-2 */ + static cob_field f_10 = {10, b_9, &a_1}; /* ws-words1 */ + static cob_field f_11 = {12, b_9 + 10, &a_1}; /* ws-words2 */ + static cob_field f_12 = {6, b_9 + 22, &a_1}; /* ws-words3 */ + static cob_field f_13 = {2, b_13, &a_2}; /* ws-count */ + + /* End of fields */ + + + + /* Start of function code */ + + /* CANCEL callback */ + if (unlikely(entry < 0)) { + if (entry == -20) + goto P_clear_decimal; + goto P_cancel; + } + + /* Check initialized, check module allocated, */ + /* set global pointer, */ + /* push module stack, save call parameter count */ + if (cob_module_global_enter (&module, &cob_glob_ptr, 0, entry, 0)) + return -1; + + /* Set address of module parameter list */ + module->cob_procedure_params = cob_procedure_params; + + /* Set frame stack pointer */ + frame_ptr = frame_stack; + frame_ptr->perform_through = 0; + + /* Initialize rest of program */ + if (unlikely(initialized == 0)) { + goto P_initialize; + } + P_ret_initialize: + + /* Increment module active */ + module->module_active++; + + /* Entry dispatch */ + goto l_2; + + /* PROCEDURE DIVISION */ + + /* Line: 16 : Entry strings-stmt : prog.cob */ + l_2:; + + /* Line: 16 : Paragraph main-section : prog.cob */ + + /* Line: 17 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 0); + cob_inspect_start (); + cob_inspect_all (&f_13, (cob_field *)&c_1); + cob_inspect_finish (); + + /* Line: 18 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_13, 2, 2LL, 0) != 0)) + { + + /* Line: 18 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_2); + + /* Line: 19 : INITIALIZE : prog.cob */ + memset (b_13, 48, 2); + + /* Line: 21 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 0); + cob_inspect_start (); + cob_inspect_leading (&f_13, (cob_field *)&c_3); + cob_inspect_finish (); + + /* Line: 22 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_13, 2, 2LL, 0) != 0)) + { + + /* Line: 22 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_4); + + /* Line: 23 : INITIALIZE : prog.cob */ + memset (b_13, 48, 2); + + /* Line: 25 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 0); + cob_inspect_start (); + cob_inspect_before (&cob_all_space); + cob_inspect_characters (&f_13); + cob_inspect_finish (); + + /* Line: 27 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_13, 2, 10LL, 0) != 0)) + { + + /* Line: 27 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_5); + + /* Line: 28 : INITIALIZE : prog.cob */ + memset (b_13, 48, 2); + + /* Line: 30 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 0); + cob_inspect_start (); + cob_inspect_before (&cob_all_space); + cob_inspect_all (&f_13, (cob_field *)&c_3); + cob_inspect_finish (); + + /* Line: 32 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_13, 2, 4LL, 0) != 0)) + { + + /* Line: 32 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_6); + + /* Line: 33 : INITIALIZE : prog.cob */ + memset (b_13, 48, 2); + + /* Line: 35 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 0); + cob_inspect_start (); + cob_inspect_after (&cob_all_space); + cob_inspect_all (&f_13, (cob_field *)&c_3); + cob_inspect_finish (); + + /* Line: 37 : IF : prog.cob */ + if (((int)cob_cmp_numdisp (b_13, 2, 1LL, 0) != 0)) + { + + /* Line: 37 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_7); + + /* Line: 39 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 1); + cob_inspect_start (); + cob_inspect_leading ((cob_field *)&c_8, (cob_field *)&c_3); + cob_inspect_finish (); + + /* Line: 40 : IF : prog.cob */ + if (((int)memcmp (b_6, (cob_u8_ptr)"ssYNSSWuAK 06fLGvxwYRgr BjVuSk", 30) != 0)) + { + + /* Line: 41 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_9); + + /* Line: 43 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 1); + cob_inspect_start (); + cob_inspect_all ((cob_field *)&c_8, (cob_field *)&c_3); + cob_inspect_start (); + cob_inspect_all ((cob_field *)&c_10, (cob_field *)&c_1); + cob_inspect_finish (); + + /* Line: 45 : IF : prog.cob */ + if (((int)memcmp (b_6, (cob_u8_ptr)"ssYNssWUAK 06fLGvxwYRgr BjVUsk", 30) != 0)) + { + + /* Line: 46 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_11); + + /* Line: 48 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 1); + cob_inspect_start (); + cob_inspect_before (&cob_all_space); + cob_inspect_all ((cob_field *)&c_12, (cob_field *)&c_8); + cob_inspect_finish (); + + /* Line: 51 : IF : prog.cob */ + if (((int)memcmp (b_6, (cob_u8_ptr)"aaYNaaWUAK 06fLGvxwYRgr BjVUsk", 30) != 0)) + { + + /* Line: 52 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_13); + + /* Line: 54 : INSPECT : prog.cob */ + cob_inspect_init (&f_6, 0); + cob_inspect_start (); + cob_inspect_converting ((cob_field *)&c_14, (cob_field *)&c_15); + cob_inspect_finish (); + + /* Line: 55 : IF : prog.cob */ + if (((int)memcmp (b_6, (cob_u8_ptr)"AAYNAAWUAK 06fLGvxwYRgr BjVUsk", 30) != 0)) + { + + /* Line: 56 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_16); + + /* Line: 58 : STRING : prog.cob */ + cob_string_init (&f_8, NULL); + cob_string_delimited (NULL); + cob_string_append (&f_6); + cob_string_delimited (NULL); + cob_string_append (&f_7); + cob_string_finish (); + + /* Line: 61 : IF : prog.cob */ + if (((int)memcmp (b_8, (cob_u8_ptr)"AAYNAAWUAK 06fLGvxwYRgr BjVUskoNDT8a9awk", 40) != 0)) + { + + /* Line: 62 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_17); + + /* Line: 64 : UNSTRING : prog.cob */ + cob_unstring_init (&f_6, NULL, 1); + cob_unstring_delimited (&cob_all_space, 1); + cob_unstring_into (&f_10, 0, 0); + cob_unstring_into (&f_11, 0, 0); + cob_unstring_into (&f_12, 0, 0); + cob_unstring_finish (); + + /* Line: 68 : IF : prog.cob */ + if (((int)memcmp (b_9, (cob_u8_ptr)"AAYNAAWUAK06fLGvxwYRgrBjVUsk", 28) != 0)) + { + + /* Line: 69 : DISPLAY : prog.cob */ + cob_display (0, 1, 1, &c_18); + + /* Line: 71 : STOP RUN : prog.cob */ + cob_stop_run (b_2); + } + } + } + } + } + } + } + } + } + } + } + + /* Program exit */ + + /* Decrement module active count */ + if (module->module_active) { + module->module_active--; + } + + /* Pop module stack */ + cob_module_leave (module); + + /* Program return */ + return b_2; + + /* Frame stack jump table */ + P_switch: + cob_fatal_error (COB_FERROR_CODEGEN); + + + /* Program initialization */ + P_initialize: + + cob_check_version (COB_SOURCE_FILE, COB_PACKAGE_VERSION, COB_PATCH_LEVEL); + + cob_module_path = cob_glob_ptr->cob_main_argv0; + + /* Initialize module structure */ + module->module_name = "strings-stmt"; + module->module_formatted_date = COB_MODULE_FORMATTED_DATE; + module->module_source = COB_SOURCE_FILE; + module->module_entry.funcptr = (void *(*)())strings__stmt; + module->module_cancel.funcptr = (void *(*)())strings__stmt_; + module->collating_sequence = NULL; + module->crt_status = NULL; + module->cursor_pos = NULL; + module->module_ref_count = NULL; + module->module_path = &cob_module_path; + module->module_active = 0; + module->module_date = COB_MODULE_DATE; + module->module_time = COB_MODULE_TIME; + module->module_type = 0; + module->module_param_cnt = 0; + module->module_returning = 0; + module->ebcdic_sign = 0; + module->decimal_point = '.'; + module->currency_symbol = '$'; + module->numeric_separator = ','; + module->flag_filename_mapping = 1; + module->flag_binary_truncate = 1; + module->flag_pretty_display = 1; + module->flag_host_sign = 0; + module->flag_no_phys_canc = 1; + module->flag_main = 1; + module->flag_fold_call = 0; + module->flag_exit_program = 0; + + /* Initialize cancel callback */ + cob_set_cancel (module); + + /* Initialize WORKING-STORAGE */ + b_2 = 0; + memcpy (b_6, "SSYNSSWuAK 06fLGvxwYRgr BjVuSk", 30); + memcpy (b_7, "oNDT8a9awk", 10); + memset (b_8, 32, 40); + memset (b_9, 32, 28); + memset (b_13, 48, 2); + + initialized = 1; + goto P_ret_initialize; + + /* CANCEL callback handling */ + P_cancel: + + if (!initialized) { + return 0; + } + if (module->module_active) { + cob_fatal_error (COB_FERROR_CANCEL); + } + + initialized = 0; + + P_clear_decimal: + + return 0; + +} + +/* End PROGRAM-ID 'strings-stmt' */ + +/* End functions */ + + +]]) + +AT_CHECK([$COMPILE prog.c], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP From eb74013d3e4fec6049135ffe259957cb787f3e03 Mon Sep 17 00:00:00 2001 From: David Declerck Date: Mon, 18 Mar 2024 14:38:51 +0100 Subject: [PATCH 04/51] Add/Update Windows workflows --- .github/workflows/macos.yml | 2 + .github/workflows/ubuntu.yml | 1 + .github/workflows/windows-msvc.yml | 248 ++++++++++++++++++++++++++++ .github/workflows/windows-msys1.yml | 227 +++++++++++++++++++++++++ .github/workflows/windows-msys2.yml | 118 +++++++++++++ .github/workflows/windows.yml | 93 ----------- 6 files changed, 596 insertions(+), 93 deletions(-) create mode 100644 .github/workflows/windows-msvc.yml create mode 100644 .github/workflows/windows-msys1.yml create mode 100644 .github/workflows/windows-msys2.yml delete mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ffc2dcec1..aa61cb3b2 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -5,6 +5,8 @@ on: branches: [ gcos4gnucobol-3.x ] push: branches: [ gcos4gnucobol-3.x ] + # manual run in actions tab - for all branches + workflow_dispatch: jobs: build: diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 352b6282f..a16d542aa 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -4,6 +4,7 @@ on: pull_request: branches: [ gcos4gnucobol-3.x ] push: + branches: [ gcos4gnucobol-3.x ] # manual run in actions tab - for all branches workflow_dispatch: diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml new file mode 100644 index 000000000..a5a9488ba --- /dev/null +++ b/.github/workflows/windows-msvc.yml @@ -0,0 +1,248 @@ +name: Windows MSVC Workflow + +on: + pull_request: + branches: [ gcos4gnucobol-3.x ] + push: + branches: [ gcos4gnucobol-3.x ] + # manual run in actions tab - for all branches + workflow_dispatch: + +env: + GC_VERSION: GnuCOBOL 3.3-dev + + FLEXBISON: https://github.com/lexxmark/winflexbison/releases/download/v2.5.25/win_flex_bison-2.5.25.zip + + MSBUILD: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MSBuild.exe + VCVARS32: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat + VCVARS64: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat + + VCPKG_ROOT: C:\vcpkg + VCPKGS32: mpir:x86-windows pdcurses:x86-windows berkeleydb:x86-windows libxml2:x86-windows cjson:x86-windows + VCPKGS64: mpir:x64-windows pdcurses:x64-windows berkeleydb:x64-windows libxml2:x64-windows cjson:x64-windows + + MSYS2_ROOT: C:\msys64 + MSYSTEM: UCRT64 + MSYSPKGS: autoconf + +defaults: + run: + shell: cmd + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: + - windows-latest + arch: + - x86 + - x64 + target: + - Debug + - Release + + runs-on: ${{ matrix.os }} + + steps: + + - name: Set git user + run: | + git config --global user.name github-actions + git config --global user.email github-actions-bot@users.noreply.github.com + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup environment + shell: pwsh + run: | + echo GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV + If ("${{ matrix.arch }}" -eq "x86") { + echo VCVARS=$env:VCVARS32 >> $env:GITHUB_ENV + echo VCPKGS=$env:VCPKGS32 >> $env:GITHUB_ENV + echo ARCHDIR=Win32 >> $env:GITHUB_ENV + } Else { + echo VCVARS=$env:VCVARS64 >> $env:GITHUB_ENV + echo VCPKGS=$env:VCPKGS64 >> $env:GITHUB_ENV + echo ARCHDIR=x64 >> $env:GITHUB_ENV + } + + - name: Restore VCPKG cache + id: restore-vcpkg + uses: actions/cache/restore@v4 + with: + key: cache-vcpkg-${{ matrix.arch }}-${{ matrix.target }} + path: | + ${{ env.VCPKG_ROOT }}/installed + ${{ env.VCPKG_ROOT }}/packages + + - name: Bootstrap VCPKG + if: steps.restore-vcpkg.outputs.cache-hit != 'true' + run: | + cd /d %VCPKG_ROOT% + vcpkg update + git pull + cmd /C .\bootstrap-vcpkg.bat -disableMetrics + + - name: Integrate VCPKG + run: | + vcpkg integrate install + + - name: Install VCPKG packages + if: steps.restore-vcpkg.outputs.cache-hit != 'true' + run: | + vcpkg install %VCPKGS% + + - name: Save VCPKG cache + if: steps.restore-vcpkg.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-vcpkg-${{ matrix.arch }}-${{ matrix.target }} + path: | + ${{ env.VCPKG_ROOT }}/installed + ${{ env.VCPKG_ROOT }}/packages + + - name: Restore WinFlexBison cache + uses: actions/cache/restore@v4 + id: restore-flexbison + with: + key: cache-flexbison-${{ matrix.arch }}-${{ matrix.target }} + path: ${{ env.GITHUB_WORKSPACE }}/flexbison + + - name: Install WinFlexBison + if: steps.restore-flexbison.outputs.cache-hit != 'true' + shell: pwsh + run: | + Invoke-WebRequest -Uri $env:FLEXBISON -OutFile flexbison.zip + Expand-Archive flexbison.zip -DestinationPath flexbison + + - name: Save WinFlexBison cache + if: steps.restore-flexbison.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-flexbison-${{ matrix.arch }}-${{ matrix.target }} + path: ${{ env.GITHUB_WORKSPACE }}/flexbison + + - name: Configure GnuCOBOL + shell: pwsh + run: | + cd build_windows + Get-Content -Path 'config.h.in' | ForEach-Object { $_ ` + -replace '(#define\s+CONFIGURED_ISAM)\s.+$', '$1 BDB' ` + -replace '(#define\s+CONFIGURED_CURSES)\s.+$', '$1 PDCURSES' ` + -replace '(#define\s+CONFIGURED_XML)\s.+$', '$1 XML2' ` + -replace '(#define\s+CONFIGURED_JSON)\s.+$', '$1 CJSON_CJSON' ` + } | Set-Content -Path 'config.h' + & .\maketarstamp.ps1 > tarstamp.h + + - name: Generate parser + run: | + cd build_windows + set PATH=%GITHUB_WORKSPACE%\flexbison;%PATH% + cmd /C .\makebisonflex.cmd atconfig + echo abs_builddir=\'$(pwd)\' >> atconfig + echo at_srcdir=\'./\' >> atconfig + echo abs_srcdir=\'$(pwd)/\' >> atconfig + echo at_top_srcdir=\'../\' >> atconfig + echo abs_top_srcdir=\'$(pwd)/../\' >> atconfig + echo at_top_build_prefix=\'../\' >> atconfig + echo abs_top_builddir=\'$(pwd)/../\' >> atconfig + echo at_top_builddir=\$at_top_build_prefix >> atconfig + echo EXEEXT=\'.exe\' >> atconfig + echo AUTOTEST_PATH=\'tests\' >> atconfig + echo SHELL=\${CONFIG_SHELL-\'/bin/sh\'} >> atconfig + echo m4_define\([AT_PACKAGE_STRING], [$GC_VERSION]\) > package.m4 + echo m4_define\([AT_PACKAGE_BUGREPORT], [bug-gnucobol@gnu.org]\) >> package.m4 + sed 's/x64\/Debug/${{ env.ARCHDIR }}\/${{ matrix.target }}/g' atlocal_win > atlocal + sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + + sed -i '/AT_SETUP(\[MOVE to edited item (4)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[MOVE to item with simple and floating insertion\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[Numeric operations (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[Numeric operations (3) PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[DISPLAY with P fields\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[MOVE with de-editting to COMP-3\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[MOVE between USAGEs\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[Computing of different USAGEs w\/- decimal point\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[C-API (param based)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[C-API (field based)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[Default Arithmetic Test (2)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[OSVS Arithmetic Test (2)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[FUNCTION ACOS\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[FUNCTION ASIN\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[MOVE of non-integer to alphanumeric\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at + sed -i '/AT_SETUP(\[XML GENERATE trimming\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_ml.at + sed -i '/AT_SETUP(\[JSON GENERATE trimming\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_ml.at + sed -i '/AT_SETUP(\[MOVE PACKED-DECIMAL to BINARY\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_binary.at + sed -i '/AT_SETUP(\[PACKED-DECIMAL dump\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[PACKED-DECIMAL used with MOVE\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[MOVE PACKED-DECIMAL to PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[MOVE PACKED-DECIMAL to DISPLAY\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[MOVE DISPLAY to PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[PACKED-DECIMAL comparison\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[COMP-6 comparison\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[COMP-3 vs. COMP-6 - BCD comparison\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[PPP COMP-3\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[PPP COMP-6\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[MOVE between several BCD fields\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, DEFAULT ROUNDING MODE\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[CURRENCY SIGN WITH PICTURE SYMBOL\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + + sed -i '/AT_SETUP(\[MF FIGURATIVE to NUMERIC\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[Default file external name\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at + sed -i '/AT_SETUP(\[EXTFH: SEQUENTIAL files\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at + sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at + sed -i '/AT_SETUP(\[FUNCTION RANDOM\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at + + autom4te --lang=autotest -I ./testsuite.src ./testsuite.at -o ./testsuite + +# The tests in sed commands above randomly hang (under debug configurations) + + - name: Run testsuite + continue-on-error: true + run: | + cd tests + set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" + call "%VCVARS%" + set MSYS2_PATH_TYPE=inherit + C:\shells\msys2bash.cmd -c "./testsuite || ./testsuite --recheck --verbose" + + - name: Upload testsuite-${{ matrix.arch }}-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + with: + name: testsuite-${{ matrix.arch }}-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/tests/testsuite.log + + # - name: Package GnuCOBOL + # run: | + # cd build_windows + # set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" + # call "%VCVARS%" + # cmd /C .\makedist.cmd > $env:GITHUB_ENV + echo HOME=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV + echo PATH="$env:MSYS_BIN;$env:PATH" >> $env:GITHUB_ENV + If ("${{ matrix.target }}" -eq "release") { + echo DISTDIR=GnuCOBOL_mingw >> $env:GITHUB_ENV + echo CFGOPT= >> $env:GITHUB_ENV + } Else { + echo DISTDIR=GnuCOBOL_mingw_dbg >> $env:GITHUB_ENV + echo CFGOPT="--enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV + } + + - name: Restore MSYS1 cache + id: restore-msys + uses: actions/cache/restore@v4 + with: + key: cache-msys-${{ matrix.target }} + path: ${{ env.MSYS_ROOT }} + + - name: Install MSYS1 + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + curl -O https://www.arnoldtrembley.com/MinGW-bkup02.7z + 7z x MinGW-bkup02.7z -o%MSYS_ROOT%\ + + - name: Install MSYS1 packages + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + bash -lc "mingw-get install %MSYSPKGS%" + + - name: Install Bison 3.0 + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + curl -L https://mirror.ibcp.fr/pub/gnu/bison/%MINGW_BISON_VERS%.tar.xz -o %MINGW_BISON_VERS%.tar.xz + tar -xvf %MINGW_BISON_VERS%.tar.xz + bash -lc "cd %MINGW_BISON_VERS% && ./configure --prefix=/mingw && make" + bash -lc "cd %MINGW_BISON_VERS% && make install" + + # Note: actually unavailable, so skip (works with the GMP alredy provided) + # - name: Install GMP + # if: steps.restore-msys.outputs.cache-hit != 'true' + # run: | + # curl -L https://gmplib.org/download/gmp/%MINGW_GMP_VERS%.tar.xz -o %MINGW_GMP_VERS%.tar.xz + # tar -xvf %MINGW_GMP_VERS%.tar.xz + # bash -lc "cd %MINGW_GMP_VERS% && ./configure --prefix=/mingw --enable-fat --enable-shared --disable-static CFLAGS=\"-Wno-attributes -Wno-ignored-attributes\" ABI=32 && make" + # bash -lc "cd %MINGW_GMP_VERS% && make install" + + - name: Install BDB + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + curl -L https://download.oracle.com/berkeley-db/%MINGW_BDB_VERS%.tar.gz -o %MINGW_BDB_VERS%.tar.gz + tar -xvf %MINGW_BDB_VERS%.tar.gz + sed -i 's/_tcsclen/strlen/' %MINGW_BDB_VERS%\src\os_windows\os_stat.c + bash -lc "cd %MINGW_BDB_VERS%/build_unix && ../dist/configure --prefix=/mingw --enable-mingw --enable-debug --disable-static --disable-replication --disable-tcl LIBCSO_LIBS=-lwsock32 && make || make" + bash -lc "cd %MINGW_BDB_VERS%/build_unix && make install" + + - name: Install PDCurses + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + curl -L https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v%MINGW_PDCM_VERS%.tar.gz -o "PDCursesMod-%MINGW_PDCM_VERS%.tar.xz" + tar -xvf PDCursesMod-%MINGW_PDCM_VERS%.tar.xz + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS%\wincon && make INFOEX=N CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS%\wingui && make CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS%\vt && make CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll CFLAGS=\"-Wall -Wextra -pedantic -g -DPDCDEBUG -fPIC -DPDC_DLL_BUILD\"" + echo #define CHTYPE_64 > PDCursesMod-%MINGW_PDCM_VERS%\pdcurses.h + echo #define PDC_DLL_BUILD >> PDCursesMod-%MINGW_PDCM_VERS%\pdcurses.h + echo #include "pdcurses/curses.h" >> PDCursesMod-%MINGW_PDCM_VERS%\pdcurses.h + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wincon/libpdcurses.dll.a /mingw/lib/" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wincon/libpdcurses.dll /mingw/bin/" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wincon/libpdcurses.dll /mingw/bin/libpdcurses-wincon.dll" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wingui/libpdcurses.dll /mingw/bin/libpdcurses-wingui.dll" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install vt/libpdcurses.dll /mingw/bin/libpdcurses-vt.dll" + bash -lc "install -d /mingw/include/pdcurses" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install -m 0644 curses.h panel.h term.h /mingw/include/pdcurses/" + bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install -m 0644 pdcurses.h /mingw/include/" + + - name: Install LibXML2 + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + curl -L https://github.com/GNOME/libxml2/archive/refs/tags/v%MINGW_XML2_VERS%.tar.gz -o libxml2-%MINGW_XML2_VERS%.tar.xz + tar -xvf libxml2-%MINGW_XML2_VERS%.tar.xz + bash -lc "cd libxml2-%MINGW_XML2_VERS% && ./autogen.sh" + bash -lc "cd libxml2-%MINGW_XML2_VERS% && ./configure --prefix=/mingw && make" + bash -lc "cd libxml2-%MINGW_XML2_VERS% && make install" + + - name: Cleanup MSYS1 env + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + rmdir /Q /S %MSYS_ROOT%\docs + rmdir /Q /S %MSYS_ROOT%\var + del /Q %MSYS_ROOT%\bin\gdb.exe + + - name: Save MSYS1 cache + if: steps.restore-msys.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-msys-${{ matrix.target }} + path: ${{ env.MSYS_ROOT }} + + - name: Download CJSON sources + run: | + curl -L https://github.com/DaveGamble/cJSON/archive/refs/tags/v%MINGW_CJSON_VERS%.tar.gz -o cjson-%MINGW_CJSON_VERS%.tar.xz + tar -xvf cjson-%MINGW_CJSON_VERS%.tar.xz + copy cjson-%MINGW_CJSON_VERS%\cJSON.* .\libcob + + - name: Bootstrap GnuCOBOL + run: | + sed -i 's/AM_PROG_AR/m4_ifdef\(\[AM_PROG_AR\], \[AM_PROG_AR\]\)/g' .\configure.ac + sed -i 's/po extras doc tests/po extras tests/g' .\Makefile.am + bash -lc "./autogen.sh" + + - name: Configure GnuCOBOL + run: | + mkdir _build + sed -i 'N;s/else/else :;/g' .\configure + sed -i 's/\} else \:;/} else/g' .\configure + sed -i 's/#else \:;/#else/g' .\configure + bash -lc "cd _build && ../configure %CFGOPT% --with-db --prefix=/opt/cobol/gnucobol" + + - name: Upload config-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + if: failure() + with: + name: config-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/config.log + + - name: Build GnuCOBOL + run: | + bash -lc "cd _build && CPATH=$(pwd)/.. make --jobs=$(($(nproc)+1))" + +# Note: the extra CPATH above is only required in debug builds, for some reason... + + - name: Install GnuCOBOL + run: | + bash -lc "cd _build && make install" + bash -lc "cd _build && find /opt/cobol > install.log" + + - name: Upload install-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + with: + name: install-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log + + - name: Run testsuite + continue-on-error: true + run: | + sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' .\tests\testsuite.src\used_binaries.at + bash -lc "cd _build/tests && CPATH=/opt/cobol/gnucobol/include make check TESTSUITEFLAGS=\"--jobs=$(($(nproc)+1))\"" + +# Note: the extra CPATH above is only required in debug builds, for some reason... + +# The NIST testsuite hangs forever in IF +# bash -lc "CPATH=/opt/cobol/gnucobol/include make test" + + - name: Upload testsuite-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + with: + name: testsuite-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log + + - name: Package GnuCOBOL + run: | + bash -lc "cd _build && make distmingw" + + - name: Upload GnuCOBOL_mingw-${{ matrix.target }} + uses: actions/upload-artifact@v4 + with: + name: GnuCOBOL_mingw-${{ matrix.target }} + path: ${{ env.GITHUB_WORKSPACE }}/_build/${{ env.DISTDIR }} diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml new file mode 100644 index 000000000..370ef71a1 --- /dev/null +++ b/.github/workflows/windows-msys2.yml @@ -0,0 +1,118 @@ +name: Windows MSYS2 Workflow + +on: + pull_request: + branches: [ gcos4gnucobol-3.x ] + push: + branches: [ gcos4gnucobol-3.x ] + # manual run in actions tab - for all branches + workflow_dispatch: + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: + - windows-latest + arch: + - x64 + target: + - debug + - release + + runs-on: ${{ matrix.os }} + + steps: + + - name: Set git user + run: | + git config --global user.name github-actions + git config --global user.email github-actions-bot@users.noreply.github.com + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup environment + run: | + echo GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV + If ("${{ matrix.target }}" -eq "release") { + echo DISTDIR=GnuCOBOL_mingw >> $env:GITHUB_ENV + echo CFGOPT= >> $env:GITHUB_ENV + } Else { + echo DISTDIR=GnuCOBOL_mingw_dbg >> $env:GITHUB_ENV + echo CFGOPT="--enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV + } + + - name: Install MSYS2 packages + uses: msys2/setup-msys2@v2 + with: + update: true + msystem: ucrt64 + install: autoconf automake libtool make mingw-w64-ucrt-x86_64-ncurses mingw-w64-ucrt-x86_64-libxml2 mingw-w64-ucrt-x86_64-cjson mingw-w64-ucrt-x86_64-db mingw-w64-ucrt-x86_64-gmp libdb-devel mingw-w64-ucrt-x86_64-gcc flex bison gmp-devel help2man texinfo gettext-devel + + - name: Bootstrap GnuCOBOL + shell: msys2 {0} + run: | + ./autogen.sh + autoconf + autoreconf --install --force + + - name: Configure GnuCOBOL + shell: msys2 {0} + run: | + mkdir _build + cd _build + ../configure $CFGOPT --with-db --prefix=/opt/cobol/gnucobol + + - name: Upload config-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + if: failure() + with: + name: config-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/config.log + + - name: Build GnuCOBOL + shell: msys2 {0} + run: | + cd _build + make --jobs=$(($(nproc)+1)) + + - name: Install GnuCOBOL + shell: msys2 {0} + run: | + cd _build + make install + find /opt/cobol > install.log + + - name: Upload install-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + with: + name: install-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log + + - name: Run testuite + shell: msys2 {0} + run: | + sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/used_binaries.at + cd _build/tests + make check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" + make test + + - name: Upload testsuite-${{ matrix.target }}.log + uses: actions/upload-artifact@v4 + with: + name: testsuite-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log + + - name: Package GnuCOBOL + shell: msys2 {0} + run: | + cd _build + make distmingw + + - name: Upload GnuCOBOL_mingw-${{ matrix.target }} + uses: actions/upload-artifact@v4 + with: + name: GnuCOBOL_mingw-${{ matrix.target }} + path: ${{ env.GITHUB_WORKSPACE }}/_build/${{ env.DISTDIR }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index e238d741a..000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Windows Workflow - -on: - pull_request: - branches: [ gcos4gnucobol-3.x ] - push: - branches: [ gcos4gnucobol-3.x ] - # manual run in actions tab - for all branches - # workflow_dispatch: - -jobs: - build: - strategy: - fail-fast: false - matrix: - os: - - windows-latest - - runs-on: ${{ matrix.os }} - - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - name: Checkout code - uses: actions/checkout@v3 - - - name: Install packages - uses: msys2/setup-msys2@v2 - with: - update: true - install: autoconf automake libtool make mingw-w64-x86_64-db mingw-w64-x86_64-gmp libdb-devel mingw-w64-x86_64-gcc flex bison gmp-devel help2man texinfo gettext-devel - - - name: Set git user - run: | - git config --global user.name github-actions - git config --global user.email github-actions-bot@users.noreply.github.com - - - name: bootstrap - run: | - ./autogen.sh - autoconf - autoreconf --install --force - shell: msys2 {0} - - - name: Build environment setup - run: | - mkdir _build - shell: msys2 {0} - - - name: configure - run: | - cd _build - ../configure --enable-cobc-internal-checks --enable-hardening --prefix /opt/cobol/gnucobol-gcos --exec-prefix /opt/cobol/gnucobol-gcos - shell: msys2 {0} - - - name: Upload config.log - uses: actions/upload-artifact@v3 - if: failure() - with: - name: config.log - path: _build/config.log - - - name: make - run: | - cd _build - make --jobs=$(($(nproc)+1)) - shell: msys2 {0} - - - name: install - run: | - cd _build - make install - find /opt/cobol > install.log - shell: msys2 {0} - - - name: Upload install.log - uses: actions/upload-artifact@v3 - with: - name: install.log - path: _build/install.log - - - name: check - continue-on-error: true - run: | - cd _build/tests - make check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || (echo "not all tests passed") - make test - shell: msys2 {0} - - - name: Upload testsuite.log - uses: actions/upload-artifact@v3 - with: - name: testsuite.log - path: _build/tests/testsuite.log From 0fa2bf5f5238772b8eb46ace17f2ea958b7726d2 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Fri, 26 Jul 2024 15:22:06 +0000 Subject: [PATCH 05/51] increase portability for Micro Focus and ACUCOBOL-GT cobc: * parser.y, config.def: rewrite `ENVIRONMENT DIVISION` parsing to allow non-standard order of `CONFIGURATION` and `INPUT-OUTPUT` sections, depending on `incorrect-conf-sec-order` dialect setting * reserved.c: make `MENU` context-sensitive * reserved.c, parser.y: added `MODAL` + `MODELESS` to acu extension windows --- cobc/ChangeLog | 8 ++++ cobc/config.def | 2 +- cobc/parser.y | 70 ++++++++++++++++++++++++--------- cobc/reserved.c | 10 ++++- tests/testsuite.src/syn_misc.at | 59 +++++++++++++++------------ 5 files changed, 102 insertions(+), 47 deletions(-) diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 50fbd7507..391f5785e 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,12 @@ +2024-07-26 Simon Sobisch + + * parser.y, config.def: rewrite ENVIRONMENT DIVISION parsing to allow + non-standard order of CONFIGURATION and INPUT-OUTPUT sections, + depending on dialect setting "incorrect-conf-sec-order" + * reserved.c: make MENU context-sensitive + * reserved.c, parser.y: added MODAL + MODELESS to acu extension windows + 2024-07-10 Chuck Haatvedt * tree.c (cb_build_picture): fixed currency scale counting logic diff --git a/cobc/config.def b/cobc/config.def index ae70c6bc2..ce587c5a4 100644 --- a/cobc/config.def +++ b/cobc/config.def @@ -381,7 +381,7 @@ CB_CONFIG_SUPPORT (cb_numeric_value_for_edited_item, "numeric-value-for-edited-i _("numeric literals in VALUE clause of numeric-edited items")) CB_CONFIG_SUPPORT (cb_incorrect_conf_sec_order, "incorrect-conf-sec-order", - _("incorrect order of CONFIGURATION SECTION paragraphs")) /* OpenCOBOL/GnuCOBOL extension */ + _("incorrect order of CONFIGURATION SECTION and its paragraphs")) /* MF extension */ CB_CONFIG_SUPPORT (cb_define_constant_directive, "define-constant-directive", _("allow >> DEFINE CONSTANT var AS literal")) /* OpenCOBOL/GnuCOBOL extension */ diff --git a/cobc/parser.y b/cobc/parser.y index 6cb5fd120..5f4eebe45 100644 --- a/cobc/parser.y +++ b/cobc/parser.y @@ -2989,7 +2989,9 @@ set_record_size (cb_tree min, cb_tree max) %token MINUS %token MIN_VAL "MIN-VAL" %token MNEMONIC_NAME "Mnemonic name" +%token MODAL %token MODE +%token MODELESS %token MODIFY %token MODULES %token MOVE @@ -3401,7 +3403,6 @@ set_record_size (cb_tree min, cb_tree max) %token V %token VALID %token VALIDATE -%token VAL_STATUS "VAL-STATUS" %token VALIDATE_STATUS "VALIDATE-STATUS" %token VALIDATING %token VALUE @@ -4163,8 +4164,21 @@ intermediate_rounding_choice: _environment_division: _environment_header - _configuration_section - _input_output_section + _environment_sections +; + +_environment_sections: +| configuration_section _input_output_section +| input_output_section configuration_section + { +#define MESSAGE_LEN 100 + char message[MESSAGE_LEN] = { '\0' }; + snprintf (message, MESSAGE_LEN, _("%s incorrectly after %s"), + "CONFIGURATION SECTION", "INPUT-OUTPUT SECTION"); + cb_verify (cb_incorrect_conf_sec_order, message); +#undef MESSAGE_LEN + } +| input_output_section ; _environment_header: @@ -4181,13 +4195,9 @@ environment_header: /* CONFIGURATION SECTION */ -_configuration_section: - _configuration_header - _configuration_paragraphs -; - -_configuration_header: -| configuration_header +configuration_section: + configuration_header _configuration_paragraphs +| configuration_paragraphs ; configuration: CONFIGURATION { check_area_a_of ("CONFIGURATION SECTION"); }; @@ -5316,15 +5326,19 @@ top_clause: /* INPUT-OUTPUT SECTION */ _input_output_section: - _input_output_header - _file_control_header - _file_control_sequence - _i_o_control +| input_output_section +; + +input_output_section: + input_output_header _file_control_header _file_control_sequence _i_o_control +| file_control_header _file_control_sequence _i_o_control +| file_control_sequence _i_o_control +| i_o_control ; input_output: INPUT_OUTPUT { check_area_a_of ("INPUT-OUTPUT SECTION"); }; -_input_output_header: -| input_output SECTION _dot +input_output_header: + input_output SECTION _dot { check_headers_present (COBC_HD_ENVIRONMENT_DIVISION, 0, 0, 0); header_check |= COBC_HD_INPUT_OUTPUT_SECTION; @@ -5334,7 +5348,10 @@ _input_output_header: /* FILE-CONTROL paragraph */ _file_control_header: -| FILE_CONTROL _dot +| file_control_header +; +file_control_header: + FILE_CONTROL _dot { check_headers_present (COBC_HD_ENVIRONMENT_DIVISION, COBC_HD_INPUT_OUTPUT_SECTION, 0, 0); @@ -5343,7 +5360,12 @@ _file_control_header: ; _file_control_sequence: -| _file_control_sequence file_control_entry +| file_control_sequence +; + +file_control_sequence: + file_control_entry +| file_control_sequence file_control_entry ; file_control_entry: @@ -6228,7 +6250,11 @@ track_limit_clause: /* I-O-CONTROL paragraph */ _i_o_control: -| i_o_control_header _i_o_control_entries +| i_o_control +; + +i_o_control: + i_o_control_header _i_o_control_entries { cobc_cs_check = 0; } @@ -13648,12 +13674,18 @@ display_window_clause: } | at_line_column | _top_or_bottom _left_or_centered_or_right TITLE _is_equal x +| modal_modeless | shadow | boxed | no_scroll_wrap | _with disp_attr ; +modal_modeless: + MODAL { /* TODO: set attribute */ } +| MODELESS +; + shadow: SHADOW { /* TODO: set attribute */ } ; diff --git a/cobc/reserved.c b/cobc/reserved.c index a9eef2dd2..344ee8cf4 100644 --- a/cobc/reserved.c +++ b/cobc/reserved.c @@ -1852,8 +1852,8 @@ static struct cobc_reserved default_reserved_words[] = { { "MEMORY", 0, 1, MEMORY, /* 85 */ 0, CB_CS_OBJECT_COMPUTER }, - { "MENU", 0, 0, MENU, /* ACU extension */ - 0, 0 /* Checkme: likely context sensitive */ + { "MENU", 0, 1, MENU, /* ACU extension */ + 0, CB_CS_GRAPHICAL_CONTROL | CB_CS_INQUIRE_MODIFY | CB_CS_USAGE /* at least for MF: undocumented C/S */ }, { "MERGE", 0, 0, MERGE, /* 2002 */ 0, 0 @@ -1879,9 +1879,15 @@ static struct cobc_reserved default_reserved_words[] = { { "MINUS", 0, 0, MINUS, /* 2002 */ 0, 0 }, + { "MODAL", 0, 1, MODAL, /* ACU extension */ + 0, CB_CS_DISPLAY | CB_CS_GRAPHICAL_CONTROL + }, { "MODE", 0, 0, MODE, /* 2002 */ 0, 0 }, + { "MODELESS", 0, 1, MODELESS, /* ACU extension */ + 0, CB_CS_DISPLAY | CB_CS_GRAPHICAL_CONTROL + }, { "MODIFY", 1, 0, MODIFY, /* ACU extension */ CB_CS_INQUIRE_MODIFY, 0 }, diff --git a/tests/testsuite.src/syn_misc.at b/tests/testsuite.src/syn_misc.at index c3c7091f7..6a4107e7d 100644 --- a/tests/testsuite.src/syn_misc.at +++ b/tests/testsuite.src/syn_misc.at @@ -2434,7 +2434,7 @@ AT_CLEANUP AT_SETUP([ACUCOBOL USAGE HANDLE]) -AT_KEYWORDS([misc acu extensions reserved CALL DESTROY]) +AT_KEYWORDS([misc acu extensions reserved CALL DESTROY WINDOW MENU THREAD]) # TODO: need a better test here # TODO: maybe add a compiler support configuration to provide better messages @@ -2456,6 +2456,7 @@ AT_DATA([prog.cob], [ 77 unused-thread handle thread. 77 mywindow usage handle of window. + 77 mymenu usage handle of menu. 77 nor-a-handle usage handle bananas. 77 neither-a-handle usage handle of apes. @@ -2500,22 +2501,23 @@ AT_DATA([prog.cob], [ ]) AT_CHECK([$COMPILE_ONLY -std=acu-strict prog.cob], [1], [], -[prog.cob:19: error: unknown HANDLE type: bananas -prog.cob:20: error: unknown HANDLE type: apes -prog.cob:21: warning: HANDLE OF control-type is not implemented +[prog.cob:18: warning: HANDLE OF MENU is not implemented +prog.cob:20: error: unknown HANDLE type: bananas +prog.cob:21: error: unknown HANDLE type: apes +prog.cob:22: warning: HANDLE OF control-type is not implemented prog.cob: in paragraph 'MAIN': -prog.cob:34: warning: THREAD is not implemented -prog.cob:36: warning: THREAD is not implemented -prog.cob:35: error: HANDLE must be either a generic or a THREAD HANDLE -prog.cob:39: error: HANDLE must be either a generic or a THREAD HANDLE -prog.cob:39: warning: STOP THREAD is replaced by STOP RUN -prog.cob:44: warning: THREAD is not implemented -prog.cob:46: warning: THREAD is not implemented -prog.cob:45: error: HANDLE must be either a generic or a THREAD HANDLE -prog.cob:51: warning: GRAPHICAL CONTROL is not implemented -prog.cob:54: error: HANDLE item not allowed here: 'neither-a-handle' -prog.cob:55: error: HANDLE item not allowed here: 'mywindow' -prog.cob:56: error: HANDLE item not allowed here: 'mydir' +prog.cob:35: warning: THREAD is not implemented +prog.cob:37: warning: THREAD is not implemented +prog.cob:36: error: HANDLE must be either a generic or a THREAD HANDLE +prog.cob:40: error: HANDLE must be either a generic or a THREAD HANDLE +prog.cob:40: warning: STOP THREAD is replaced by STOP RUN +prog.cob:45: warning: THREAD is not implemented +prog.cob:47: warning: THREAD is not implemented +prog.cob:46: error: HANDLE must be either a generic or a THREAD HANDLE +prog.cob:52: warning: GRAPHICAL CONTROL is not implemented +prog.cob:55: error: HANDLE item not allowed here: 'neither-a-handle' +prog.cob:56: error: HANDLE item not allowed here: 'mywindow' +prog.cob:57: error: HANDLE item not allowed here: 'mydir' ]) AT_CHECK([$COMPILE_ONLY -std=rm-strict prog.cob], [1], [], @@ -2523,18 +2525,19 @@ AT_CHECK([$COMPILE_ONLY -std=rm-strict prog.cob], [1], [], prog.cob:14: error: 'handle' is not defined, but is a reserved word in another dialect prog.cob:15: error: syntax error, unexpected Identifier prog.cob:17: error: 'handle' is not defined, but is a reserved word in another dialect -prog.cob:19: error: 'handle' is not defined, but is a reserved word in another dialect +prog.cob:18: error: 'handle' is not defined, but is a reserved word in another dialect prog.cob:20: error: 'handle' is not defined, but is a reserved word in another dialect prog.cob:21: error: 'handle' is not defined, but is a reserved word in another dialect +prog.cob:22: error: 'handle' is not defined, but is a reserved word in another dialect prog.cob: in paragraph 'MAIN': -prog.cob:35: error: 'handle IN mywindow' is not defined -prog.cob:34: error: invalid expression: unfinished expression -prog.cob:38: error: syntax error, unexpected END-PERFORM -prog.cob:39: error: 'thread' is not defined, but is a reserved word in another dialect -prog.cob:39: error: syntax error, unexpected Identifier -prog.cob:44: error: syntax error, unexpected Identifier, expecting THREAD -prog.cob:48: error: syntax error, unexpected END-CALL -prog.cob:51: error: syntax error, unexpected Identifier +prog.cob:36: error: 'handle IN mywindow' is not defined +prog.cob:35: error: invalid expression: unfinished expression +prog.cob:39: error: syntax error, unexpected END-PERFORM +prog.cob:40: error: 'thread' is not defined, but is a reserved word in another dialect +prog.cob:40: error: syntax error, unexpected Identifier +prog.cob:45: error: syntax error, unexpected Identifier, expecting THREAD +prog.cob:49: error: syntax error, unexpected END-CALL +prog.cob:52: error: syntax error, unexpected Identifier ]) AT_CLEANUP @@ -2590,6 +2593,8 @@ AT_DATA([prog.cob], [ FOREGROUND-COLOR 14. ACCEPT OMITTED DESTROY WINDOW-HANDLE + DISPLAY FLOATING WINDOW MODAL CENTERED TITLE IS "centered" + DISPLAY FLOATING WINDOW MODELESS RIGHT TITLE IS "correct" * STOP RUN. ]) @@ -2606,6 +2611,8 @@ prog.cob:28: warning: GRAPHICAL WINDOW is not implemented prog.cob:33: warning: GRAPHICAL WINDOW is not implemented prog.cob:38: warning: GRAPHICAL WINDOW is not implemented prog.cob:44: warning: GRAPHICAL CONTROL is not implemented +prog.cob:45: warning: GRAPHICAL WINDOW is not implemented +prog.cob:46: warning: GRAPHICAL WINDOW is not implemented ]) AT_CHECK([$COMPILE_ONLY prog.cob], [1], [], @@ -2620,6 +2627,8 @@ prog.cob:28: warning: GRAPHICAL WINDOW is not implemented prog.cob:33: warning: GRAPHICAL WINDOW is not implemented prog.cob:38: warning: GRAPHICAL WINDOW is not implemented prog.cob:44: warning: GRAPHICAL CONTROL is not implemented +prog.cob:45: warning: GRAPHICAL WINDOW is not implemented +prog.cob:46: warning: GRAPHICAL WINDOW is not implemented ]) AT_CLEANUP From ec5562cfb9f610ce72029547b68a1999aaa0322a Mon Sep 17 00:00:00 2001 From: chaat Date: Tue, 30 Jul 2024 21:58:30 +0000 Subject: [PATCH 06/51] Adjustment to support the 2023 standard for edited numeric picture strings and to fix [bugs:#935] cobc: * tree.c (cb_build_picture, valid_char_order, find_floating_insertion_str, char_to_precedence_idx) changes to support the above standard for edited numeric picture strings. Also simplified the functions by identifying the floating symbol in the cb_build_picture function and passing that information to the downstream functions. libcob: * move.c (optimized_move_display_to_edited) fixed a small bug for floating sign symbol --- cobc/ChangeLog | 14 ++ cobc/tree.c | 146 +++++++----- libcob/ChangeLog | 7 +- libcob/move.c | 10 +- tests/testsuite.src/listings.at | 65 ++---- tests/testsuite.src/run_fundamental.at | 305 +++++++++++++++++++++++++ tests/testsuite.src/syn_definition.at | 56 ++--- 7 files changed, 463 insertions(+), 140 deletions(-) diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 391f5785e..84aa483e6 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,18 @@ +2024-07-29 Chuck Haatvedt + + * tree.c (cb_build_picture): added logic to find the valid floating + symbol if one exists and pass that symbol to the downstream functions + * tree.c (valid_char_order): adjust the precedence in an ambigous + where +$9 or 9$+ to identify the condition of the $ correctly + to fix bug #935 + * tree.c (find_floating_insertion_str): generate a compile error + if an invalid symbol is found between the float symbols; this also + allows the COBOL 2023 standard to be more closely followed for + display numeric edited picture strings + * tree.c (char_to_precedence_idx): changed to check penultimate and last + symbols before the first and second symbols + 2024-07-26 Simon Sobisch * parser.y, config.def: rewrite ENVIRONMENT DIVISION parsing to allow diff --git a/cobc/tree.c b/cobc/tree.c index c4df8cdf0..5fc7c92e2 100644 --- a/cobc/tree.c +++ b/cobc/tree.c @@ -2892,69 +2892,50 @@ is_simple_insertion_char (const char c) /* Returns the first and last characters of a floating insertion string. + Returns a zero if no errors encountered or a 1 if an error is encountered. - A floating insertion string is made up of two adjacent +'s, -'s or currency - symbols to each other, optionally with simple insertion characters between them. + A floating insertion string is made up of two or more +'s, -'s or currency + symbols, optionally with simple insertion characters between them. + + Note that the non punctuation characters are '.', ',', '/', V, B , 0 + */ -static void +static int find_floating_insertion_str (const cob_pic_symbol *str, const cob_pic_symbol **first, - const cob_pic_symbol **last) + const cob_pic_symbol **last, + const unsigned char float_char) { - const cob_pic_symbol *last_non_simple_insertion = NULL; - char floating_char = ' '; - *first = NULL; - *last = NULL; + int non_punctuation_found = 0; + unsigned char non_punctuation_char; for (; str->symbol != '\0'; ++str) { - if (!*first - && (str->symbol == '+' - || str->symbol == '-' - || (current_program && (str->symbol == current_program->currency_symbol)))) { - if (last_non_simple_insertion - && last_non_simple_insertion->symbol == str->symbol) { - *first = last_non_simple_insertion; - floating_char = str->symbol; - continue; - } else if (str->times_repeated > 1) { + if (str->symbol == float_char) { + if (*first == NULL) { *first = str; - floating_char = str->symbol; - continue; + } else { + if (non_punctuation_found) { + *first = NULL; + *last = NULL; + cb_error (_("floating '%c' symbols cannot have a '%c' between them"), float_char, non_punctuation_char); + return 1; + } } + *last = str; + } else if ( *first + && str->symbol != '.' + && str->symbol != ',' + && str->symbol != 'V' + && str->symbol != 'B' + && str->symbol != '/' + && str->symbol != '0') { + non_punctuation_found = 1; + non_punctuation_char = str->symbol; } - - - if (!*first && !is_simple_insertion_char (str->symbol)) { - last_non_simple_insertion = str; - } else if (*first && !(is_simple_insertion_char (str->symbol) - || str->symbol == floating_char)) { - *last = str - 1; - break; - } - } - - if (str->symbol == '\0' && *first) { - *last = str - 1; - return; - } else if (! ( str->symbol == 'V' - || (current_program && (str->symbol == current_program->decimal_point)))) { - return; } - /* - Check whether all digits after the decimal point are also part of the - floating insertion string. If they are, set *last to the last - character in the string. - */ - ++str; - for (; str->symbol != '\0'; ++str) { - if (!(is_simple_insertion_char (str->symbol) - || str->symbol == floating_char)) { - return; - } - } - *last = str - 1; + return 0; } /* Number of character types in picture strings */ @@ -3075,10 +3056,10 @@ char_to_precedence_idx (const cob_pic_symbol *str, if (current_sym->symbol == (current_program ? current_program->currency_symbol : '$')) { if (!(first_floating_sym <= current_sym && current_sym <= last_floating_sym)) { - if (first_sym || second_sym) { - return 7; - } else if (penultimate_sym || last_sym) { + if (penultimate_sym || last_sym) { return 8; + } else if (first_sym || second_sym) { + return 7; } else { /* Fudge char type - will still result in error */ return 7; @@ -3188,7 +3169,7 @@ emit_precedence_error (const int preceding_idx, const int following_idx) } static int -valid_char_order (const cob_pic_symbol *str, const int s_char_seen) +valid_char_order (const cob_pic_symbol *str, const int s_char_seen, const unsigned char float_char) { const int precedence_table[CB_PIC_CHAR_TYPES][CB_PIC_CHAR_TYPES] = { /* @@ -3231,8 +3212,8 @@ valid_char_order (const cob_pic_symbol *str, const int s_char_seen) }; int error_emitted[CB_PIC_CHAR_TYPES][CB_PIC_CHAR_TYPES] = {{ 0 }}; int chars_seen[CB_PIC_CHAR_TYPES] = { 0 }; - const cob_pic_symbol *first_floating_sym; - const cob_pic_symbol *last_floating_sym; + const cob_pic_symbol *first_floating_sym = NULL; + const cob_pic_symbol *last_floating_sym = NULL; int before_decimal_point = 1; int idx; const cob_pic_symbol *s; @@ -3241,9 +3222,18 @@ valid_char_order (const cob_pic_symbol *str, const int s_char_seen) int j; int non_p_digits_seen = 0; int error_detected = 0; + const unsigned char currency_symbol = (current_program ? current_program->currency_symbol : '$'); chars_seen[CB_PIC_S_CHAR_TYPE] = s_char_seen; - find_floating_insertion_str (str, &first_floating_sym, &last_floating_sym); + if (float_char == 0xFF) { + cb_error (_("only one of the symbols '-' , '+' or '%c' may occur multiple times in a PICTURE string"), currency_symbol); + return 0; + } + if (float_char) { + if (find_floating_insertion_str (str, &first_floating_sym, &last_floating_sym, float_char)) { + return 0; + } + } for (s = str; s->symbol != '\0'; ++s) { /* Perform the check twice if a character is repeated, e.g. to detect 9VV. */ @@ -3254,6 +3244,9 @@ valid_char_order (const cob_pic_symbol *str, const int s_char_seen) last_floating_sym, before_decimal_point, non_p_digits_seen); + if ((idx == 8) && ((s + 1)->symbol == '9') && ((s +2)->symbol == '\0')) { + idx = 7; + } if (idx == -1) { continue; } @@ -3460,6 +3453,10 @@ cb_build_picture (const char *str) cob_u32_t v_count = 0; cob_u32_t digits = 0; cob_u32_t digits_exponent = 0; + cob_u32_t pos_count = 0; + cob_u32_t neg_count = 0; + cob_u32_t curency_count = 0; + cob_u32_t float_count = 0; #if 0 /* currently unused */ cob_u32_t real_digits = 0; #endif @@ -3471,6 +3468,7 @@ cb_build_picture (const char *str) int scale = 0; int n; unsigned char c; + unsigned char float_char; const unsigned char decimal_point = (current_program ? current_program->decimal_point : '.'); const unsigned char currency_symbol = (current_program ? current_program->currency_symbol : '$'); @@ -3504,7 +3502,7 @@ cb_build_picture (const char *str) has_parens = 0; c = *p; repeat: - /* early check for picture characters with mulitple characters */ + /* early check for picture characters with multiple characters */ if ( (c == 'C' && p[1] == 'R') || (c == 'D' && p[1] == 'B')) { p++; @@ -3748,6 +3746,10 @@ cb_build_picture (const char *str) case '+': case '-': + if (c == '+') + pos_count += n; + else + neg_count += n; category |= PIC_NUMERIC_EDITED; digits += n; if (s_edit_count == 0) { @@ -3794,6 +3796,7 @@ cb_build_picture (const char *str) default: if (c == currency_symbol) { + curency_count += n; category |= PIC_NUMERIC_EDITED; if (c_count == 0) { digits += n - 1; @@ -3858,7 +3861,28 @@ cb_build_picture (const char *str) "or at least two of the set +, - and the currency symbol")); error_detected = 1; } - if (!valid_char_order (pic_buff, s_char_seen)) { + + float_char = 0x00; + + if (pos_count > 1) { + float_char = '+'; + float_count++; + } + + if (neg_count > 1) { + float_char = '-'; + float_count++; + } + + if (curency_count > 1) { + float_char = currency_symbol; + float_count++; + } + + if (float_count > 1) + float_char = 0xFF; + + if (!valid_char_order (pic_buff, s_char_seen, float_char)) { error_detected = 1; } @@ -7321,7 +7345,7 @@ cb_build_intrinsic (cb_tree func, cb_tree args, cb_tree refmod, } return make_intrinsic (func, cbp, args, NULL, refmod, 0); - /* mulitple, numeric only arguments */ + /* multiple, numeric only arguments */ case CB_INTR_MEAN: case CB_INTR_MEDIAN: case CB_INTR_MIDRANGE: @@ -7332,7 +7356,7 @@ cb_build_intrinsic (cb_tree func, cb_tree args, cb_tree refmod, case CB_INTR_VARIANCE: return make_intrinsic (func, cbp, args, cb_int1, NULL, 0); - /* mulitple, compatible only arguments */ + /* multiple, compatible only arguments */ case CB_INTR_MAX: case CB_INTR_MIN: return make_intrinsic (func, cbp, args, cb_int1, NULL, 0); diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 98d51264e..880927535 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,10 +1,15 @@ +2024-07-29 Chuck Haatvedt + + * move.c (optimized_move_display_to_edited): fixed small bug + in logic for floating sign symbol to the right of decimal_point + or assumed decimal_point + 2024-07-13 Chuck Haatvedt * move.c (indirect_move) fixed sanitizer warnings by moving one line of code - 2024-07-11 Chuck Haatvedt * screenio.c (cob_sys_scr_dump, cob_sys_scr_restore) fixed C90 warnings diff --git a/libcob/move.c b/libcob/move.c index 095a5ea13..795ce7846 100644 --- a/libcob/move.c +++ b/libcob/move.c @@ -1148,13 +1148,13 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) sign_position = dst; dst++; break; - } else if (prev_float_char == NULL) { + } else if (prev_float_char == NULL && !have_decimal_point) { *dst = c; prev_float_char = dst; sign_position = dst; dst++; break; - } else if ((*src == '0') && (suppress_zero)) { + } else if (*src == '0' && suppress_zero && !have_decimal_point) { *prev_float_char = ' '; prev_float_char = dst; sign_position = dst; @@ -1164,7 +1164,10 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) break; } else { *dst = *src; - is_zero = suppress_zero = 0; + if (*src != '0') { + is_zero = 0; + suppress_zero = 0; + } dst++; src++; break; @@ -1194,6 +1197,7 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) break; case 'V': + have_decimal_point = 1; break; case '0': diff --git a/tests/testsuite.src/listings.at b/tests/testsuite.src/listings.at index 6d3bd16a1..3377baf85 100644 --- a/tests/testsuite.src/listings.at +++ b/tests/testsuite.src/listings.at @@ -1,4 +1,4 @@ -## Copyright (C) 2015-2023 Free Software Foundation, Inc. +## Copyright (C) 2015-2024 Free Software Foundation, Inc. ## Written by Dave Pitts, Simon Sobisch, Edward Hart ## ## This file is part of GnuCOBOL. @@ -125,7 +125,7 @@ AT_DATA([prog2.cob], [ ]) AT_CHECK([$COMPILE_LISTING0 -t- -free prog2.cob], [0], -[GnuCOBOL V.R.P prog2.cob +[GnuCOBOL V.R.P prog2.cob LINE .....................SOURCE............................................. @@ -411,7 +411,7 @@ AT_DATA([prog2.cob], [ ]) AT_CHECK([$COMPILE_LISTING0 -t- prog2.cob], [0], -[GnuCOBOL V.R.P prog2.cob +[GnuCOBOL V.R.P prog2.cob LINE PG/LN A...B............................................................ @@ -475,7 +475,7 @@ AT_DATA([prog3.cob], [ ]) AT_CHECK([$COMPILE_LISTING0 -t- prog3.cob], [0], -[GnuCOBOL V.R.P prog3.cob +[GnuCOBOL V.R.P prog3.cob LINE PG/LN A...B............................................................ @@ -568,7 +568,7 @@ SIZE TYPE LVL NAME PICTURE AT_CHECK([$COBC $FLAGS -E -o prog.i prog.cob], [0], [], []) AT_CHECK([$COMPILE_LISTING0 -t- -ftsymbols prog.i], [0], -[GnuCOBOL V.R.P prog.i +[GnuCOBOL V.R.P prog.i LINE PG/LN A...B............................................................ @@ -772,7 +772,7 @@ AT_DATA([prog1.cob], [ ]) AT_CHECK([$COMPILE_LISTING0 -t- -ftsymbols prog1.cob], [0], -[GnuCOBOL V.R.P prog1.cob +[GnuCOBOL V.R.P prog1.cob LINE PG/LN A...B............................................................ @@ -1459,7 +1459,7 @@ AT_DATA([prog.cob], [ ]) AT_DATA([prog17.lst], -[GnuCOBOL V.R.P prog.i +[GnuCOBOL V.R.P prog.i LINE PG/LN A...B............................................................ @@ -2250,7 +2250,7 @@ AT_DATA([prog2.cob], [ ]) AT_CHECK([$COMPILE_LISTING0 -t- -fno-tmessages -fno-tsource -ftsymbols prog2.cob], [0], -[GnuCOBOL V.R.P prog2.cob +[GnuCOBOL V.R.P prog2.cob SIZE TYPE LVL NAME PICTURE @@ -2284,7 +2284,7 @@ AT_DATA([prog3.cob], [ AT_CHECK([$COMPILE_LISTING0 -t prog.lst -fno-tsource -fno-tmessages -ftsymbols prog3.cob], [0], [], []) AT_DATA([prog15-1.lst], -[GnuCOBOL V.R.P prog3.cob +[GnuCOBOL V.R.P prog3.cob SIZE TYPE LVL NAME PICTURE @@ -3382,11 +3382,9 @@ error: . may only occur once in a PICTURE string 000020 03 PIC 99VV9. error: V may only occur once in a PICTURE string 000021 03 PIC +$99+. -error: a trailing +/- sign cannot follow a leading +/- sign +error: floating '+' symbols cannot have a '9' between them 000022 03 PIC $+99$-. -error: a leading +/- sign cannot follow a leading currency symbol -error: a trailing currency symbol cannot follow a leading currency symbol -error: a trailing +/- sign cannot follow a leading +/- sign +error: floating '$' symbols cannot have a '9' between them 000023 01 non-symbols. 000024 03 PIC 9K. error: invalid PICTURE character 'K' @@ -3414,9 +3412,8 @@ error: . cannot follow V 000036 03 PIC Z*. error: cannot have both Z and * in PICTURE string 000037 03 PIC +(5)--. -error: a trailing +/- sign cannot follow a floating +/- string which is before - + the decimal point -error: a trailing +/- sign may only occur once in a PICTURE string +error: only one of the symbols '-' , '+' or '$' can occur multiple times in a + + picture string 000038 03 PIC $(4)Z(9). error: a Z or * which is before the decimal point cannot follow a floating + currency symbol string which is before the decimal point @@ -3434,15 +3431,10 @@ error: A or X cannot follow . 000044 03 PIC SA. error: A or X cannot follow S 000045 03 PIC $$$B+++B---. -error: a leading +/- sign cannot follow B, 0 or / -error: a leading +/- sign cannot follow a floating currency symbol string - + which is before the decimal point -error: a leading +/- sign may only occur once in a PICTURE string -error: a trailing +/- sign cannot follow a leading +/- sign -error: a trailing +/- sign may only occur once in a PICTURE string +error: only one of the symbols '-' , '+' or '$' can occur multiple times in a + + picture string 000046 03 PIC +++9+. -error: a trailing +/- sign cannot follow a floating +/- string which is before - + the decimal point +error: floating '+' symbols cannot have a '9' between them 000047 03 PIC +9(5)CR. error: CR or DB cannot follow a leading +/- sign 000048 03 PIC -9(5)DB. @@ -3460,7 +3452,7 @@ error: 9 cannot follow CR or DB error: a floating currency symbol string which is before the decimal point + cannot follow 9 000055 03 PIC 99$B. -error: a leading currency symbol cannot follow 9 +error: B, 0 or / cannot follow a trailing currency symbol 000056 03 PIC 0$99. error: a leading currency symbol cannot follow B, 0 or / 000057 03 PIC PPPVP9. @@ -3626,10 +3618,8 @@ prog.cob:18: error: S may only occur once in a PICTURE string prog.cob:18: error: S must be at start of PICTURE string prog.cob:19: error: . may only occur once in a PICTURE string prog.cob:20: error: V may only occur once in a PICTURE string -prog.cob:21: error: a trailing +/- sign cannot follow a leading +/- sign -prog.cob:22: error: a leading +/- sign cannot follow a leading currency symbol -prog.cob:22: error: a trailing currency symbol cannot follow a leading currency symbol -prog.cob:22: error: a trailing +/- sign cannot follow a leading +/- sign +prog.cob:21: error: floating '+' symbols cannot have a '9' between them +prog.cob:22: error: floating '$' symbols cannot have a '9' between them prog.cob:24: error: invalid PICTURE character 'K' prog.cob:25: error: C must be followed by R prog.cob:26: error: D must be followed by B @@ -3642,8 +3632,7 @@ prog.cob:32: error: parentheses must contain an unsigned integer prog.cob:34: error: . cannot follow a P which is after the decimal point prog.cob:35: error: . cannot follow V prog.cob:36: error: cannot have both Z and * in PICTURE string -prog.cob:37: error: a trailing +/- sign cannot follow a floating +/- string which is before the decimal point -prog.cob:37: error: a trailing +/- sign may only occur once in a PICTURE string +prog.cob:37: error: only one of the symbols '-' , '+' or '$' may occur multiple times in a PICTURE string prog.cob:38: error: a Z or * which is before the decimal point cannot follow a floating currency symbol string which is before the decimal point prog.cob:39: error: a Z or * which is before the decimal point cannot follow a floating currency symbol string which is before the decimal point prog.cob:40: error: A or X cannot follow N @@ -3651,12 +3640,8 @@ prog.cob:41: error: N cannot follow A or X prog.cob:42: error: a Z or * which is before the decimal point cannot follow A or X prog.cob:43: error: A or X cannot follow . prog.cob:44: error: A or X cannot follow S -prog.cob:45: error: a leading +/- sign cannot follow B, 0 or / -prog.cob:45: error: a leading +/- sign cannot follow a floating currency symbol string which is before the decimal point -prog.cob:45: error: a leading +/- sign may only occur once in a PICTURE string -prog.cob:45: error: a trailing +/- sign cannot follow a leading +/- sign -prog.cob:45: error: a trailing +/- sign may only occur once in a PICTURE string -prog.cob:46: error: a trailing +/- sign cannot follow a floating +/- string which is before the decimal point +prog.cob:45: error: only one of the symbols '-' , '+' or '$' may occur multiple times in a PICTURE string +prog.cob:46: error: floating '+' symbols cannot have a '9' between them prog.cob:47: error: CR or DB cannot follow a leading +/- sign prog.cob:48: error: CR or DB cannot follow a leading +/- sign prog.cob:50: error: a leading +/- sign cannot follow B, 0 or / @@ -3664,7 +3649,7 @@ prog.cob:51: error: a leading +/- sign cannot follow 9 prog.cob:52: error: B, 0 or / cannot follow CR or DB prog.cob:53: error: 9 cannot follow CR or DB prog.cob:54: error: a floating currency symbol string which is before the decimal point cannot follow 9 -prog.cob:55: error: a leading currency symbol cannot follow 9 +prog.cob:55: error: B, 0 or / cannot follow a trailing currency symbol prog.cob:56: error: a leading currency symbol cannot follow B, 0 or / prog.cob:57: error: P must be at start or end of PICTURE string prog.cob:57: error: V cannot follow a P which is after the decimal point @@ -3678,7 +3663,7 @@ prog.cob:70: error: 'UNSEEN-CONSTANT' is not defined prog.cob:81: warning: uncommon parentheses 1 warning in compilation group -57 errors in compilation group +50 errors in compilation group ]) AT_CHECK([diff expected.lst prog.lst], [0]) @@ -5129,7 +5114,7 @@ EDITOR.cob:254: warning: ALTER is obsolete in GnuCOBOL ], [ignore]) AT_CHECK([$COMPILE_LISTING0 -Xref -T- -ftsymbols EDITOR.cob], [1], -[GnuCOBOL V.R.P EDITOR.cob +[GnuCOBOL V.R.P EDITOR.cob LINE PG/LN A...B............................................................SEQUENCE diff --git a/tests/testsuite.src/run_fundamental.at b/tests/testsuite.src/run_fundamental.at index 69d7cd99c..7d450ef6a 100644 --- a/tests/testsuite.src/run_fundamental.at +++ b/tests/testsuite.src/run_fundamental.at @@ -2125,6 +2125,311 @@ AT_CHECK([$COBCRUN_DIRECT ./prog], [0], []) AT_CLEANUP +AT_SETUP([MOVE to edited item (5)]) +AT_KEYWORDS([fundamental editing]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + *AUTHOR. CHUCK HAATVEDT + + * CHECK THE char_to_precedence_idx function in tree.c + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + + ****************************************************************** + * * + * THIS PROGRAM WILL ONLY DISPLAY MESSAGES IF THE * + * COMPILER IS GENERATING AN INCORRECT RESULT. * + * * + * IF YOU WISH TO SEE ALL THE DISPLAYS, THEN * + * COMMENT THE SOURCE-COMPUTER LINE BELOW. * + * * + ****************************************************************** + + ****************************************************************** + SOURCE-COMPUTER. IBM-PC WITH DEBUGGING MODE. + ****************************************************************** + OBJECT-COMPUTER. IBM-PC. + + DATA DIVISION. + WORKING-STORAGE SECTION. + 77 CURR00 PIC 9$DB. + 77 CURR01 PIC 9$+. + 77 CURR02 PIC 9$. + 77 CURR03 PIC $9. + 77 CURR04 PIC +$9. + 77 CURR05 PIC 090. + 77 CURR06 PIC $9,9999.99-. + 77 CURR07 PIC +$9,9999.99. + 77 CURR08 PIC +$9,9999.99,99. + 77 CURR09 PIC +$9,9999.99099. + 77 CURR10 PIC 9,9/99.99$. + 77 CURR11 PIC $,$$$$.$$+. + 77 CURR12 PIC $,$$$$.$$CR. + 77 CURR13 PIC -$,$$$$.$$. + 77 CURR14 PIC $,$$$$.$$. + 77 CURR15 PIC $,$$$$V99. + 77 CURR16 PIC $,$$$$.99. + 77 CURR17 PIC -,----V--. + 77 CURR18 PIC -,----.--. + 77 CURR19 PIC 9$-. + 77 CURR20 PIC -$9. + 77 CURR21 PIC 9$DB. + 77 CURR22 PIC 9$CR. + 77 CURR23 PIC 9,9/99.99+. + 77 N1 PIC S9(8) COMP-5 VALUE +0. + 77 PAD-1 PIC *,***.**-. + 77 PAD-2 PIC $.**. + + PROCEDURE DIVISION. + MOVE +7 TO CURR00 + D IF CURR00 NOT EQUAL '7$ ' + DISPLAY 'TEST 1 CURR00 ===>' CURR00 '<===' + D END-IF. + + MOVE +0.01 TO CURR01 + D IF CURR01 NOT EQUAL '0$+' + DISPLAY 'TEST 1 CURR01 ===>' CURR01 '<===' + D END-IF. + + MOVE +0.01 TO CURR02 + D IF CURR02 NOT EQUAL '0$' + DISPLAY 'TEST 1 CURR02 ===>' CURR02 '<===' + D END-IF. + + MOVE +0.01 TO CURR03 + D IF CURR03 NOT EQUAL '$0' + DISPLAY 'TEST 1 CURR03 ===>' CURR03 '<===' + D END-IF. + + MOVE +0.01 TO CURR04 + D IF CURR04 NOT EQUAL '+$0' + DISPLAY 'TEST 1 CURR04 ===>' CURR04 '<===' + D END-IF. + + MOVE +0.01 TO CURR05 + D IF CURR05 NOT EQUAL '000' + DISPLAY 'TEST 1 CURR05 ===>' CURR05 '<===' + D END-IF. + + MOVE +0.01 TO CURR06 + D IF CURR06 NOT EQUAL '$0,0000.01' + DISPLAY 'TEST 1 CURR06 ===>' CURR06 '<===' + D END-IF. + + MOVE +0.01 TO CURR07 + D IF CURR07 NOT EQUAL '+$0,0000.01' + DISPLAY 'TEST 1 CURR07 ===>' CURR07 '<===' + D END-IF. + + MOVE +0.01 TO CURR08 + D IF CURR08 NOT EQUAL '+$0,0000.01,00' + DISPLAY 'TEST 1 CURR08 ===>' CURR08 '<===' + D END-IF. + + MOVE +0.01 TO CURR09 + D IF CURR09 NOT EQUAL '+$0,0000.01000' + DISPLAY 'TEST 1 CURR09 ===>' CURR09 '<===' + D END-IF. + + MOVE +0.01 TO CURR10 + D IF CURR10 NOT EQUAL '0,0/00.01$' + DISPLAY 'TEST 1 CURR10 ===>' CURR10 '<===' + D END-IF. + + MOVE +0.01 TO CURR11 + D IF CURR11 NOT EQUAL ' $.01+' + DISPLAY 'TEST 1 CURR11 ===>' CURR11 '<===' + D END-IF. + + MOVE +0.01 TO CURR12 + D IF CURR12 NOT EQUAL ' $.01 ' + DISPLAY 'TEST 1 CURR12 ===>' CURR12 '<===' + D END-IF. + + MOVE +0.01 TO CURR13 + D IF CURR13 NOT EQUAL ' $.01' + DISPLAY 'TEST 1 CURR13 ===>' CURR13 '<===' + D END-IF. + + MOVE +0.01 TO CURR14 + D IF CURR14 NOT EQUAL ' $.01' + DISPLAY 'TEST 1 CURR14 ===>' CURR14 '<===' + D END-IF. + + MOVE +0.01 TO CURR15 + D IF CURR15 NOT EQUAL ' $01' + DISPLAY 'TEST 1 CURR15 ===>' CURR15 '<===' + D END-IF. + + MOVE +0.01 TO CURR16 + D IF CURR16 NOT EQUAL ' $.01' + DISPLAY 'TEST 1 CURR16 ===>' CURR16 '<===' + D END-IF. + + MOVE +0.01 TO CURR17 + D IF CURR17 NOT EQUAL ' 01' + DISPLAY 'TEST 1 CURR17 ===>' CURR17 '<===' + D END-IF. + + MOVE +0.01 TO CURR18 + D IF CURR18 NOT EQUAL ' .01' + DISPLAY 'TEST 1 CURR18 ===>' CURR18 '<===' + D END-IF. + + MOVE +0.01 TO CURR19 + D IF CURR19 NOT EQUAL '0$' + DISPLAY 'TEST 1 CURR19 ===>' CURR19 '<===' + D END-IF. + + MOVE +0.01 TO CURR20 + D IF CURR20 NOT EQUAL ' $0' + DISPLAY 'TEST 1 CURR20 ===>' CURR20 '<===' + D END-IF. + + MOVE +0.01 TO CURR21 + D IF CURR21 NOT EQUAL '0$' + DISPLAY 'TEST 1 CURR21 ===>' CURR21 '<===' + D END-IF. + + MOVE +0.01 TO CURR22 + D IF CURR22 NOT EQUAL '0$' + DISPLAY 'TEST 1 CURR22 ===>' CURR22 '<===' + D END-IF. + + MOVE +0.01 TO CURR23 + D IF CURR23 NOT EQUAL '0,0/00.01+' + DISPLAY 'TEST 1 CURR23 ===>' CURR23 '<===' + D END-IF. + + + + MOVE -987654321.987654 TO CURR01 + D IF CURR01 NOT EQUAL '1$-' + DISPLAY 'TEST 2 CURR01 ===>' CURR01 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR02 + D IF CURR02 NOT EQUAL '1$' + DISPLAY 'TEST 2 CURR02 ===>' CURR02 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR03 + D IF CURR03 NOT EQUAL '$1' + DISPLAY 'TEST 2 CURR03 ===>' CURR03 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR04 + D IF CURR04 NOT EQUAL '-$1' + DISPLAY 'TEST 2 CURR04 ===>' CURR04 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR05 + D IF CURR05 NOT EQUAL '010' + DISPLAY 'TEST 2 CURR05 ===>' CURR05 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR06 + D IF CURR06 NOT EQUAL '$5,4321.98-' + DISPLAY 'TEST 2 CURR06 ===>' CURR06 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR07 + D IF CURR07 NOT EQUAL '-$5,4321.98' + DISPLAY 'TEST 2 CURR07 ===>' CURR07 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR08 + D IF CURR08 NOT EQUAL '-$5,4321.98,76' + DISPLAY 'TEST 2 CURR08 ===>' CURR08 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR09 + D IF CURR09 NOT EQUAL '-$5,4321.98076' + DISPLAY 'TEST 2 CURR09 ===>' CURR09 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR10 + D IF CURR10 NOT EQUAL '4,3/21.98$' + DISPLAY 'TEST 2 CURR10 ===>' CURR10 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR11 + D IF CURR11 NOT EQUAL ' $4321.98-' + DISPLAY 'TEST 2 CURR11 ===>' CURR11 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR12 + D IF CURR12 NOT EQUAL ' $4321.98CR' + DISPLAY 'TEST 2 CURR12 ===>' CURR12 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR13 + D IF CURR13 NOT EQUAL '- $4321.98' + DISPLAY 'TEST 2 CURR13 ===>' CURR13 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR14 + D IF CURR14 NOT EQUAL ' $4321.98' + DISPLAY 'TEST 2 CURR14 ===>' CURR14 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR15 + D IF CURR15 NOT EQUAL ' $432198' + DISPLAY 'TEST 2 CURR15 ===>' CURR15 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR16 + D IF CURR16 NOT EQUAL ' $4321.98' + DISPLAY 'TEST 2 CURR16 ===>' CURR16 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR17 + D IF CURR17 NOT EQUAL ' -432198' + DISPLAY 'TEST 2 CURR17 ===>' CURR17 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR18 + D IF CURR18 NOT EQUAL ' -4321.98' + DISPLAY 'TEST 2 CURR18 ===>' CURR18 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR19 + D IF CURR19 NOT EQUAL '1$-' + DISPLAY 'TEST 2 CURR19 ===>' CURR19 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR20 + D IF CURR20 NOT EQUAL '-$1' + DISPLAY 'TEST 2 CURR20 ===>' CURR20 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR21 + D IF CURR21 NOT EQUAL '1$DB' + DISPLAY 'TEST 2 CURR21 ===>' CURR21 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR22 + D IF CURR22 NOT EQUAL '1$CR' + DISPLAY 'TEST 2 CURR22 ===>' CURR22 '<===' + D END-IF. + + MOVE -987654321.987654 TO CURR23 + D IF CURR23 NOT EQUAL '4,3/21.98-' + DISPLAY 'TEST 2 CURR23 ===>' CURR23 '<===' + D END-IF. + + + GOBACK. +]) + +AT_CHECK([$COMPILE -Wno-truncate prog.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], []) + +AT_CLEANUP + + AT_SETUP([MOVE to item with simple and floating insertion]) AT_KEYWORDS([fundamental edited editing]) diff --git a/tests/testsuite.src/syn_definition.at b/tests/testsuite.src/syn_definition.at index 4e7a2f590..0f0edb57d 100644 --- a/tests/testsuite.src/syn_definition.at +++ b/tests/testsuite.src/syn_definition.at @@ -1,4 +1,4 @@ -## Copyright (C) 2003-2012, 2016-2023 Free Software Foundation, Inc. +## Copyright (C) 2003-2012, 2016-2024 Free Software Foundation, Inc. ## Written by Keisuke Nishida, Roger While, Edward Hart, Simon Sobisch ## ## This file is part of GnuCOBOL. @@ -1615,10 +1615,8 @@ prog.cob:18: error: S may only occur once in a PICTURE string prog.cob:18: error: S must be at start of PICTURE string prog.cob:19: error: . may only occur once in a PICTURE string prog.cob:20: error: V may only occur once in a PICTURE string -prog.cob:21: error: a trailing +/- sign cannot follow a leading +/- sign -prog.cob:22: error: a leading +/- sign cannot follow a leading currency symbol -prog.cob:22: error: a trailing currency symbol cannot follow a leading currency symbol -prog.cob:22: error: a trailing +/- sign cannot follow a leading +/- sign +prog.cob:21: error: floating '+' symbols cannot have a '9' between them +prog.cob:22: error: floating '$' symbols cannot have a '9' between them prog.cob:24: error: invalid PICTURE character 'K' prog.cob:25: error: C must be followed by R prog.cob:26: error: D must be followed by B @@ -1631,8 +1629,7 @@ prog.cob:32: error: parentheses must contain an unsigned integer prog.cob:34: error: . cannot follow a P which is after the decimal point prog.cob:35: error: . cannot follow V prog.cob:36: error: cannot have both Z and * in PICTURE string -prog.cob:37: error: a trailing +/- sign cannot follow a floating +/- string which is before the decimal point -prog.cob:37: error: a trailing +/- sign may only occur once in a PICTURE string +prog.cob:37: error: only one of the symbols '-' , '+' or '$' may occur multiple times in a PICTURE string prog.cob:38: error: a Z or * which is before the decimal point cannot follow a floating currency symbol string which is before the decimal point prog.cob:39: error: a Z or * which is before the decimal point cannot follow a floating currency symbol string which is before the decimal point prog.cob:40: warning: handling of USAGE NATIONAL is unfinished; implementation is likely to be changed @@ -1642,12 +1639,8 @@ prog.cob:41: error: N cannot follow A or X prog.cob:42: error: a Z or * which is before the decimal point cannot follow A or X prog.cob:43: error: A or X cannot follow . prog.cob:44: error: A or X cannot follow S -prog.cob:45: error: a leading +/- sign cannot follow B, 0 or / -prog.cob:45: error: a leading +/- sign cannot follow a floating currency symbol string which is before the decimal point -prog.cob:45: error: a leading +/- sign may only occur once in a PICTURE string -prog.cob:45: error: a trailing +/- sign cannot follow a leading +/- sign -prog.cob:45: error: a trailing +/- sign may only occur once in a PICTURE string -prog.cob:46: error: a trailing +/- sign cannot follow a floating +/- string which is before the decimal point +prog.cob:45: error: only one of the symbols '-' , '+' or '$' may occur multiple times in a PICTURE string +prog.cob:46: error: floating '+' symbols cannot have a '9' between them prog.cob:47: error: CR or DB cannot follow a leading +/- sign prog.cob:48: error: CR or DB cannot follow a leading +/- sign prog.cob:50: error: a leading +/- sign cannot follow B, 0 or / @@ -1655,7 +1648,7 @@ prog.cob:51: error: a leading +/- sign cannot follow 9 prog.cob:52: error: B, 0 or / cannot follow CR or DB prog.cob:53: error: 9 cannot follow CR or DB prog.cob:54: error: a floating currency symbol string which is before the decimal point cannot follow 9 -prog.cob:55: error: a leading currency symbol cannot follow 9 +prog.cob:55: error: B, 0 or / cannot follow a trailing currency symbol prog.cob:56: error: a leading currency symbol cannot follow B, 0 or / prog.cob:57: error: P must be at start or end of PICTURE string prog.cob:57: error: V cannot follow a P which is after the decimal point @@ -1693,10 +1686,8 @@ prog.cob:18: error: S may only occur once in a PICTURE string prog.cob:18: error: S must be at start of PICTURE string prog.cob:19: error: . may only occur once in a PICTURE string prog.cob:20: error: V may only occur once in a PICTURE string -prog.cob:21: error: a trailing +/- sign cannot follow a leading +/- sign -prog.cob:22: error: a leading +/- sign cannot follow a leading currency symbol -prog.cob:22: error: a trailing currency symbol cannot follow a leading currency symbol -prog.cob:22: error: a trailing +/- sign cannot follow a leading +/- sign +prog.cob:21: error: floating '+' symbols cannot have a '9' between them +prog.cob:22: error: floating '$' symbols cannot have a '9' between them prog.cob:24: error: invalid PICTURE character 'K' prog.cob:25: error: C must be followed by R prog.cob:26: error: D must be followed by B @@ -1709,8 +1700,7 @@ prog.cob:32: error: parentheses must contain an unsigned integer prog.cob:34: error: . cannot follow a P which is after the decimal point prog.cob:35: error: . cannot follow V prog.cob:36: error: cannot have both Z and * in PICTURE string -prog.cob:37: error: a trailing +/- sign cannot follow a floating +/- string which is before the decimal point -prog.cob:37: error: a trailing +/- sign may only occur once in a PICTURE string +prog.cob:37: error: only one of the symbols '-' , '+' or '$' may occur multiple times in a PICTURE string prog.cob:38: error: a Z or * which is before the decimal point cannot follow a floating currency symbol string which is before the decimal point prog.cob:39: error: a Z or * which is before the decimal point cannot follow a floating currency symbol string which is before the decimal point prog.cob:40: warning: handling of USAGE NATIONAL is unfinished; implementation is likely to be changed @@ -1720,12 +1710,8 @@ prog.cob:41: error: N cannot follow A or X prog.cob:42: error: a Z or * which is before the decimal point cannot follow A or X prog.cob:43: error: A or X cannot follow . prog.cob:44: error: A or X cannot follow S -prog.cob:45: error: a leading +/- sign cannot follow B, 0 or / -prog.cob:45: error: a leading +/- sign cannot follow a floating currency symbol string which is before the decimal point -prog.cob:45: error: a leading +/- sign may only occur once in a PICTURE string -prog.cob:45: error: a trailing +/- sign cannot follow a leading +/- sign -prog.cob:45: error: a trailing +/- sign may only occur once in a PICTURE string -prog.cob:46: error: a trailing +/- sign cannot follow a floating +/- string which is before the decimal point +prog.cob:45: error: only one of the symbols '-' , '+' or '$' may occur multiple times in a PICTURE string +prog.cob:46: error: floating '+' symbols cannot have a '9' between them prog.cob:47: error: CR or DB cannot follow a leading +/- sign prog.cob:48: error: CR or DB cannot follow a leading +/- sign prog.cob:50: error: a leading +/- sign cannot follow B, 0 or / @@ -1733,7 +1719,7 @@ prog.cob:51: error: a leading +/- sign cannot follow 9 prog.cob:52: error: B, 0 or / cannot follow CR or DB prog.cob:53: error: 9 cannot follow CR or DB prog.cob:54: error: a floating currency symbol string which is before the decimal point cannot follow 9 -prog.cob:55: error: a leading currency symbol cannot follow 9 +prog.cob:55: error: B, 0 or / cannot follow a trailing currency symbol prog.cob:56: error: a leading currency symbol cannot follow B, 0 or / prog.cob:57: error: P must be at start or end of PICTURE string prog.cob:57: error: V cannot follow a P which is after the decimal point @@ -2092,10 +2078,10 @@ AT_DATA([prog.cob], [ 66 invalid-7 RENAMES j. 66 invalid-8 RENAMES m THRU o. 66 invalid-9 RENAMES b THRU m. - + 78 my-ext-const VALUE "123". 66 invalid-ec RENAMES my-ext-const. - + 01 my-std-const CONSTANT AS "123". 66 invalid-sc RENAMES my-std-const. @@ -2168,7 +2154,7 @@ AT_DATA([prog.cob], [ 05 FILLER PIC 9999. 05 DETAIL-NO PIC 9999. 02 FILLER SAME AS AUSGABE-FILE-NAME. - + 77 OUTPUT-NAME SAME AS DETAIL-NO GLOBAL. 01 Z-MESSAGE-T2 SAME AS AUSGABE-FILE-NAME-2. @@ -2238,7 +2224,7 @@ AT_DATA([prog.cob], [ 02 FILLER USAGE AUSGABE-FILE-NAME-T. * 01 MESSAGE-TEXT-2 EXTERNAL USAGE MESSAGE-TEXT-2T. - + 77 OUTPUT-NAME USAGE SOME-VERY-LONG-TYPEDEF-NAME GLOBAL. 01 Z-MESSAGE-T2 USAGE AUSGABE-FILE-NAME-2T. @@ -2290,7 +2276,7 @@ AT_DATA([progstd.cob], [ 02 FILLER TYPE AUSGABE-FILE-NAME-T. * 01 MESSAGE-TEXT-2 EXTERNAL TYPE MESSAGE-TEXT-2T. - + 77 OUTPUT-NAME TYPE TO DETAIL-NO-T GLOBAL. 01 Z-MESSAGE-T2 TYPE AUSGABE-FILE-NAME-2T. @@ -2587,7 +2573,7 @@ AT_DATA([prog.cob], [ 05 FILLER PIC 9999. 05 DETAIL-NO PIC 9999. 02 FILLER LIKE AUSGABE-FILE-NAME. - + 77 OUTPUT-VAL LIKE DETAIL-NO GLOBAL. 77 OUTPUT-VAL-P1 LIKE DETAIL-NO (+1). 77 OUTPUT-VAL-P1b LIKE DETAIL-NO (1). @@ -2611,7 +2597,7 @@ AT_DATA([prog.cob], [ # PROGRAM-ID. prog. # DATA DIVISION. # WORKING-STORAGE SECTION. -# +# # ]) AT_CHECK([$COMPILE_ONLY prog.cob], [0], [], []) @@ -2799,7 +2785,7 @@ AT_DATA([prog.cob], [ MOVE "Doe" TO People-LastName WRITE STCK-REC CLOSE STCK-FILE - + CALL "INNER-PROGRAM". GOBACK. From db0e8067d3e8d2b22285e726a4d3f229b68b72e9 Mon Sep 17 00:00:00 2001 From: chaat Date: Wed, 31 Jul 2024 01:01:23 +0000 Subject: [PATCH 07/51] fix small error in compile error expected results --- tests/testsuite.src/listings.at | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/testsuite.src/listings.at b/tests/testsuite.src/listings.at index 3377baf85..2a2fb68a6 100644 --- a/tests/testsuite.src/listings.at +++ b/tests/testsuite.src/listings.at @@ -3412,8 +3412,8 @@ error: . cannot follow V 000036 03 PIC Z*. error: cannot have both Z and * in PICTURE string 000037 03 PIC +(5)--. -error: only one of the symbols '-' , '+' or '$' can occur multiple times in a - + picture string +error: only one of the symbols '-' , '+' or '$' may occur multiple times in a + + PICTURE string 000038 03 PIC $(4)Z(9). error: a Z or * which is before the decimal point cannot follow a floating + currency symbol string which is before the decimal point @@ -3431,8 +3431,8 @@ error: A or X cannot follow . 000044 03 PIC SA. error: A or X cannot follow S 000045 03 PIC $$$B+++B---. -error: only one of the symbols '-' , '+' or '$' can occur multiple times in a - + picture string +error: only one of the symbols '-' , '+' or '$' may occur multiple times in a + + PICTURE string 000046 03 PIC +++9+. error: floating '+' symbols cannot have a '9' between them 000047 03 PIC +9(5)CR. From a672fbba0388d30d25ea97e19bf37608ffc12de6 Mon Sep 17 00:00:00 2001 From: David Declerck Date: Thu, 1 Aug 2024 00:30:48 +0200 Subject: [PATCH 08/51] Update MSVC & MSYS1 CI --- .github/workflows/windows-msvc.yml | 57 +++++++++++++++++------------ .github/workflows/windows-msys1.yml | 24 ++++++++++-- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index a5a9488ba..0bf82e5a4 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -154,27 +154,23 @@ jobs: run: | pacman --needed --noconfirm -S $MSYSPKGS - - name: Build testsuite + - name: Adjust testsuite shell: C:\shells\msys2bash.cmd {0} run: | cd tests - echo at_testdir=\'tests\' > atconfig - echo abs_builddir=\'$(pwd)\' >> atconfig - echo at_srcdir=\'./\' >> atconfig - echo abs_srcdir=\'$(pwd)/\' >> atconfig - echo at_top_srcdir=\'../\' >> atconfig - echo abs_top_srcdir=\'$(pwd)/../\' >> atconfig - echo at_top_build_prefix=\'../\' >> atconfig - echo abs_top_builddir=\'$(pwd)/../\' >> atconfig - echo at_top_builddir=\$at_top_build_prefix >> atconfig - echo EXEEXT=\'.exe\' >> atconfig - echo AUTOTEST_PATH=\'tests\' >> atconfig - echo SHELL=\${CONFIG_SHELL-\'/bin/sh\'} >> atconfig - echo m4_define\([AT_PACKAGE_STRING], [$GC_VERSION]\) > package.m4 - echo m4_define\([AT_PACKAGE_BUGREPORT], [bug-gnucobol@gnu.org]\) >> package.m4 - sed 's/x64\/Debug/${{ env.ARCHDIR }}\/${{ matrix.target }}/g' atlocal_win > atlocal sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + - name: Adjust testsuite for Debug target + if: ${{ matrix.target == 'Debug' }} + shell: C:\shells\msys2bash.cmd {0} + run: | + cd tests + + sed -i '/AT_SETUP(\[MF FIGURATIVE to NUMERIC\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[Default file external name\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at + sed -i '/AT_SETUP(\[EXTFH: SEQUENTIAL files\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at + sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at + sed -i '/AT_SETUP(\[MOVE to edited item (4)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at sed -i '/AT_SETUP(\[MOVE to item with simple and floating insertion\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at sed -i '/AT_SETUP(\[Numeric operations (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at @@ -189,6 +185,7 @@ jobs: sed -i '/AT_SETUP(\[OSVS Arithmetic Test (2)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at sed -i '/AT_SETUP(\[FUNCTION ACOS\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at sed -i '/AT_SETUP(\[FUNCTION ASIN\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[FUNCTION RANDOM\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at sed -i '/AT_SETUP(\[MOVE of non-integer to alphanumeric\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at sed -i '/AT_SETUP(\[XML GENERATE trimming\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_ml.at sed -i '/AT_SETUP(\[JSON GENERATE trimming\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_ml.at @@ -209,18 +206,30 @@ jobs: sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at sed -i '/AT_SETUP(\[CURRENCY SIGN WITH PICTURE SYMBOL\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[MF FIGURATIVE to NUMERIC\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[Default file external name\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at - sed -i '/AT_SETUP(\[EXTFH: SEQUENTIAL files\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at - sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at - sed -i '/AT_SETUP(\[FUNCTION RANDOM\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at +# The tests in sed commands above randomly hang (under debug configurations) + - name: Build testsuite + shell: C:\shells\msys2bash.cmd {0} + run: | + cd tests + echo at_testdir=\'tests\' > atconfig + echo abs_builddir=\'$(pwd)\' >> atconfig + echo at_srcdir=\'./\' >> atconfig + echo abs_srcdir=\'$(pwd)/\' >> atconfig + echo at_top_srcdir=\'../\' >> atconfig + echo abs_top_srcdir=\'$(pwd)/../\' >> atconfig + echo at_top_build_prefix=\'../\' >> atconfig + echo abs_top_builddir=\'$(pwd)/../\' >> atconfig + echo at_top_builddir=\$at_top_build_prefix >> atconfig + echo EXEEXT=\'.exe\' >> atconfig + echo AUTOTEST_PATH=\'tests\' >> atconfig + echo SHELL=\${CONFIG_SHELL-\'/bin/sh\'} >> atconfig + echo m4_define\([AT_PACKAGE_STRING], [$GC_VERSION]\) > package.m4 + echo m4_define\([AT_PACKAGE_BUGREPORT], [bug-gnucobol@gnu.org]\) >> package.m4 + sed 's/x64\/Debug/${{ env.ARCHDIR }}\/${{ matrix.target }}/g' atlocal_win > atlocal autom4te --lang=autotest -I ./testsuite.src ./testsuite.at -o ./testsuite -# The tests in sed commands above randomly hang (under debug configurations) - - name: Run testsuite - continue-on-error: true run: | cd tests set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" diff --git a/.github/workflows/windows-msys1.yml b/.github/workflows/windows-msys1.yml index 1233bedc8..2fa32a692 100644 --- a/.github/workflows/windows-msys1.yml +++ b/.github/workflows/windows-msys1.yml @@ -173,7 +173,7 @@ jobs: sed -i 'N;s/else/else :;/g' .\configure sed -i 's/\} else \:;/} else/g' .\configure sed -i 's/#else \:;/#else/g' .\configure - bash -lc "cd _build && ../configure %CFGOPT% --with-db --prefix=/opt/cobol/gnucobol" + bash -lc "cd _build && CFLAGS=\"-I ../libcob\" ../configure %CFGOPT% --with-db --prefix=/opt/cobol/gnucobol" - name: Upload config-${{ matrix.target }}.log uses: actions/upload-artifact@v4 @@ -200,9 +200,27 @@ jobs: path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log - name: Run testsuite - continue-on-error: true run: | - sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' .\tests\testsuite.src\used_binaries.at + sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/used_binaries.at + + sed -i '/AT_SETUP(\[Compare FLOAT-LONG with floating-point literal\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[Numeric operations (3) PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[Numeric operations (7)\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[integer arithmetic on floating-point var\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at + sed -i '/AT_SETUP(\[FLOAT-DECIMAL w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[FLOAT-SHORT \/ FLOAT-LONG w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[FLOAT-LONG with SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at + sed -i '/AT_SETUP(\[FUNCTION ANNUITY\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[FUNCTION INTEGER\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[FUNCTION MOD (valid)\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[FUNCTION SECONDS-FROM-FORMATTED-TIME\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at + sed -i '/AT_SETUP(\[GCOS floating-point usages\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_extensions.at + sed -i '/AT_SETUP(\[BINARY: 64bit unsigned arithmetic notrunc\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_binary.at + sed -i '/AT_SETUP(\[DISPLAY: ADD and SUBTRACT w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_display.at + sed -i '/AT_SETUP(\[DISPLAY: ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_display.at + sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_packed.at + sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_packed.at + bash -lc "cd _build/tests && CPATH=/opt/cobol/gnucobol/include make check TESTSUITEFLAGS=\"--jobs=$(($(nproc)+1))\"" # Note: the extra CPATH above is only required in debug builds, for some reason... From 1b01ffd2398e226e005382850e71d6708eb11f27 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Sat, 3 Aug 2024 21:04:02 +0000 Subject: [PATCH 09/51] Testuite fixes for MSVC * testsuite.src/run_file.at, testsuite.src/run_misc.at: fix a few tests that break under MSVC Debug while working under MSVC Release, by forcing a flush of stdout with fflush and using cob_free instead of free in C codes --- tests/ChangeLog | 7 +++++++ tests/testsuite.src/run_file.at | 4 +++- tests/testsuite.src/run_misc.at | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/ChangeLog b/tests/ChangeLog index 94eb7191a..6c28dd67f 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,4 +1,11 @@ +2024-08-03 David Declerck + + * testsuite.src/run_file.at, testsuite.src/run_misc.at: + fix a few tests that break under MSVC Debug while working + under MSVC Release, by forcing a flush of stdout with + fflush and using cob_free instead of free in C codes + 2024-06-19 David Declerck * atlocal_win: fix path-related issues in Windows builds diff --git a/tests/testsuite.src/run_file.at b/tests/testsuite.src/run_file.at index 2fc93cadf..11a491571 100644 --- a/tests/testsuite.src/run_file.at +++ b/tests/testsuite.src/run_file.at @@ -4297,7 +4297,7 @@ fexists_signed (char *fid, char *signature, int signature_size) res = 0; } } - free (bfr); + cob_free (bfr); } return res; } @@ -9040,6 +9040,7 @@ doOpenFile( printf("EXFTH did %s; Status=%c%c; File now %s\n", opmsg, fcd->fileStatus[0], fcd->fileStatus[1], (fcd->openMode & OPEN_NOT_OPEN) ? "Closed" : "Open"); + fflush(stdout); return sts; } @@ -9094,6 +9095,7 @@ TSTFH (unsigned char *opCodep, FCD3 *fcd) sts = EXTFH(opCodep, fcd); printf("EXFTH did %s; Status=%c%c\n", txtOpCode(opCode), fcd->fileStatus[0], fcd->fileStatus[1]); + fflush(stdout); return sts; } diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 879667ffe..7ec0062f0 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -7486,6 +7486,7 @@ dump (unsigned char *data) for (i = 0; i < 4; i++) printf ("%02X", data[i]); puts (" ."); + fflush(stdout); return 0; } ]]) From fabaca953a23f9ebbdd790acec65190de03e4b48 Mon Sep 17 00:00:00 2001 From: Simon Sobisch Date: Wed, 7 Aug 2024 07:23:16 +0200 Subject: [PATCH 10/51] Update .gitignore --- .gitignore | 115 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 8e2ee8661..3e7f833e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,99 @@ -*~ +# Exclude generated translations +/po/en@boldquot.po +/po/en@quot.po +/po/*.gmo +/po/POTFILES + +# Exclude autoconf/automake parts +/aclocal.m4 +/aminclude_static.am +/conf*.dir +/conf*.file +/confdefs.h +/conftest* +/config.* +/configure +/libtool +/stamp-h1 +/tarstamp.h +/build_aux/ar-lib + +Makefile.in +Makefile +.* + +# generated releases +/*.7z +/*.bz2 +/*.gz +/*.lz +/*.sig +/*.xz +/*.zip +/*mingw* +/*dist* +/gnucobol-* + +# several temporary/tool generated files *.la -.libs *.lo *.o *.so +*.obj +*.dll +*.lib +*.exe -.deps -Makefile.in +*cache* +*-coverage +*.bak +*.gcda +*.gcno +*.diff +*.patch +*.tmp +*~ +* - * +_* +cscope.* +TAGS -/aclocal.m4 -/aminclude_static.am -/autom4te.cache +/build_windows/ia64 +/build_windows/Win32 +/build_windows/x64 +/build_windows/config.h +ipch +*.db +.vs +*.aps +*.bak +*.ncb +*.*sdf +*.suo +*.user + +/build +/build.* +/build-* +/compile_commands.json + +# generated files /bin/cob-config /bin/cob-config.1 /bin/cobcrun /bin/cobcrun.1 /bin/cobfile /bin/gcdiff -/_build /cobc/cobc /cobc/cobc.1 /cobc/parser.c /cobc/parser.h -/cobc/parser.output +/cobc/*.output /cobc/pplex.c /cobc/ppparse.c /cobc/ppparse.h /cobc/scanner.c -/config.h -/config.h.in -/config.log -/config.status -/configure + /doc/cbchelp.tex /doc/cbconf.tex /doc/cbexceptions.tex @@ -44,27 +106,25 @@ Makefile.in /doc/gnucobol.info /doc/stamp-vti /doc/version.texi -/libtool -/Makefile -/po/en@boldquot.po -/po/en@quot.po -/po/*.gmo -/po/POTFILES + /pre-inst-env -/stamp-h1 -/tarstamp.h /tests/atconfig /tests/atlocal /tests/cobol85/copy/ /tests/cobol85/copyalt/ /tests/cobol85/DB/ +/tests/cobol85/DBNOIX/ /tests/cobol85/EXEC85 -/tests/cobol85/EXEC85.cob +/tests/cobol85/EXEC85.c.* +/tests/cobol85/EXEC85.i +/tests/cobol85/EXEC85.lst +/tests/cobol85/EXEC85.o* +/tests/cobol85/EXEC85.exe /tests/cobol85/IC/ /tests/cobol85/IF/ /tests/cobol85/IX/ /tests/cobol85/NC/ -/tests/cobol85/newcob.val +/tests/cobol85/newcob.val* /tests/cobol85/OB/ /tests/cobol85/RL/ /tests/cobol85/RW/ @@ -72,11 +132,10 @@ Makefile.in /tests/cobol85/SM/ /tests/cobol85/SQ/ /tests/cobol85/ST/ -/tests/cobol85/summary.log +/tests/cobol85/*.log /tests/package.m4 /tests/run_prog_manual.sh /tests/testsuite -/tests/testsuite.dir/ -/tests/testsuite.log /tests/testsuite_manual -/build_aux/ar-lib +/tests/testsuite*.dir/ +/tests/testsuite*.log From 71ea358aa9101faa5f2c3732d763e59934aacc94 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Sat, 10 Aug 2024 15:18:40 +0000 Subject: [PATCH 11/51] work on ALPHABET definitions, especially ALPHABET FOR NATIONAL cobc: * typeck.c (validate_alphabet), tree.h (cb_alphabet_name): cater for national alphabets with increased size (max. 65535 instead of 255) * typeck.c (validate_alphabet): check that alphabet and literal types match * codegen.c (output_alphabet_name_definition): cater for national alphabet * typeck.c (validate_alphabet): speedup for alphabet checks * pplex.l (ppopen_get_file): explicit check for UTF16/UTF32 and hint to use iconv additional, in preparation of character encoding support: * configure.ac: new option --with-iconv * DEPENDENCIES, NEWS: document usage of libiconv --- ChangeLog | 8 + DEPENDENCIES | 13 ++ DEPENDENCIES.md | 14 +- NEWS | 4 + cobc/ChangeLog | 18 ++ cobc/cobc.c | 17 +- cobc/codegen.c | 36 ++-- cobc/pplex.l | 32 +++- cobc/tree.h | 8 +- cobc/typeck.c | 229 ++++++++++++++++---------- configure.ac | 44 +++-- tests/testsuite.src/run_ml.at | 2 +- tests/testsuite.src/syn_definition.at | 42 ++++- 13 files changed, 334 insertions(+), 133 deletions(-) diff --git a/ChangeLog b/ChangeLog index c640f812c..a54a08fae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ +2024-08-10 Simon Sobisch + + * DEPENDENCIES, NEWS: document usage of libiconv + +2024-08-06 Simon Sobisch + + * configure.ac: new option --with-iconv + 2024-05-14 David Declerck * configure.ac: update flags for building dynamic libraries on macOS diff --git a/DEPENDENCIES b/DEPENDENCIES index 2a1bde415..f0d54169b 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -137,6 +137,19 @@ The following libraries ARE required WHEN : JSON-C is distributed under Expat License. +5) charachter encoding support is needed and iconv is not provided + as part of libc + + BOTH runtime AND development components required. + + libiconv - https://www.gnu.org/software/libiconv/ + + GNU libiconv is distributed under GNU Lesser General Public License. + + Note: Support for partial character encoding is provided directly, + full support for national and utf8 literals and data, as well as + utf8 source encoding needs an implementation of the iconv API. + See HACKING if you wish to hack the GnuCOBOL source or build directly from version control as this includes the list of additional tools diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 266459ff7..289265bf5 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -102,7 +102,7 @@ XML Support Support for GENERATE XML is provided by: -* [libxml2](http://xmlsoft.org) +* [libxml2](https://xmlsoft.org) libxml2 is distributed under MIT License. @@ -119,3 +119,15 @@ Support for GENERATE JSON is provided by *one* of the following: JSON-C is distributed under Expat License. + +charachter encoding support +---------------------------- + +Support for partial character encoding is provided directly, +full support for national and utf8 literals and data, as well as +utf8 source encoding needs an implementation of the iconv API. +If this is not provided by libc, it is provided by: + +* [libiconv](https://www.gnu.org/software/libiconv/) + + GNU libiconv is distributed under GNU Lesser General Public License. diff --git a/NEWS b/NEWS index 97f62186c..d6f861455 100644 --- a/NEWS +++ b/NEWS @@ -76,6 +76,10 @@ NEWS - user visible changes -*- outline -*- ** configure now uses pkg-config/ncurses-config to search for ncurses and honors NCURSES_LIBS and NCURSES_CFLAGS +** configure now checks for iconv and accepts --with-iconv/--without-iconv; + this is used for character encoding support, which otherwise is only provided + partially + ** use the "default" -shared flag to build dynamic libraries on macOS so as to fix testuite issues with recent macOS versions diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 84aa483e6..4da9dad05 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,17 @@ +2024-08-06 Simon Sobisch + + * codegen.c (output_alphabet_name_definition): cater for national alphabet + * typeck.c (validate_alphabet): speedup for alphabet checks + * pplex.l (ppopen_get_file): explicit check for UTF16/UTF32 and + hint to use iconv + +2024-08-05 Simon Sobisch + + * typeck.c (validate_alphabet), tree.h (cb_alphabet_name): cater for + national alphabets with increased size (max. 65535 instead of 255) + * typeck.c (validate_alphabet): check that alphabet and literal types match + 2024-07-29 Chuck Haatvedt * tree.c (cb_build_picture): added logic to find the valid floating @@ -33,6 +46,11 @@ * tree.c (cb_build_picture): fixed currency digit counting logic +2024-05-16 David Declerck + + * cobc.c (process_compile)[_MSC_VER]: adjustment for compile + from assembler source + 2024-05-15 Simon Sobisch * replace.c: fix compile warnings and formatting diff --git a/cobc/cobc.c b/cobc/cobc.c index 98f05baa0..f44c62f75 100644 --- a/cobc/cobc.c +++ b/cobc/cobc.c @@ -2153,7 +2153,7 @@ cobc_check_action (const char *name) char temp_buff[COB_MEDIUM_BUFF]; snprintf (temp_buff, (size_t)COB_MEDIUM_MAX, - "%s%s%s", save_temps_dir, SLASH_STR, name); + "%s%c%s", save_temps_dir, SLASH_CHAR, name); temp_buff[COB_MEDIUM_MAX] = 0; /* Remove possible target file - ignore return */ (void)unlink (temp_buff); @@ -2186,9 +2186,9 @@ clean_up_intermediates (struct filename *fn, const int status) } if (fn->need_preprocess && (status - || cb_compile_level > CB_LEVEL_PREPROCESS - || (cb_compile_level == CB_LEVEL_PREPROCESS - && save_temps && !save_temps_dir))) { + || cb_compile_level > CB_LEVEL_PREPROCESS + || (cb_compile_level == CB_LEVEL_PREPROCESS + && save_temps && !save_temps_dir))) { cobc_check_action (fn->preprocess); } /* CHECKME: we had reports of unexpected intermediate @@ -2200,8 +2200,8 @@ clean_up_intermediates (struct filename *fn, const int status) if (fn->need_translate && (status - || cb_compile_level > CB_LEVEL_TRANSLATE - || (cb_compile_level == CB_LEVEL_TRANSLATE && save_temps))) { + || cb_compile_level > CB_LEVEL_TRANSLATE + || (cb_compile_level == CB_LEVEL_TRANSLATE && save_temps))) { cobc_check_action (fn->translate); cobc_check_action (fn->trstorage); if (fn->localfile) { @@ -8181,7 +8181,6 @@ process_translate (struct filename *fn) } /* Create single-element assembly source */ - static int process_compile (struct filename *fn) { @@ -8241,7 +8240,6 @@ process_compile (struct filename *fn) } /* Create single-element assembled object */ - static int process_assemble (struct filename *fn) { @@ -8443,7 +8441,6 @@ process_module_direct (struct filename *fn) } /* Create single-element loadable object */ - static int process_module (struct filename *fn) { @@ -8541,7 +8538,6 @@ process_module (struct filename *fn) } /* Create multi-element loadable object */ - static int process_library (struct filename *l) { @@ -8660,7 +8656,6 @@ process_library (struct filename *l) } /* Create executable */ - static int process_link (struct filename *l) { diff --git a/cobc/codegen.c b/cobc/codegen.c index 011f6be40..298917312 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -10711,6 +10711,11 @@ output_report_init (struct cb_report *rep) static void output_alphabet_name_definition (struct cb_alphabet_name *p) { + const int is_national_alphabet = p->alphabet_target == CB_ALPHABET_NATIONAL; + const int maxchar = is_national_alphabet + ? COB_MAX_CHAR_NATIONAL : COB_MAX_CHAR_ALPHANUMERIC; + const int size = is_national_alphabet + ? (COB_MAX_CHAR_NATIONAL + 1) * COB_NATIONAL_SIZE : COB_MAX_CHAR_ALPHANUMERIC + 1; int i; if (p->alphabet_type != CB_ALPHABET_CUSTOM) { @@ -10718,22 +10723,33 @@ output_alphabet_name_definition (struct cb_alphabet_name *p) } /* Output the table */ - output_local ("static const unsigned char %s%s[256] = {\n", - CB_PREFIX_SEQUENCE, p->cname); - for (i = 0; i < 256; i++) { - if (i == 255) { - output_local (" %d", p->values[i]); + output_local ("static const unsigned char %s%s[%d] = {\n", + CB_PREFIX_SEQUENCE, p->cname, size); + i = 0; + for (i = 0; ; i++) { + if (is_national_alphabet) { + /* FIXME: this isn't tested at all and likely needs + adjustments in the runtime */ + output_local (" 0x%02x, 0x%02x", + (p->values[i] >> 8) & 0xFF, p->values[i] & 0xFF); } else { - output_local (" %d,", p->values[i]); + output_local (" %d", p->values[i]); + } + if (i == maxchar) { + output_local ("};\n"); + break; } if (i % 16 == 15) { - output_local ("\n"); + output_local (",\n"); + } else { + output_local (","); } } - output_local ("};\n"); - i = lookup_attr (COB_TYPE_ALPHANUMERIC, 0, 0, 0, NULL, 0); - output_local ("static cob_field %s%s = { 256, (cob_u8_ptr)%s%s, &%s%d };\n", + i = lookup_attr (is_national_alphabet ? COB_TYPE_NATIONAL : COB_TYPE_ALPHANUMERIC, + 0, 0, 0, NULL, 0); + output_local ("static cob_field %s%s = { %d, (cob_u8_ptr)%s%s, &%s%d };\n", CB_PREFIX_FIELD, p->cname, + size, CB_PREFIX_SEQUENCE, p->cname, CB_PREFIX_ATTR, i); output_local ("\n"); diff --git a/cobc/pplex.l b/cobc/pplex.l index 02bb2640c..0b7105efb 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -1251,8 +1251,8 @@ is_fixed_indicator (char c){ } } -/* open file with the specified 'name', then check for BOM (skipped) and if - in reference-format "auto" also for "likely free-format" */ +/* open file with the specified 'name', then check for BOM (utf-8 skipped, utf16/32 errored) + and if in reference-format "auto" also for "likely free-format" */ static FILE * ppopen_get_file (const char *name) { @@ -1316,6 +1316,32 @@ ppopen_get_file (const char *name) } else /* check for binary */ if (nread > 5) { + const char *enc = NULL; + if (buffer[0] == 0xFF && buffer[1] == 0xFE) { + if (buffer[2] == 0x00 && buffer[3] == 0x00) { + enc = "UTF-32LE"; + } else { + enc = "UTF-16LE"; + } + } else if (buffer[0] == 0xFE && buffer[1] == 0xFF) { + enc = "UTF-16BE"; + } else if (buffer[0] == 0x00 && buffer[1] == 0x00 + && buffer[2] == 0xFE && buffer[3] == 0xFF) { + enc = "UTF-32BE"; + } + if (enc) { + /* unsupported encoding */ + fclose (ppin); + ppin = NULL; + cb_note (COB_WARNOPT_NONE, 0, _("try \"iconv -f %s -t UTF-8 '%s' -o 'out%c%s'"), + enc, name, SLASH_CHAR, name); + if (cb_source_line == 0) { + /* if this is a "main" source, terminate with an error */ + cobc_terminate_exit (name, _("source file has unsupported encoding")); + } + cb_error ("%s: %s", name, _("source file has unsupported encoding")); + return 0; + } #if 0 if ((buffer[0] == 0x7F && buffer[1] == 0x45 && buffer[2] == 0x4C && buffer[3] == 0x46 && (buffer[4] & 0xF0) == 0x00 /* ELF */) @@ -2297,7 +2323,7 @@ start: if (buff[n - 1] != '\n') { /* FIXME: cb_source_line is one too low when CB_FORMAT_FREE is used [but only during ppinput() in pplex.l ?] - Workaround for now: Temporary newline_count + 1 + Workaround for now: temporary newline_count + 1 */ if (source_format == CB_FORMAT_FREE) { if (line_overflow == 0) { diff --git a/cobc/tree.h b/cobc/tree.h index f69f88c2a..19878838f 100644 --- a/cobc/tree.h +++ b/cobc/tree.h @@ -686,6 +686,10 @@ struct cb_string { #define CB_STRING(x) (CB_TREE_CAST (CB_TAG_STRING, struct cb_string, x)) #define CB_STRING_P(x) (CB_TREE_TAG (x) == CB_TAG_STRING) + +#define COB_MAX_CHAR_ALPHANUMERIC (unsigned int)(0xFF) +#define COB_MAX_CHAR_NATIONAL (unsigned int)(0xFFFF) + /* Alphabet-name */ struct cb_alphabet_name { @@ -697,8 +701,8 @@ struct cb_alphabet_name { enum cb_alphabet_type alphabet_type; /* ALPHABET type */ int low_val_char; /* LOW-VALUE */ int high_val_char; /* HIGH-VALUE */ - int values[256]; /* Collating values */ - int alphachr[256]; /* Actual values */ + int *values; /* Collating values */ + int *alphachr; /* Actual values */ }; #define CB_ALPHABET_NAME(x) (CB_TREE_CAST (CB_TAG_ALPHABET_NAME, struct cb_alphabet_name, x)) diff --git a/cobc/typeck.c b/cobc/typeck.c index 3a086add4..c484550aa 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -3828,46 +3828,76 @@ cb_validate_collating (cb_tree collating_sequence) return 0; } +static int alphabet_valid; + +static int +is_alphabet_matching_literal_type (cb_tree x, int is_national_alphabet) +{ + if ((is_national_alphabet && x->category != CB_CATEGORY_NATIONAL) + || (!is_national_alphabet && x->category == CB_CATEGORY_NATIONAL)) { + if (alphabet_valid) { + const char *type = is_national_alphabet ? "national" : "alphanumeric"; + cb_error_x (x, + _("only literals of type %s allowed for %s alphabet"), + type, type); + alphabet_valid = 0; + } + return 0; + } + return 1; +} + static void validate_alphabet (cb_tree alphabet) { + register unsigned int n; struct cb_alphabet_name *ap = CB_ALPHABET_NAME (alphabet); - unsigned int n; + const int is_national_alphabet = ap->alphabet_target == CB_ALPHABET_NATIONAL; + const int maxchar = is_national_alphabet + ? COB_MAX_CHAR_NATIONAL : COB_MAX_CHAR_ALPHANUMERIC; + const int memsize = (maxchar + 1) * sizeof(int); + + ap->values = cobc_parse_malloc (memsize); + ap->alphachr = cobc_parse_malloc (memsize); /* Native */ if (ap->alphabet_type == CB_ALPHABET_NATIVE) { - for (n = 0; n < 256; n++) { - ap->values[n] = n; - ap->alphachr[n] = n; + register int *entry = ap->values; + for (n = 0; n < COB_MAX_CHAR_ALPHANUMERIC + 1; n++) { + *entry = n; + entry++; } return; } /* ASCII */ if (ap->alphabet_type == CB_ALPHABET_ASCII) { - for (n = 0; n < 256; n++) { + register int *entry = ap->values; + for (n = 0; n < COB_MAX_CHAR_ALPHANUMERIC + 1; n++) { #ifdef COB_EBCDIC_MACHINE - ap->values[n] = (int)cob_refer_ascii[n]; - ap->alphachr[n] = (int)cob_refer_ascii[n]; + *entry = (int)cob_refer_ascii[n]; #else - ap->values[n] = n; - ap->alphachr[n] = n; + *entry = n; #endif + entry++; } + memcpy (ap->alphachr, ap->values, memsize); return; } /* EBCDIC */ if (ap->alphabet_type == CB_ALPHABET_EBCDIC) { - for (n = 0; n < 256; n++) { + register int *entry = ap->values; + for (n = 0; n < COB_MAX_CHAR_ALPHANUMERIC + 1; n++) { #ifdef COB_EBCDIC_MACHINE - ap->values[n] = n; - ap->alphachr[n] = n; + *entry = n; #else - ap->values[n] = (int)cob_refer_ebcdic[n]; - ap->alphachr[n] = (int)cob_refer_ebcdic[n]; + *entry = (int)cob_refer_ebcdic[n]; #endif + entry++; } + + memcpy (ap->alphachr, ap->values, memsize); return; } @@ -3879,42 +3909,46 @@ validate_alphabet (cb_tree alphabet) int lastval = 0, tableval = 0; int pos = 0; int i; - int values[256]; - int charvals[256]; - int dupvals[256]; + int *values = malloc (memsize); + int *charvals = malloc (memsize); + int *dupvals = malloc (memsize); + + memset (values, -1, memsize); + memcpy (charvals, values, memsize); + memcpy (dupvals, values, memsize); + + memcpy (ap->values, values, memsize); + memcpy (ap->alphachr, values, memsize); - for (n = 0; n < 256; n++) { - values[n] = -1; - charvals[n] = -1; - dupvals[n] = -1; - ap->values[n] = -1; - ap->alphachr[n] = -1; - } ap->low_val_char = 0; - ap->high_val_char = 255; + ap->high_val_char = maxchar; + + alphabet_valid = 1; + for (l = ap->custom_list; l; l = CB_CHAIN (l)) { x = CB_VALUE (l); pos++; - if (count > 255 + if (count > maxchar || x == NULL) { unvals = pos; break; } if (CB_PAIR_P (x)) { /* X THRU Y */ - int lower = get_value (CB_PAIR_X (x)); - int upper = get_value (CB_PAIR_Y (x)); + cb_tree X = CB_PAIR_X (x); + cb_tree Y = CB_PAIR_Y (x); + int lower = get_value (X); + int upper = get_value (Y); + if (!is_alphabet_matching_literal_type (X, is_national_alphabet) + || !is_alphabet_matching_literal_type (Y, is_national_alphabet)) { + continue; + } + lastval = upper; if (!count) { ap->low_val_char = lower; } - /* regression in NATIONAL literals as - thpose are unfinished; would be fine - with national alphabet in general */ - if (lower < 0 || lower > 255) { - unvals = pos; - continue; - } - if (upper < 0 || upper > 255) { + if ((lower < 0 || lower > maxchar) + || (upper < 0 || upper > maxchar)) { unvals = pos; continue; } @@ -3944,23 +3978,28 @@ validate_alphabet (cb_tree alphabet) } } } else if (CB_LIST_P (x)) { /* X ALSO Y ... */ - cb_tree ls; + cb_tree ls; + cb_tree X = CB_VALUE (x); + if (!is_alphabet_matching_literal_type (X, is_national_alphabet)) { + continue; + } if (!count) { - ap->low_val_char = get_value (CB_VALUE (x)); + ap->low_val_char = get_value (X); } for (ls = x; ls; ls = CB_CHAIN (ls)) { - int val = get_value (CB_VALUE (ls)); + X = CB_VALUE (ls); + if (!is_alphabet_matching_literal_type (X, is_national_alphabet)) { + continue; + } + int val = get_value (X); if (!CB_CHAIN (ls)) { lastval = val; } - /* regression in NATIONAL literals as - those are unfinished; would be fine - with national alphabet in general */ - if (val < 0 || val > 255) { + if (val < 0 || val > maxchar) { unvals = pos; continue; } - n = (unsigned char)val; + n = val; if (values[n] != -1) { dupvals[n] = n; dupls = 1; @@ -3979,11 +4018,11 @@ validate_alphabet (cb_tree alphabet) if (!count) { ap->low_val_char = lastval; } - if (lastval < 0 || lastval > 255) { + if (lastval < 0 || lastval > maxchar) { unvals = pos; continue; } - n = (unsigned char)lastval; + n = lastval; if (values[n] != -1) { dupvals[n] = n; dupls = 1; @@ -3993,14 +4032,16 @@ validate_alphabet (cb_tree alphabet) ap->alphachr[tableval] = n; ap->values[n] = tableval++; count++; - } else if (CB_LITERAL_P (x)) { /* Non-numeric Literal */ + } else if (CB_LITERAL_P (x)) { /* Non-numeric Literal (single or sequence) */ int size = (int)CB_LITERAL (x)->size; unsigned char *data = CB_LITERAL (x)->data; - if (!count) { - ap->low_val_char = data[0]; + if (!is_alphabet_matching_literal_type (x, is_national_alphabet)) { + continue; } - lastval = data[size - 1]; if (CB_TREE_CATEGORY (x) != CB_CATEGORY_NATIONAL) { + if (!count) { + ap->low_val_char = data[0]; + } for (i = 0; i < size; i++) { n = data[i]; if (values[n] != -1) { @@ -4018,10 +4059,10 @@ validate_alphabet (cb_tree alphabet) /* assuming we have UTF16BE here */ if (data[i] == 0) { /* only checking lower entries, all others, - which are currently only possible with - national-hex literals are not checked - TODO: add a list of values for those and - iterate over the list */ + which are currently only possible with + national-hex literals are not checked + TODO: add a list of values for those and + iterate over the list */ n = data[++i]; if (values[n] != -1) { dupvals[n] = n; @@ -4035,19 +4076,23 @@ validate_alphabet (cb_tree alphabet) n = n * 255 + data[i]; } ap->alphachr[tableval++] = n; + if (!count) { + ap->low_val_char = n; + } count++; } } + lastval = n; } else { /* CHECKME and doc here */ lastval = get_value (x); if (!count) { ap->low_val_char = lastval; } - if (lastval < 0 || lastval > 255) { + if (lastval < 0 || lastval > maxchar) { unvals = pos; continue; } - n = (unsigned char) lastval; + n = lastval; if (values[n] != -1) { dupls = 1; } @@ -4060,29 +4105,30 @@ validate_alphabet (cb_tree alphabet) } if (dupls || unvals) { if (dupls) { - /* FIXME: can't handle UTF8 / NATIONAL values */ - char dup_vals[256]; + char dup_val_str[256]; i = 0; for (n = 0; n < 256; n++) { if (dupvals[n] != -1) { if (i > 240) { - i += sprintf (dup_vals + i, ", ..."); + i += sprintf (dup_val_str + i, ", ..."); break; } if (i) { - i += sprintf (dup_vals + i, ", "); + i += sprintf (dup_val_str + i, ", "); } - if (isprint (n)) { - dup_vals[i++] = (char)n; + if (n > COB_MAX_CHAR_ALPHANUMERIC) { + i += sprintf (dup_val_str + i, "x'%04x'", n); + } else if (isprint (n)) { + dup_val_str[i++] = (char)n; } else { - i += sprintf (dup_vals + i, "x'%02x'", n); + i += sprintf (dup_val_str + i, "x'%02x'", n); } }; } - dup_vals[i] = 0; + dup_val_str[i] = 0; cb_error_x (alphabet, _("duplicate character values in alphabet '%s': %s"), - ap->name, dup_vals); + ap->name, dup_val_str); } if (unvals) { cb_error_x (alphabet, @@ -4091,18 +4137,18 @@ validate_alphabet (cb_tree alphabet) } ap->low_val_char = 0; ap->high_val_char = 255; - return; + goto val_ex; } /* Calculate HIGH-VALUE */ /* If all 256 values have been specified, */ /* HIGH-VALUE is the last one */ /* Otherwise if HIGH-VALUE has been specified, find the highest */ /* value that has not been used */ - if (count == 256) { + if (count == maxchar + 1) { ap->high_val_char = lastval; - } else if (values[255] != -1) { + } else if (values[maxchar] != -1) { ap->high_val_char = 0; - for (n = 254; n > 0; n--) { + for (n = maxchar - 1; n > 0; n--) { if (values[n] == -1) { ap->high_val_char = n; break; @@ -4111,23 +4157,40 @@ validate_alphabet (cb_tree alphabet) } /* Get rest of code set */ - for (n = tableval; n < 256; ++n) { - for (i = 0; i < 256; ++i) { - if (charvals[i] < 0) { - charvals[i] = 0; - ap->alphachr[n] = i; - break; + { + register int *entry = charvals; + i = 0; + for (n = tableval; n <= maxchar; ++n) { + while (i <= maxchar) { + if (*entry == -1) { + *entry = 0; + ap->alphachr[n] = i; + /* increase start for next iteration and leave current one */ + entry++; + i++; + break; + } + entry++; + i++; } } - } - /* Fill in missing characters */ - for (n = 0; n < 256; n++) { - if (ap->values[n] < 0) { - ap->values[n] = tableval++; + /* Fill in missing characters */ + entry = ap->values; + for (n = 0; n <= maxchar; n++) { + if (*entry == -1) { + *entry = tableval++; + } + entry++; } } + + val_ex: + free (values); + free (charvals); + free (dupvals); } + } static void @@ -10511,11 +10574,11 @@ cb_build_converting (cb_tree x, cb_tree y, cb_tree l) return cb_list_add (l, CB_BUILD_FUNCALL_0 ("cob_inspect_finish")); } -#if 0 /* Simon: unfinished prototype, get back to it later */ +#if 0 /* Simon: unfinished prototype, get back to it later, but only for not-national */ if (tag_x == tag_y) { switch (tag_x) { case CB_TAG_LITERAL: - { + if (x->category != CB_CATEGORY_NATIONAL) { unsigned char conv_tab[256]; const struct cb_literal *lit_x = CB_LITERAL (x); const unsigned char *conv_to = (tag_y == CB_TAG_CONST) @@ -10560,7 +10623,7 @@ cb_build_converting (cb_tree x, cb_tree y, cb_tree l) /* use the existing and configurable translation table */ return cb_list_add (l, CB_BUILD_FUNCALL_1 ("cob_inspect_translating", CB_TREE (alph_y))); - } else { + } else if (alph_x->alphabet_target == CB_ALPHABET_ALPHANUMERIC) { // TODO: create conversion tab struct cb_alphabet_name *alph_conv; diff --git a/configure.ac b/configure.ac index a17d2f83c..e5cc8b1e5 100644 --- a/configure.ac +++ b/configure.ac @@ -659,6 +659,18 @@ fi CFLAGS="$curr_cflags" +dnl Add --enable-code-coverage and test for code-coverage tools if enabled +AX_CODE_COVERAGE + +if test "$COB_USES_GCC_NO_ICC" != yes -a "$enable_code_coverage" = yes; then + AC_MSG_ERROR([Code coverage checks are only usable with GCC!]) +fi + + +dnl set PKG_CONFIG to use (cross-compile aware) +PKG_PROG_PKG_CONFIG + + # more things to save... AC_CACHE_SAVE @@ -722,18 +734,6 @@ else fi -dnl Add --enable-code-coverage and test for code-coverage tools if enabled -AX_CODE_COVERAGE - -if test "$COB_USES_GCC_NO_ICC" != yes -a "$enable_code_coverage" = yes; then - AC_MSG_ERROR([Code coverage checks are only usable with GCC!]) -fi - - -dnl set PKG_CONFIG to use (cross-compile aware) -PKG_PROG_PKG_CONFIG - - # Checks for gmp. AC_MSG_NOTICE([Checks for GMP/MPIR ...]) @@ -908,6 +908,23 @@ AC_CHECK_LIB([$with_math], [__gmp_get_memory_functions], LIBS="$curr_libs" CPPFLAGS="$curr_cppflags" +AC_ARG_WITH([iconv], + [AS_HELP_STRING([--with-iconv], + [(GnuCOBOL) Use iconv for character set conversion (default: check)])], + [], + [with_iconv=check]) + +if test "$with_iconv" = yes -o "$with_iconv" = check; then + AM_ICONV + if test "$with_iconv" = yes && test "$am_cv_func_iconv" != yes; then + AC_MSG_ERROR([iconv library requested but not found]) + fi + if test "$am_cv_func_iconv" = yes -a "x$LIBICONV" != x; then + PROGRAMS_LIBS="$PROGRAMS_LIBS $LIBICONV" + LIBCOB_LIBS="$LIBCOB $LIBICONV" + fi +fi + dnl dnl Configure options part II (needing compilation) @@ -915,7 +932,7 @@ dnl AC_ARG_WITH([xml2], [AS_HELP_STRING([--with-xml2], - [(GnuCOBOL) Use libxml2 as XML handler (default)])], + [(GnuCOBOL) Use libxml2 as XML handler (default: check)])], [], [with_xml2=check]) @@ -2559,6 +2576,7 @@ else AC_MSG_NOTICE([ Dynamic loading: Libtool]) fi AC_MSG_NOTICE([ Use gettext for international messages: ${USE_NLS}]) +AC_MSG_NOTICE([ Use iconv for character encoding: ${am_cv_func_iconv_summary}]) AC_MSG_NOTICE([ Use fcntl for file locking: ${ac_cv_func_fcntl}]) AC_MSG_NOTICE([ Use math multiple precision library: ${with_math}]) case "$USE_CURSES" in diff --git a/tests/testsuite.src/run_ml.at b/tests/testsuite.src/run_ml.at index b50ba62df..2b94f4bb2 100644 --- a/tests/testsuite.src/run_ml.at +++ b/tests/testsuite.src/run_ml.at @@ -362,7 +362,7 @@ AT_KEYWORDS([extensions]) AT_SKIP_IF([test "$COB_HAS_XML2" = "no"]) -# TO-DO: Add support for IBM/COBOL 2002 edited floating point (e.g. PIC 9(3)E+99). +# TO-DO: Add support for IBM/COBOL 2002 edited floating point, e.g. PIC 9(3)E+99. AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. diff --git a/tests/testsuite.src/syn_definition.at b/tests/testsuite.src/syn_definition.at index 0f0edb57d..33889dd69 100644 --- a/tests/testsuite.src/syn_definition.at +++ b/tests/testsuite.src/syn_definition.at @@ -1895,7 +1895,7 @@ AT_DATA([prog3.cob], [ SPECIAL-NAMES. ALPHABET ALPHABET-1 IS 'A' THROUGH 'Z', x'00' thru x'05'. - ALPHABET ALPHABET-2 + ALPHABET ALPHABET-2 NATIONAL IS n'A' also n'B' ALSO n'f', n'g' also n'G', n'1' thru n'9'. END PROGRAM prog3. @@ -1911,7 +1911,7 @@ AT_DATA([prog3.cob], [ SPECIAL-NAMES. ALPHABET ALPHABET-1 IS 'A' THROUGH 'Z', x'00' thru x'05'. - ALPHABET ALPHABET-2 IS + ALPHABET ALPHABET-2 FOR NATIONAL n'A' ALSO n'f', n'g' also n'G'. END PROGRAM prog3b. @@ -1923,8 +1923,8 @@ AT_DATA([prog3.cob], [ SOURCE-COMPUTER. GNU-LINUX. OBJECT-COMPUTER. GC-MACHINE, SEQUENCE ALPHABET-1, ALPHABET-2. SPECIAL-NAMES. - ALPHABET ALPHABET-1 x'00' thru x'05'. - ALPHABET ALPHABET-2 IS n'g' also n'G', n'1' thru n'9'. + ALPHABET ALPHABET-1 x'00' thru x'05'. + ALPHABET ALPHABET-2 NATIONAL IS n'g' also n'G', n'1' thru n'9'. END PROGRAM prog3c. IDENTIFICATION DIVISION. @@ -1935,7 +1935,7 @@ AT_DATA([prog3.cob], [ OBJECT-COMPUTER. GC-MACHINE, SEQUENCE ALPHABET-1, ALPHABET-2. SPECIAL-NAMES. ALPHABET ALPHABET-1 IS 'A' THROUGH 'Z'. - ALPHABET ALPHABET-2 n'A' also n'B', n'1' thru n'9'. + ALPHABET ALPHABET-2 NATIONAL n'A' also n'B', n'1' thru n'9'. END PROGRAM prog3d. IDENTIFICATION DIVISION. @@ -1985,7 +1985,7 @@ AT_DATA([prog3.cob], [ SPECIAL-NAMES. ALPHABET ALPHABET-1 IS 'A', 'C', x'05'. - ALPHABET ALPHABET-2 + ALPHABET ALPHABET-2 FOR NATIONAL IS n'A', n'1' thru n'9'. END PROGRAM prog3h. @@ -2001,7 +2001,7 @@ AT_DATA([prog3.cob], [ SPECIAL-NAMES. ALPHABET ALPHABET-1 IS 'a' THROUGH 'z'. - ALPHABET ALPHABET-2 + ALPHABET ALPHABET-2 NATIONAL IS n'B', n'C'; n'g' also n'G'. END PROGRAM prog3i. @@ -2014,10 +2014,29 @@ AT_DATA([prog3.cob], [ COLLATING SEQUENCE NATIONAL ALPHABET-2. SPECIAL-NAMES. - ALPHABET ALPHABET-2 - n'B', n'C'; n'g' also n'G'. + ALPHABET ALPHABET-2 NATIONAL + n'B', n'C'; n'g' also n'G' also nx'003E'. END PROGRAM prog3j. ]) +# check that alphabets with a literal have correct types +AT_DATA([prog4.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog4. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SOURCE-COMPUTER. GNU-LINUX. + OBJECT-COMPUTER. GC-MACHINE, + COLLATING SEQUENCE + NATIONAL ALPHABET-2 + ALPHANUMERIC ALPHABET-1. + SPECIAL-NAMES. + ALPHABET ALPHABET-1 IS + 'a' THROUGH n'z', + n'B'; 'G' also n'G' also nx'003E'. + ALPHABET ALPHABET-2 FOR NATIONAL IS + nx'0000' thru nx'0005', N'A' THROUGH N'Z'; + x'41' ALSO x'42', nx'00C1' ALSO x'C2'. +]) AT_CHECK([$COMPILE_ONLY prog.cob], [1], [], [prog.cob:10: error: duplicate character values in alphabet 'TESTME': x'00', A, B @@ -2035,6 +2054,11 @@ prog3.cob:99: warning: NATIONAL COLLATING SEQUENCE is not implemented prog3.cob:114: warning: NATIONAL COLLATING SEQUENCE is not implemented prog3.cob:130: warning: NATIONAL COLLATING SEQUENCE is not implemented ]) +AT_CHECK([$COMPILE_ONLY -Wno-unfinished prog4.cob], [1], [], +[prog4.cob:9: warning: NATIONAL COLLATING SEQUENCE is not implemented +prog4.cob:13: error: only literals of type alphanumeric allowed for alphanumeric alphabet +prog4.cob:17: error: only literals of type national allowed for national alphabet +]) AT_CLEANUP From 3e146193295e30c31ff0a50022204c9d91a1ef9b Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Sun, 11 Aug 2024 10:56:20 +0000 Subject: [PATCH 12/51] added missing iconv.m4 update - follow-up to r5310 * m4/iconv.m4: updated to current version from gnulib --- ChangeLog | 1 + NEWS | 6 +-- configure.ac | 2 +- m4/iconv.m4 | 141 ++++++++++++++++++++++++++++++++------------------- 4 files changed, 93 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index a54a08fae..0f9c31240 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ 2024-08-06 Simon Sobisch * configure.ac: new option --with-iconv + * m4/iconv.m4: updated to current version from gnulib 2024-05-14 David Declerck diff --git a/NEWS b/NEWS index d6f861455..955e0cba0 100644 --- a/NEWS +++ b/NEWS @@ -6,9 +6,9 @@ NEWS - user visible changes -*- outline -*- * New GnuCOBOL features -** cobc now checks for binary files and early exit parsing those; - the error output for format errors (for example invalid indicator column) - is now limitted to 5 per source file +** cobc now checks for binary and multi-byte encoded files and early exit + parsing those; the error output for format errors (for example invalid + indicator column) is now limitted to 5 per source file ** support the COLLATING SEQUENCE clause on indexed files (currently only with the BDB backend) diff --git a/configure.ac b/configure.ac index e5cc8b1e5..d8719b571 100644 --- a/configure.ac +++ b/configure.ac @@ -921,7 +921,7 @@ if test "$with_iconv" = yes -o "$with_iconv" = check; then fi if test "$am_cv_func_iconv" = yes -a "x$LIBICONV" != x; then PROGRAMS_LIBS="$PROGRAMS_LIBS $LIBICONV" - LIBCOB_LIBS="$LIBCOB $LIBICONV" + LIBCOB_LIBS="$LIBCOB_LIBS $LIBICONV" fi fi diff --git a/m4/iconv.m4 b/m4/iconv.m4 index e593b7270..b414bfca6 100644 --- a/m4/iconv.m4 +++ b/m4/iconv.m4 @@ -1,5 +1,6 @@ -# iconv.m4 serial 21 -dnl Copyright (C) 2000-2002, 2007-2014, 2016-2020 Free Software Foundation, +# iconv.m4 +# serial 28 +dnl Copyright (C) 2000-2002, 2007-2014, 2016-2024 Free Software Foundation, dnl Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,6 +8,12 @@ dnl with or without modifications, as long as this notice is preserved. dnl From Bruno Haible. +AC_PREREQ([2.64]) + +dnl Note: AM_ICONV is documented in the GNU gettext manual +dnl . +dnl Don't make changes that are incompatible with that documentation! + AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], [ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. @@ -32,7 +39,7 @@ AC_DEFUN([AM_ICONV_LINK], dnl because if the user has installed libiconv and not disabled its use dnl via --without-libiconv-prefix, he wants to use it. The first dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed. - am_save_CPPFLAGS="$CPPFLAGS" + gl_saved_CPPFLAGS="$CPPFLAGS" AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ @@ -49,7 +56,7 @@ AC_DEFUN([AM_ICONV_LINK], iconv_close(cd);]])], [am_cv_func_iconv=yes]) if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" + gl_saved_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" AC_LINK_IFELSE( [AC_LANG_PROGRAM( @@ -62,14 +69,14 @@ AC_DEFUN([AM_ICONV_LINK], iconv_close(cd);]])], [am_cv_lib_iconv=yes] [am_cv_func_iconv=yes]) - LIBS="$am_save_LIBS" + LIBS="$gl_saved_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11, - dnl Solaris 10. - am_save_LIBS="$LIBS" + dnl Solaris 10, macOS 14.4. + gl_saved_LIBS="$LIBS" if test $am_cv_lib_iconv = yes; then LIBS="$LIBS $LIBICONV" fi @@ -86,8 +93,9 @@ AC_DEFUN([AM_ICONV_LINK], #endif ]], [[int result = 0; - /* Test against AIX 5.1 bug: Failures are not distinguishable from successful - returns. */ + /* Test against AIX 5.1...7.2 bug: Failures are not distinguishable from + successful returns. This is even documented in + */ { iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); if (cd_utf8_to_88591 != (iconv_t)(-1)) @@ -106,6 +114,35 @@ AC_DEFUN([AM_ICONV_LINK], iconv_close (cd_utf8_to_88591); } } + /* Test against macOS 14.4 bug: Failures are not distinguishable from + successful returns. + POSIX:2018 says: "The iconv() function shall ... return the number of + non-identical conversions performed." + But here, the conversion always does transliteration (the suffixes + "//TRANSLIT" and "//IGNORE" have no effect, nor does iconvctl()) and + does not report when it does a non-identical conversion. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO-8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static ICONV_CONST char input[] = "\305\202"; /* LATIN SMALL LETTER L WITH STROKE */ + char buf[10]; + ICONV_CONST char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + &inptr, &inbytesleft, + &outptr, &outbytesleft); + /* Here: + With glibc, GNU libiconv (including macOS up to 13): res == (size_t)-1, errno == EILSEQ. + With musl libc, NetBSD 10, Solaris 11: res == 1. + With macOS 14.4: res == 0, output is "l". */ + if (res == 0) + result |= 2; + iconv_close (cd_utf8_to_88591); + } + } /* Test against Solaris 10 bug: Failures are not distinguishable from successful returns. */ { @@ -122,7 +159,7 @@ AC_DEFUN([AM_ICONV_LINK], &inptr, &inbytesleft, &outptr, &outbytesleft); if (res == 0) - result |= 2; + result |= 4; iconv_close (cd_ascii_to_88591); } } @@ -141,7 +178,7 @@ AC_DEFUN([AM_ICONV_LINK], &inptr, &inbytesleft, &outptr, &outbytesleft); if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) - result |= 4; + result |= 8; iconv_close (cd_88591_to_utf8); } } @@ -161,7 +198,7 @@ AC_DEFUN([AM_ICONV_LINK], &inptr, &inbytesleft, &outptr, &outbytesleft); if ((int)res > 0) - result |= 8; + result |= 16; iconv_close (cd_88591_to_utf8); } } @@ -179,7 +216,7 @@ AC_DEFUN([AM_ICONV_LINK], iconv_t cd4 = iconv_open ("utf8", "eucJP"); if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1) && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1)) - result |= 16; + result |= 32; if (cd1 != (iconv_t)(-1)) iconv_close (cd1); if (cd2 != (iconv_t)(-1)) @@ -198,7 +235,7 @@ AC_DEFUN([AM_ICONV_LINK], esac]) test "$am_cv_func_iconv_works" = no || break done - LIBS="$am_save_LIBS" + LIBS="$gl_saved_LIBS" ]) case "$am_cv_func_iconv_works" in *no) am_func_iconv=no am_cv_lib_iconv=no ;; @@ -217,7 +254,7 @@ AC_DEFUN([AM_ICONV_LINK], else dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV dnl either. - CPPFLAGS="$am_save_CPPFLAGS" + CPPFLAGS="$gl_saved_CPPFLAGS" LIBICONV= LTLIBICONV= fi @@ -225,64 +262,62 @@ AC_DEFUN([AM_ICONV_LINK], AC_SUBST([LTLIBICONV]) ]) -dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to -dnl avoid warnings like +dnl Define AM_ICONV using AC_DEFUN_ONCE, in order to avoid warnings like dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". -dnl This is tricky because of the way 'aclocal' is implemented: -dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. -dnl Otherwise aclocal's initial scan pass would miss the macro definition. -dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. -dnl Otherwise aclocal would emit many "Use of uninitialized value $1" -dnl warnings. -m4_define([gl_iconv_AC_DEFUN], - m4_version_prereq([2.64], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [m4_ifdef([gl_00GNULIB], - [[AC_DEFUN_ONCE( - [$1], [$2])]], - [[AC_DEFUN( - [$1], [$2])]])])) -gl_iconv_AC_DEFUN([AM_ICONV], +AC_DEFUN_ONCE([AM_ICONV], [ AM_ICONV_LINK if test "$am_cv_func_iconv" = yes; then - AC_MSG_CHECKING([for iconv declaration]) - AC_CACHE_VAL([am_cv_proto_iconv], [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ + AC_CACHE_CHECK([whether iconv is compatible with its POSIX signature], + [gl_cv_iconv_nonconst], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ #include #include extern #ifdef __cplusplus "C" #endif -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); -#else -size_t iconv(); -#endif - ]], - [[]])], - [am_cv_proto_iconv_arg1=""], - [am_cv_proto_iconv_arg1="const"]) - am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) - am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` - AC_MSG_RESULT([ - $am_cv_proto_iconv]) + ]], + [[]])], + [gl_cv_iconv_nonconst=yes], + [gl_cv_iconv_nonconst=no]) + ]) else dnl When compiling GNU libiconv on a system that does not have iconv yet, dnl pick the POSIX compliant declaration without 'const'. - am_cv_proto_iconv_arg1="" + gl_cv_iconv_nonconst=yes fi - AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + if test $gl_cv_iconv_nonconst = yes; then + iconv_arg1="" + else + iconv_arg1="const" + fi + AC_DEFINE_UNQUOTED([ICONV_CONST], [$iconv_arg1], [Define as const if the declaration of iconv() needs const.]) dnl Also substitute ICONV_CONST in the gnulib generated . m4_ifdef([gl_ICONV_H_DEFAULTS], [AC_REQUIRE([gl_ICONV_H_DEFAULTS]) - if test -n "$am_cv_proto_iconv_arg1"; then + if test $gl_cv_iconv_nonconst != yes; then ICONV_CONST="const" fi ]) + + dnl A summary result, for those packages which want to print a summary at the + dnl end of the configuration. + if test "$am_func_iconv" = yes; then + if test -n "$LIBICONV"; then + am_cv_func_iconv_summary='yes, in libiconv' + else + am_cv_func_iconv_summary='yes, in libc' + fi + else + if test "$am_cv_func_iconv" = yes; then + am_cv_func_iconv_summary='not working, consider installing GNU libiconv' + else + am_cv_func_iconv_summary='no, consider installing GNU libiconv' + fi + fi ]) From 41e2e4488de18f3aba4adc4085a63061159b124b Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Sun, 11 Aug 2024 14:28:06 +0000 Subject: [PATCH 13/51] work on ALPHABET definitions, especially ALPHABET FOR NATIONAL - C90 fix for r5310 cobc/typeck.c (validate_alphabet): fixed --- cobc/typeck.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cobc/typeck.c b/cobc/typeck.c index c484550aa..1b2a5039a 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -3987,11 +3987,12 @@ validate_alphabet (cb_tree alphabet) ap->low_val_char = get_value (X); } for (ls = x; ls; ls = CB_CHAIN (ls)) { + int val; X = CB_VALUE (ls); if (!is_alphabet_matching_literal_type (X, is_national_alphabet)) { continue; } - int val = get_value (X); + val = get_value (X); if (!CB_CHAIN (ls)) { lastval = val; } From 8b7350a27a7afc4d424dc3279ec4e30a73ed638e Mon Sep 17 00:00:00 2001 From: Simon Sobisch Date: Sat, 17 Aug 2024 18:53:59 +0200 Subject: [PATCH 14/51] Update .gitpod.yml * ensure bear + clangd are installed and usable for nice IDE experience * install OCamlPro COBOL extension by default --- .gitpod.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 6cdf438c1..ee365640a 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -11,41 +11,43 @@ tasks: sudo apt update && sudo apt upgrade -y sudo apt install -y build-essential libgmp-dev libdb-dev libjson-c-dev ncurses-dev libxml2-dev \ automake libtool flex bison help2man texinfo \ - lcov + lcov \ + clangd bear # sudo apt install gettext texlive-base # for make dist (po/*, doc/gnucobol.pdf) gp sync-done system-prepare - name: building GnuCOBOL init: | - mkdir -p $GITPOD_REPO_ROOTS/_build - cd $GITPOD_REPO_ROOTS/_build + mkdir -p $GITPOD_REPO_ROOTS/build + cd $GITPOD_REPO_ROOTS/build gp sync-await system-prepare ../autogen.sh - ../configure --enable-cobc-internal-checks --enable-debug --enable-code-coverage - make --jobs=$(nproc) + ../configure --enable-cobc-internal-checks --enable-debug --enable-code-coverage \ + CC="gcc -std=c89" CPPFLAGS="-Werror=declaration-after-statement" + bear -- make --jobs=$(nproc) command: | - cd $GITPOD_REPO_ROOTS/_build + cd $GITPOD_REPO_ROOTS/build gp sync-done build-finish - name: running GnuCOBOL tests with coverage command: | gp sync-await build-finish - cd $GITPOD_REPO_ROOTS/_build + cd $GITPOD_REPO_ROOTS/build half_jobs=$(( $(nproc) / 2 )) nice make --jobs=${half_jobs} check-code-coverage TESTSUITEFLAGS="--jobs=${half_jobs}" - name: running NIST85 tests command: | gp sync-await build-finish - cd $GITPOD_REPO_ROOTS/_build + cd $GITPOD_REPO_ROOTS/build half_jobs=$(( $(nproc) / 2 )) nice make -C tests/cobol85 --jobs=${half_jobs} test -# disabled as the download takes too long +# disabled as running that is really onbly useful after several adjustments #- name: running GnuCOBOL distribution tests with testuite # command: | # gp sync-await build-finish -# cd $GITPOD_REPO_ROOTS/_build +# cd $GITPOD_REPO_ROOTS/build # half_jobs=$(( $(nproc) / 2 )) # nice make --jobs=${half_jobs} distcheck TESTSUITEFLAGS="--jobs=${half_jobs}" @@ -58,3 +60,4 @@ vscode: - tenninebt.vscode-koverage - meronz.manpages - webfreak.debug + - OCamlPro.SuperBOL From 6bf47af0209e7cac2f395f71c6e99fd093e5afbc Mon Sep 17 00:00:00 2001 From: almorsi Date: Mon, 19 Aug 2024 13:55:16 +0000 Subject: [PATCH 15/51] [feature-request:#474]: add runtime configuration to hide cursor for extended screenio libcob: * common.c, coblocal.h (cob_settings): added boolean COB_HIDE_CURSOR * screenio.c (cob_settings_screenio): implemented runtime config to hide the cursor config/runtime.cfg: add COB_HIDE_CURSOR --- NEWS | 5 +- config/ChangeLog | 5 ++ config/runtime.cfg | 7 +++ libcob/ChangeLog | 7 +++ libcob/coblocal.h | 2 + libcob/common.c | 4 +- libcob/screenio.c | 30 +++++----- tests/testsuite.src/run_manual_screen.at | 70 ++++++++++++++++++++++-- 8 files changed, 108 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index 955e0cba0..411ca2cc0 100644 --- a/NEWS +++ b/NEWS @@ -13,13 +13,16 @@ NEWS - user visible changes -*- outline -*- ** support the COLLATING SEQUENCE clause on indexed files (currently only with the BDB backend) -** Support for time profiling of modules, sections, paragraphs, entries +** support for time profiling of modules, sections, paragraphs, entries and external CALLs. This feature is activated by compiling the modules to be profiled with -fprof, and then executing the code with environment variable COB_PROF_ENABLE. The output is stored in a CSV file. Further customization can be done using COB_PROF_FILE, COB_PROF_MAX_DEPTH and COB_PROF_FORMAT +** new runtime configuraiton COB_HIDE_CURSOR, allows to hide the cursor during + extended ScreenIO operations + more work in progress * Important Bugfixes diff --git a/config/ChangeLog b/config/ChangeLog index e31460947..cd1a4744f 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,4 +1,9 @@ +2024-08-17 Ammar Almoris + + FR #474: add runtime configuration to hide cursor for extended screenio + * runtime.cfg: add COB_HIDE_CURSOR + 2024-07-11 David Declerck * general: fix minor alignment / tab issues diff --git a/config/runtime.cfg b/config/runtime.cfg index b076f2298..6f583f0ee 100644 --- a/config/runtime.cfg +++ b/config/runtime.cfg @@ -465,6 +465,13 @@ # Note: also sets the cursor type (if available) # Example: insert_mode Y +# Environment name: COB_HIDE_CURSOR +# Parameter name: hide_cursor +# Purpose: hide the cursor; 0=visible, 1=hidden +# Type: boolean +# Default: false +# Example: hide_cursor Y + # Environment name: COB_MOUSE_FLAGS # Parameter name: mouse_flags # Purpose: specify which mouse events will be sent as function key diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 880927535..db881ed02 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,11 @@ +2024-08-17 Ammar Almorsi + + FR #474: add runtime configuration to hide cursor for extended screenio + * common.c, coblocal.h (cob_settings): added boolean COB_HIDE_CURSOR + * screenio.c (cob_settings_screenio): implemented runtime config to hide + the cursor + 2024-07-29 Chuck Haatvedt * move.c (optimized_move_display_to_edited): fixed small bug diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 8471722dd..5fa04d7f9 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -253,6 +253,7 @@ Note: also defined together with __clang__ in both frontends: #define COB_BEEP_VALUE cobsetptr->cob_beep_value #define COB_TIMEOUT_SCALE cobsetptr->cob_timeout_scale #define COB_INSERT_MODE cobsetptr->cob_insert_mode +#define COB_HIDE_CURSOR cobsetptr->cob_hide_cursor #define COB_EXTENDED_STATUS cobsetptr->cob_extended_status #define COB_MOUSE_FLAGS cobsetptr->cob_mouse_flags #define COB_MOUSE_INTERVAL cobsetptr->cob_mouse_interval @@ -335,6 +336,7 @@ typedef struct __cob_settings { unsigned int cob_use_esc; /* Check ESC key */ unsigned int cob_timeout_scale; /* timeout scale */ unsigned int cob_insert_mode; /* insert toggle, 0=off, 1=on */ + unsigned int cob_hide_cursor; /* hide cursor, 0=visible, 1=hidden */ unsigned int cob_exit_wait; /* wait on program exit if no ACCEPT came after last DISPLAY */ const char *cob_exit_msg; /* message for cob_exit_wait */ diff --git a/libcob/common.c b/libcob/common.c index 4b428ecee..672dd35e5 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -503,6 +503,7 @@ static struct config_tbl gc_conf[] = { {"COB_SCREEN_EXCEPTIONS", "screen_exceptions", "0", NULL, GRP_SCREEN, ENV_BOOL, SETPOS (cob_extended_status)}, {"COB_TIMEOUT_SCALE", "timeout_scale", "0", timeopts, GRP_SCREEN, ENV_UINT, SETPOS (cob_timeout_scale)}, {"COB_INSERT_MODE", "insert_mode", "0", NULL, GRP_SCREEN, ENV_BOOL, SETPOS (cob_insert_mode)}, + {"COB_HIDE_CURSOR", "hide_cursor", "0", NULL, GRP_SCREEN, ENV_BOOL, SETPOS (cob_hide_cursor)}, {"COB_MOUSE_FLAGS", "mouse_flags", "1", NULL, GRP_SCREEN, ENV_UINT, SETPOS (cob_mouse_flags)}, {"MOUSE_FLAGS", "mouse_flags", NULL, NULL, GRP_HIDE, ENV_UINT, SETPOS (cob_mouse_flags)}, #ifdef HAVE_MOUSEINTERVAL /* possibly add an internal option for mouse support, too */ @@ -8080,7 +8081,8 @@ set_config_val (char *value, int pos) if (data == (char *)&cobsetptr->cob_debugging_mode) { /* Copy variables from settings (internal) to global structure, each time */ cobglobptr->cob_debugging_mode = cobsetptr->cob_debugging_mode; - } else if (data == (char *)&cobsetptr->cob_insert_mode) { + } else if (data == (char *)&cobsetptr->cob_insert_mode + || data == (char *)&cobsetptr->cob_hide_cursor) { cob_settings_screenio (); } else if (data == (char *)&cobsetptr->cob_debugging_mode) { cob_switch[11 + 'D' - 'A'] = (int)numval; diff --git a/libcob/screenio.c b/libcob/screenio.c index cb76dcace..17a3c9df0 100644 --- a/libcob/screenio.c +++ b/libcob/screenio.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2012, 2014-2023 Free Software Foundation, Inc. + Copyright (C) 2001-2012, 2014-2024 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart, Chuck Haatvedt @@ -161,7 +161,6 @@ static int accept_cursor_y; static int accept_cursor_x; static int pending_accept; static int got_sys_char; -static unsigned int curr_setting_insert_mode = INT_MAX; #ifdef HAVE_MOUSEMASK static unsigned int curr_setting_mouse_flags = UINT_MAX; #endif @@ -5008,21 +5007,22 @@ cob_settings_screenio (void) return; } - /* Extended ACCEPT status returns */ - if (cobsetptr->cob_extended_status == 0) { - cobsetptr->cob_use_esc = 0; + /* requesting cursor type depending on both settings, 0 = hide, + 1 = vertical bar cursor, 2 = square cursor; note: the cursor change + may not have an effect in all curses implementations / terminals */ + { + static unsigned int prev_cursor_mode = UINT_MAX; + const unsigned int new_cursor_mode + = (COB_HIDE_CURSOR)?0U:((COB_INSERT_MODE)?1U:2U); + if (prev_cursor_mode != new_cursor_mode) { + (void) curs_set (new_cursor_mode); + prev_cursor_mode = new_cursor_mode; + } } - if (curr_setting_insert_mode != COB_INSERT_MODE) { - /* Depending on insert mode set vertical bar cursor (on) - or square cursor (off) - note: the cursor change may has no - effect in all curses implementations / terminals */ - if (COB_INSERT_MODE == 0) { - (void)curs_set (2); /* set square cursor */ - } else { - (void)curs_set (1); /* set vertical bar cursor */ - } - curr_setting_insert_mode = COB_INSERT_MODE; + /* extended ACCEPT status returns */ + if (cobsetptr->cob_extended_status == 0) { + cobsetptr->cob_use_esc = 0; } #ifdef HAVE_MOUSEINTERVAL diff --git a/tests/testsuite.src/run_manual_screen.at b/tests/testsuite.src/run_manual_screen.at index cb1ea2e5f..8d64a5e15 100644 --- a/tests/testsuite.src/run_manual_screen.at +++ b/tests/testsuite.src/run_manual_screen.at @@ -1,4 +1,4 @@ -## Copyright (C) 2014-2018,2020-2023 Free Software Foundation, Inc. +## Copyright (C) 2014-2018,2020-2024 Free Software Foundation, Inc. ## Written by Edward Hart, Simon Sobisch ## ## This file is part of GnuCOBOL. @@ -2747,7 +2747,7 @@ AT_CLEANUP AT_SETUP([END key]) -AT_KEYWORDS([END SIZE]) +AT_KEYWORDS([END SIZE position]) AT_SKIP_IF([test "$COB_HAS_CURSES" != "yes"]) @@ -2794,7 +2794,7 @@ AT_CLEANUP AT_SETUP([INSERT key]) -AT_KEYWORDS([INSERT SIZE]) +AT_KEYWORDS([COB_INSERT_MODE SIZE]) AT_SKIP_IF([test "$COB_HAS_CURSES" != "yes"]) @@ -2842,8 +2842,68 @@ MANUAL_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) AT_CLEANUP +AT_SETUP([cursor visibility]) +AT_KEYWORDS([COB_HIDE_CURSOR]) + +AT_SKIP_IF([test "$COB_HAS_CURSES" != "yes"]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 success-flag PIC X VALUE 'Y'. + 88 fail VALUE 'N'. + 01 ws-input PIC X. + 88 success VALUE 'Y', 'y'. + PROCEDURE DIVISION. + DISPLAY "Type 'Y' if you see the cursor" + LINE 1 COLUMN 1. + + ACCEPT WS-INPUT + LINE 1 COLUMN 50 + WITH AUTO-SKIP + UPDATE. + IF NOT success SET fail TO TRUE. + + SET ENVIRONMENT 'COB_HIDE_CURSOR' TO 'TRUE'. + + DISPLAY "Type 'Y' if you do not see the cursor" + LINE 3 COLUMN 1. + + ACCEPT WS-INPUT + LINE 3 COLUMN 50 + WITH AUTO-SKIP + UPDATE. + IF NOT success SET fail TO TRUE. + + SET ENVIRONMENT 'COB_INSERT_MODE' TO 'TRUE'. + + DISPLAY "Type 'Y' if you still do not see the cursor" + LINE 5 COLUMN 1. + + ACCEPT WS-INPUT + LINE 5 COLUMN 50 + WITH AUTO-SKIP + UPDATE. + IF NOT success SET fail TO TRUE. + + IF fail + GOBACK RETURNING 1 + ELSE + GOBACK RETURNING 0 + END-IF + . +]) + +AT_CHECK([$COMPILE prog.cob], [0], [], []) +MANUAL_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP + + AT_SETUP([BACKSPACE key]) -AT_KEYWORDS([BACKSPACE SIZE CURSOR]) +AT_KEYWORDS([SIZE CURSOR position]) AT_SKIP_IF([test "$COB_HAS_CURSES" != "yes"]) @@ -2898,7 +2958,7 @@ AT_CLEANUP AT_SETUP([DELETE key]) -AT_KEYWORDS([DELETE SIZE]) +AT_KEYWORDS([SIZE position]) AT_SKIP_IF([test "$COB_HAS_CURSES" != "yes"]) From 816bd2be16d88e9ea9f17f2e047fd08844d7f8c2 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Thu, 22 Aug 2024 14:45:34 +0000 Subject: [PATCH 16/51] Disable Windows error popups in programs compiled with MSVC * libcob/common.c (DllMain) [_MSC_VER]: added calls to _CrtSetReportMode to disable Windows error popups and redirect them to stderr --- libcob/ChangeLog | 5 +++++ libcob/common.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/libcob/ChangeLog b/libcob/ChangeLog index db881ed02..408d6fe8b 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,9 @@ +2024-08-22 David Declerck + + * common.c (DllMain) [_MSC_VER]: added calls to _CrtSetReportMode + to disable Windows error popups and redirect them to stderr + 2024-08-17 Ammar Almorsi FR #474: add runtime configuration to hide cursor for extended screenio diff --git a/libcob/common.c b/libcob/common.c index 672dd35e5..3a747ae9d 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -11225,3 +11225,31 @@ void cob_cleanup_thread () { cob_exit_strings (); } + +#ifdef _MSC_VER + +#include +#include + +BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + COB_UNUSED (hinstDLL); + COB_UNUSED (lpReserved); + + if (fdwReason == DLL_PROCESS_ATTACH) { + /* Programs compiled with MSVC will by default display a popup + window on some errors. In general, we do not want that, + so we disable them, unless explicitly requested. */ + if (!IsDebuggerPresent() && !getenv ("DEBUG_POPUPS_WANTED")) { + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + } + } + return TRUE; +} + +#endif From 7529ba38d84bcb886090d4028245546b7b85b446 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Thu, 22 Aug 2024 19:24:20 +0000 Subject: [PATCH 17/51] Remove debugapi.h include from common.c - follow-up to r5315 --- libcob/common.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libcob/common.c b/libcob/common.c index 3a747ae9d..7ecf0c926 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -11228,7 +11228,6 @@ void cob_cleanup_thread () #ifdef _MSC_VER -#include #include BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) From 808c9be88a5066b2c9a9b3eb9e7d904ee797a187 Mon Sep 17 00:00:00 2001 From: nberth Date: Tue, 27 Aug 2024 21:21:41 +0000 Subject: [PATCH 18/51] Retrieve archive of NIST test suite from sourceforge instead of from an out-dated URL * tests/cobol85/Makefile.am: stop downloading "newcob.val.Z" from out-dated URL --- tests/cobol85/ChangeLog | 4 ++++ tests/cobol85/Makefile.am | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/cobol85/ChangeLog b/tests/cobol85/ChangeLog index bb6d3f366..fa52b1d5f 100644 --- a/tests/cobol85/ChangeLog +++ b/tests/cobol85/ChangeLog @@ -1,4 +1,8 @@ +2024-08-27 Nicolas Berthier + + * Makefile.am: stop downloading "newcob.val.Z" from out-dated URL + 2023-06-02 Simon Sobisch * report.pl: place stderr from test runs into .out file diff --git a/tests/cobol85/Makefile.am b/tests/cobol85/Makefile.am index 07f02fbe3..1490ef85c 100644 --- a/tests/cobol85/Makefile.am +++ b/tests/cobol85/Makefile.am @@ -169,11 +169,13 @@ diff-summary: @diff $(DIFF_FLAGS) "$(srcdir)/$(SUMMARY)" "summary.log" @echo Done -newcob.val.Z: - @echo "Trying to download newcob.val.Z..." - @(which curl 1>/dev/null && curl $(CURL_FLAGS) "$(URL_NEWCOB_Z)" -o $@) || \ - wget $(WGET_FLAGS) "$(URL_NEWCOB_Z)" || \ - ($(RM) $@; echo "Downloading $@ failed"; false) +# Note: $(URL_NEWCOB_Z) is out-dated and simply grabs an HTML file +# without error. +# newcob.val.Z: +# @echo "Trying to download newcob.val.Z..." +# @(which curl 1>/dev/null && curl $(CURL_FLAGS) "$(URL_NEWCOB_Z)" -o $@) || \ +# wget $(WGET_FLAGS) "$(URL_NEWCOB_Z)" || \ +# ($(RM) $@; echo "Downloading $@ failed"; false) newcob.val.tar.gz: @echo "Trying to download newcob.val.tar.gz..." From 5a8666888fada0fdbbc904269ef809629fd93fbb Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Wed, 28 Aug 2024 08:31:07 +0000 Subject: [PATCH 19/51] Fix bugs reported by the MSVC runtime checker cobc: * tree.c (char_to_precedence_idx, get_char_type_description, valid_char_order): adjusted size of precedence table and gave proper precedence to U libcob: * intrinsics.c (cob_intr_random), move.c (cob_move_display_to_packed): make casts with loss of data explicit using masking to silence the MSVC runtime error checker --- cobc/ChangeLog | 9 ++++- cobc/tree.c | 71 +++++++++++++++++---------------- libcob/ChangeLog | 6 +++ libcob/intrinsic.c | 18 +++++---- libcob/move.c | 4 +- tests/testsuite.src/run_misc.at | 2 + 6 files changed, 64 insertions(+), 46 deletions(-) diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 4da9dad05..2cb212623 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,17 +1,22 @@ +2024-08-28 David Declerck + + * tree.c (char_to_precedence_idx, get_char_type_description, valid_char_order): + adjusted size of precedence table and gave proper precedence to U + 2024-08-06 Simon Sobisch * codegen.c (output_alphabet_name_definition): cater for national alphabet * typeck.c (validate_alphabet): speedup for alphabet checks * pplex.l (ppopen_get_file): explicit check for UTF16/UTF32 and hint to use iconv - + 2024-08-05 Simon Sobisch * typeck.c (validate_alphabet), tree.h (cb_alphabet_name): cater for national alphabets with increased size (max. 65535 instead of 255) * typeck.c (validate_alphabet): check that alphabet and literal types match - + 2024-07-29 Chuck Haatvedt * tree.c (cb_build_picture): added logic to find the valid floating diff --git a/cobc/tree.c b/cobc/tree.c index 5fc7c92e2..cb49c88c8 100644 --- a/cobc/tree.c +++ b/cobc/tree.c @@ -2940,14 +2940,14 @@ find_floating_insertion_str (const cob_pic_symbol *str, /* Number of character types in picture strings */ /* - The 25 character types are: - B , . + + + CR cs cs Z Z + + cs cs 9 A L S V P P 1 N E + The 26 character types are: + B , . + + + CR cs cs Z Z + + cs cs 9 A L S V P P 1 U N E 0 - - DB * * - - X / Duplicates indicate floating/non-floating insertion symbols and/or left/right of decimal point positon. */ -#define CB_PIC_CHAR_TYPES 25 +#define CB_PIC_CHAR_TYPES 26 #define CB_FIRST_NON_P_DIGIT_CHAR_TYPE 9 #define CB_LAST_NON_P_DIGIT_CHAR_TYPE 15 #define CB_PIC_S_CHAR_TYPE 18 @@ -3043,13 +3043,13 @@ char_to_precedence_idx (const cob_pic_symbol *str, case '1': return 22; - case 'N': + case 'U': return 23; - case 'E': + case 'N': return 24; - case 'U': + case 'E': return 25; default: @@ -3140,11 +3140,11 @@ get_char_type_description (const int idx) case 22: return "1"; case 23: - return "N"; + return "U"; case 24: - return "E"; + return "N"; case 25: - return "U"; + return "E"; default: return NULL; } @@ -3180,35 +3180,36 @@ valid_char_order (const cob_pic_symbol *str, const int s_char_seen, const unsign manual. */ /* - B , . + + + CR cs cs Z Z + + cs cs 9 A L S V P P 1 N E + B , . + + + CR cs cs Z Z + + cs cs 9 A L S V P P 1 U N E 0 - - DB * * - - X / */ - { 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0 }, - { 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0 }, - { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 }, - { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0 }, - { 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, - { 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0 }, - { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, - { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, - { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0 }, + { 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 }, + { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 }, + { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 }, + { 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }, + { 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, + { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; int error_emitted[CB_PIC_CHAR_TYPES][CB_PIC_CHAR_TYPES] = {{ 0 }}; int chars_seen[CB_PIC_CHAR_TYPES] = { 0 }; diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 408d6fe8b..31bc7a0db 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,10 @@ +2024-08-28 David Declerck + + * intrinsics.c (cob_intr_random), move.c (cob_move_display_to_packed): + make casts with loss of data explicit using masking to silence + the MSVC runtime error checker + 2024-08-22 David Declerck * common.c (DllMain) [_MSC_VER]: added calls to _CrtSetReportMode diff --git a/libcob/intrinsic.c b/libcob/intrinsic.c index e9c85c94a..785fa3b1b 100644 --- a/libcob/intrinsic.c +++ b/libcob/intrinsic.c @@ -5462,11 +5462,7 @@ cob_intr_random (const int params, ...) cob_field *f; va_list args; double val; -#ifdef DISABLE_GMP_RANDOM - unsigned int seed = 0; -#else - unsigned long seed = 0; -#endif + unsigned long seed = 0; cob_field_attr attr; cob_field field; @@ -5478,7 +5474,11 @@ cob_intr_random (const int params, ...) if (specified_seed < 0) { cob_set_exception (COB_EC_ARGUMENT_FUNCTION); } else { +#ifdef _WIN32 + seed = (unsigned long)(specified_seed & 0xFFFFFFFF); +#else seed = (unsigned long)specified_seed; +#endif } rand_needs_seeding++; #ifdef DISABLE_GMP_RANDOM @@ -5490,8 +5490,12 @@ cob_intr_random (const int params, ...) note: we need an explicit integer cast to get around some warnings, but then need a matching size to get around others...*/ #ifdef COB_64_BIT_POINTER - seed = get_seconds_past_midnight () - * (((cob_s64_t)COB_MODULE_PTR) & 0xFFFFF); + seed = (get_seconds_past_midnight () + #ifdef _WIN32 + * (((cob_s64_t)COB_MODULE_PTR) & 0xFFFFF)) & 0xFFFFFFFF; + #else + * (((cob_s64_t)COB_MODULE_PTR) & 0xFFFFF)); + #endif #else seed = get_seconds_past_midnight () * (((cob_s32_t)COB_MODULE_PTR) & 0xFFFF); diff --git a/libcob/move.c b/libcob/move.c index 795ce7846..053bbf246 100644 --- a/libcob/move.c +++ b/libcob/move.c @@ -630,7 +630,7 @@ cob_move_display_to_packed (cob_field *f1, cob_field *f2) while ((p < p_end) && (q <= q_end)) { - *q = (unsigned char) (*p << 4) /* -> dropping the higher bits = no use in COB_D2I */ + *q = (unsigned char) ((*p << 4) & 0xF0) /* -> dropping the higher bits = no use in COB_D2I */ + COB_D2I (*(p + 1)); p = p + 2; q++; @@ -644,7 +644,7 @@ cob_move_display_to_packed (cob_field *f1, cob_field *f2) if ((p == p_end) && (q <= q_end)) { - *q = (unsigned char) (*p << 4) & 0xF0; + *q = (unsigned char) ((*p << 4) & 0xF0); } COB_PUT_SIGN_ADJUSTED (f1, sign); diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 7ec0062f0..210a28758 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -11877,6 +11877,7 @@ CAPI (void *p1, ...) nargs = cob_get_num_params(); printf ("CAPI called with %d parameters\n",nargs); + fflush(stdout); for (k=1; k <= nargs; k++) { type = cob_get_param_type (k); digits = cob_get_param_digits (k); @@ -12112,6 +12113,7 @@ CAPI (void *p1, ...) nargs = cob_get_num_params(); printf ("CAPI called with %d parameters\n",nargs); + fflush(stdout); for (k=1; k <= nargs; k++) { cob_field *fld = cob_get_param_field (k, "CAPI"); type = cob_get_field_type (fld); From d3c4e188dd30ab0e20af0d15d5c72cf26e4daa4f Mon Sep 17 00:00:00 2001 From: David Declerck Date: Wed, 28 Aug 2024 11:54:02 +0200 Subject: [PATCH 20/51] Update MSVC CI --- .github/workflows/windows-msvc.yml | 48 +++++------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index 0bf82e5a4..e8fc76fd6 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -160,53 +160,19 @@ jobs: cd tests sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at + # Skip two tests that behave differently (fail or hand) 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: | cd tests - - sed -i '/AT_SETUP(\[MF FIGURATIVE to NUMERIC\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[Default file external name\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at - sed -i '/AT_SETUP(\[EXTFH: SEQUENTIAL files\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_file.at sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at - - sed -i '/AT_SETUP(\[MOVE to edited item (4)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[MOVE to item with simple and floating insertion\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[Numeric operations (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[Numeric operations (3) PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[DISPLAY with P fields\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[MOVE with de-editting to COMP-3\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[MOVE between USAGEs\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[Computing of different USAGEs w\/- decimal point\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[C-API (param based)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[C-API (field based)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[Default Arithmetic Test (2)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[OSVS Arithmetic Test (2)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[FUNCTION ACOS\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[FUNCTION ASIN\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[FUNCTION RANDOM\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[MOVE of non-integer to alphanumeric\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at - sed -i '/AT_SETUP(\[XML GENERATE trimming\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_ml.at - sed -i '/AT_SETUP(\[JSON GENERATE trimming\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_ml.at - sed -i '/AT_SETUP(\[MOVE PACKED-DECIMAL to BINARY\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_binary.at - sed -i '/AT_SETUP(\[PACKED-DECIMAL dump\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[PACKED-DECIMAL used with MOVE\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[MOVE PACKED-DECIMAL to PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[MOVE PACKED-DECIMAL to DISPLAY\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[MOVE DISPLAY to PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[PACKED-DECIMAL comparison\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[COMP-6 comparison\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[COMP-3 vs. COMP-6 - BCD comparison\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[PPP COMP-3\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[PPP COMP-6\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[MOVE between several BCD fields\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, DEFAULT ROUNDING MODE\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[CURRENCY SIGN WITH PICTURE SYMBOL\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - -# The tests in sed commands above randomly hang (under debug configurations) + sed -i '/AT_SETUP(\[PROGRAM COLLATING SEQUENCE\])/a AT_SKIP_IF(\[true\])' testsuite.src/syn_definition.at - name: Build testsuite shell: C:\shells\msys2bash.cmd {0} From d9ef15191468f765997b3151ec2f3730c155fd2d Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 20 Aug 2024 09:04:33 +0200 Subject: [PATCH 21/51] Upgrade versions of github actions used in CI --- .github/workflows/macos.yml | 30 +++++++++---------- .github/workflows/ubuntu.yml | 58 +++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index aa61cb3b2..d4886a656 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -24,7 +24,7 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install packages run: | @@ -55,44 +55,44 @@ jobs: - name: configure run: | cd _build - ../configure --enable-cobc-internal-checks --enable-hardening --prefix /opt/cobol/gnucobol-gcos --exec-prefix /opt/cobol/gnucobol-gcos + ../configure --enable-cobc-internal-checks \ + --enable-hardening \ + --prefix /opt/cobol/gnucobol-gcos \ + --exec-prefix /opt/cobol/gnucobol-gcos - name: Upload config.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: config.log + name: config-${{ matrix.os }}.log path: _build/config.log if: failure() - name: make run: | - cd _build - make --jobs=$((${NPROC}+1)) + make -C _build --jobs=$((${NPROC}+1)) # make install must be done before make check, otherwise execution of # generated COBOL files fail for a missing /usr/local/lib/libcob.dylib - name: make install run: | - cd _build - sudo make install - find /opt/cobol > install.log + sudo make -C _build install + find /opt/cobol > _build/install.log - name: Upload install.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: install.log + name: install-${{ matrix.os }}.log path: _build/install.log - name: check run: | - cd _build - make check TESTSUITEFLAGS="--jobs=$((${NPROC}+1))" + make -C _build check TESTSUITEFLAGS="--jobs=$((${NPROC}+1))" - name: Upload testsuite.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: - name: testsuite.log + name: testsuite-${{ matrix.os }}.log path: _build/tests/testsuite.log - name: Cache newcob.val.Z diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a16d542aa..b2015d801 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -25,7 +25,7 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install packages run: | @@ -65,20 +65,21 @@ jobs: - name: configure run: | cd _build - ../configure --enable-cobc-internal-checks --enable-hardening --prefix ${INSTALL_PATH} + ../configure --enable-cobc-internal-checks \ + --enable-hardening \ + --prefix ${INSTALL_PATH} echo "VERSION=PACKAGE_VERSION" | cpp -P -imacros config.h | tr -d \" >> $GITHUB_ENV - name: Upload config.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: - name: config.log + name: config-${{ matrix.os }}.log path: _build/config.log - name: make run: | - cd _build - make --jobs=$(($(nproc)+1)) + make -C _build --jobs=$(($(nproc)+1)) # - name: check # run: | @@ -88,19 +89,20 @@ jobs: # note: distcheck also creates the dist tarball - name: distcheck run: | - cd _build - make --jobs=$(($(nproc)+1)) distcheck TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" + make -C _build distcheck \ + TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" \ + --jobs=$(($(nproc)+1)) - name: Upload testsuite.log - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() with: # Assume there's only one directory matching `_build/gnucobol-*`: - name: testsuite.log + name: testsuite-${{ matrix.os }}.log path: _build/gnucobol-${{ env.VERSION }}/_build/sub/tests/testsuite.log - name: Upload dist tarball - uses: actions/upload-artifact@v3.1.0 + uses: actions/upload-artifact@v4 with: name: gnucobol-ci source distribution path: _build/gnucobol*.tar* @@ -127,17 +129,16 @@ jobs: ln -f newcob.val.Z.cached newcob.val.Z make EXEC85 && make --jobs=$(($(nproc)+1)) test - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: NIST85 results + name: NIST85 results on ${{ matrix.os }} path: | _build/tests/cobol85/**/*.log _build/tests/cobol85/**/*.out - name: install run: | - cd _build - make install + make -C _build install coverage: @@ -145,12 +146,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # note: less dependencies as we don't generate a dist tarball, one additional for lcov - name: Install dependencies run: | - sudo apt-get install automake libtool libdb5.3-dev libxml2-dev libcjson-dev bison flex help2man gettext lcov + sudo apt-get install automake libtool libdb5.3-dev libxml2-dev \ + libcjson-dev bison flex help2man gettext lcov - name: bootstrap run: | @@ -166,33 +168,33 @@ jobs: - name: configure run: | cd _build - ../configure --enable-code-coverage CPPFLAGS="-Werror=declaration-after-statement" + ../configure --enable-code-coverage \ + CPPFLAGS="-Werror=declaration-after-statement" - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: failure() with: - name: config.log + name: config-${{ matrix.os }}.log path: _build/config.log - name: make run: | - cd _build - make --jobs=$(($(nproc)+1)) + make -C _build --jobs=$(($(nproc)+1)) - name: coverage run: | - cd _build - make check-code-coverage TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" + make -C _build check-code-coverage \ + TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: failure() with: - name: testsuite.log + name: testsuite-${{ matrix.os }}.log path: _build/tests/testsuite.log - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: coverage + name: coverage-${{ matrix.os }} path: _build/GnuCOBOL-**-coverage/ - uses: codecov/codecov-action@v2 From dfb0c9c82f96ee8d95228fd84c5490100286e80a Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 20 Aug 2024 09:07:58 +0200 Subject: [PATCH 22/51] Swap install and tests in CI for Windows MSYS2 --- .github/workflows/windows-msys2.yml | 36 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 370ef71a1..6e2cf8240 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -75,41 +75,39 @@ jobs: - name: Build GnuCOBOL shell: msys2 {0} run: | - cd _build - make --jobs=$(($(nproc)+1)) + make -C _build --jobs=$(($(nproc)+1)) - - name: Install GnuCOBOL + - name: Run testuite shell: msys2 {0} run: | - cd _build - make install - find /opt/cobol > install.log + sed '/AT_SETUP(\[temporary path invalid\])/a \ + AT_SKIP_IF(\[true\])' \ + -i tests/testsuite.src/used_binaries.at + make -C _build/tests check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" + make -C _build/tests test - - name: Upload install-${{ matrix.target }}.log + - name: Upload testsuite-${{ matrix.target }}.log uses: actions/upload-artifact@v4 with: - name: install-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log + name: testsuite-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log - - name: Run testuite + - name: Install GnuCOBOL shell: msys2 {0} run: | - sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/used_binaries.at - cd _build/tests - make check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" - make test + make -C _build install + find /opt/cobol > _build/install.log - - name: Upload testsuite-${{ matrix.target }}.log + - name: Upload install-${{ matrix.target }}.log uses: actions/upload-artifact@v4 with: - name: testsuite-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log + name: install-${{ matrix.target }}.log + path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log - name: Package GnuCOBOL shell: msys2 {0} run: | - cd _build - make distmingw + make -C _build distmingw - name: Upload GnuCOBOL_mingw-${{ matrix.target }} uses: actions/upload-artifact@v4 From c1665fc6e603e4117bbc52a28dc93457284668ce Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Fri, 23 Aug 2024 10:30:16 +0200 Subject: [PATCH 23/51] Adjust MSVC workflow now that error popups are disabled by default --- .github/workflows/windows-msvc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index e8fc76fd6..1073acefc 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -196,6 +196,7 @@ jobs: autom4te --lang=autotest -I ./testsuite.src ./testsuite.at -o ./testsuite - name: Run testsuite + continue-on-error: ${{ matrix.target == 'Debug' }} run: | cd tests set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" From 803826741663820d5785570c828f1fd1a2165792 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 21 Aug 2024 16:40:49 +0200 Subject: [PATCH 24/51] Further CI adjustments --- .github/workflows/macos.yml | 8 ++-- .github/workflows/ubuntu.yml | 27 +++++------- .github/workflows/windows-msvc.yml | 1 - .github/workflows/windows-msys1.yml | 1 - .github/workflows/windows-msys2.yml | 65 +++++++++++++---------------- 5 files changed, 43 insertions(+), 59 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index d4886a656..5e88ce185 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -4,7 +4,6 @@ on: pull_request: branches: [ gcos4gnucobol-3.x ] push: - branches: [ gcos4gnucobol-3.x ] # manual run in actions tab - for all branches workflow_dispatch: @@ -14,7 +13,8 @@ jobs: fail-fast: false matrix: os: - - macos-latest + # - macos-latest-large # macos 14, amd64 + - macos-latest # macos 14, arm64 runs-on: ${{ matrix.os }} @@ -41,9 +41,7 @@ jobs: - name: bootstrap run: | - ./autogen.sh - autoconf - autoreconf --install --force + ./build_aux/bootstrap install - name: Build environment setup run: | diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index b2015d801..daf9c13ef 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -4,7 +4,6 @@ on: pull_request: branches: [ gcos4gnucobol-3.x ] push: - branches: [ gcos4gnucobol-3.x ] # manual run in actions tab - for all branches workflow_dispatch: @@ -30,7 +29,8 @@ jobs: - name: Install packages run: | sudo apt-get update - sudo apt-get install automake libtool libdb5.3-dev libxml2-dev libcjson-dev bison flex help2man gettext texlive + sudo apt-get install automake libtool libdb5.3-dev libxml2-dev libcjson-dev \ + bison flex help2man gettext texlive - name: Set git user run: | @@ -68,7 +68,8 @@ jobs: ../configure --enable-cobc-internal-checks \ --enable-hardening \ --prefix ${INSTALL_PATH} - echo "VERSION=PACKAGE_VERSION" | cpp -P -imacros config.h | tr -d \" >> $GITHUB_ENV + echo "VERSION=PACKAGE_VERSION" | cpp -P -imacros config.h | tr -d \" \ + >> $GITHUB_ENV - name: Upload config.log uses: actions/upload-artifact@v4 @@ -81,17 +82,14 @@ jobs: run: | make -C _build --jobs=$(($(nproc)+1)) - # - name: check - # run: | - # cd _build - # make check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" - # note: distcheck also creates the dist tarball - name: distcheck run: | - make -C _build distcheck \ - TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" \ - --jobs=$(($(nproc)+1)) + make -C _build distcheck \ + TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" \ + --jobs=$(($(nproc)+1)) || \ + make -C _build/gnucobol-$VERSION/_build/sub/tests check \ + TESTSUITEFLAGS="--recheck --verbose" - name: Upload testsuite.log uses: actions/upload-artifact@v4 @@ -136,10 +134,6 @@ jobs: _build/tests/cobol85/**/*.log _build/tests/cobol85/**/*.out - - name: install - run: | - make -C _build install - coverage: name: Coverage and Warnings @@ -169,7 +163,8 @@ jobs: run: | cd _build ../configure --enable-code-coverage \ - CPPFLAGS="-Werror=declaration-after-statement" + CPPFLAGS="-Werror=declaration-after-statement -pedantic" \ + CC="gcc -std=c89" - uses: actions/upload-artifact@v4 if: failure() diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index 1073acefc..dc20463a1 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -4,7 +4,6 @@ on: pull_request: branches: [ gcos4gnucobol-3.x ] push: - branches: [ gcos4gnucobol-3.x ] # manual run in actions tab - for all branches workflow_dispatch: diff --git a/.github/workflows/windows-msys1.yml b/.github/workflows/windows-msys1.yml index 2fa32a692..13df5f2fe 100644 --- a/.github/workflows/windows-msys1.yml +++ b/.github/workflows/windows-msys1.yml @@ -4,7 +4,6 @@ on: pull_request: branches: [ gcos4gnucobol-3.x ] push: - branches: [ gcos4gnucobol-3.x ] # manual run in actions tab - for all branches workflow_dispatch: diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 6e2cf8240..6b44890eb 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -4,7 +4,6 @@ on: pull_request: branches: [ gcos4gnucobol-3.x ] push: - branches: [ gcos4gnucobol-3.x ] # manual run in actions tab - for all branches workflow_dispatch: @@ -13,15 +12,13 @@ jobs: strategy: fail-fast: false matrix: - os: - - windows-latest - arch: - - x64 - target: - - debug - - release - - runs-on: ${{ matrix.os }} + include: + - { os: windows-latest, target: release, sys: mingw64, env: x86_64 } + - { os: windows-latest, target: debug, sys: mingw64, env: x86_64 } + - { os: windows-latest, target: debug, sys: ucrt64, env: ucrt-x86_64 } + - { os: windows-latest, target: debug, sys: clang64, env: clang-x86_64 } + # - { target: debug, sys: mingw32, env: i686 } + runs-on: ${{matrix.os}} steps: @@ -44,19 +41,24 @@ jobs: echo CFGOPT="--enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV } - - name: Install MSYS2 packages + - name: Install packages uses: msys2/setup-msys2@v2 with: update: true - msystem: ucrt64 - install: autoconf automake libtool make mingw-w64-ucrt-x86_64-ncurses mingw-w64-ucrt-x86_64-libxml2 mingw-w64-ucrt-x86_64-cjson mingw-w64-ucrt-x86_64-db mingw-w64-ucrt-x86_64-gmp libdb-devel mingw-w64-ucrt-x86_64-gcc flex bison gmp-devel help2man texinfo gettext-devel + msystem: ${{matrix.sys}} + install: autoconf automake libtool make flex bison help2man texinfo + mingw-w64-${{matrix.env}}-cc + mingw-w64-${{matrix.env}}-gmp gmp-devel + mingw-w64-${{matrix.env}}-gettext-runtime gettext-devel + mingw-w64-${{matrix.env}}-ncurses + mingw-w64-${{matrix.env}}-libxml2 + mingw-w64-${{matrix.env}}-cjson + mingw-w64-${{matrix.env}}-db libdb-devel - name: Bootstrap GnuCOBOL shell: msys2 {0} run: | - ./autogen.sh - autoconf - autoreconf --install --force + ./build_aux/bootstrap install - name: Configure GnuCOBOL shell: msys2 {0} @@ -65,11 +67,11 @@ jobs: cd _build ../configure $CFGOPT --with-db --prefix=/opt/cobol/gnucobol - - name: Upload config-${{ matrix.target }}.log + - name: Upload config-${{matrix.sys}}-${{matrix.target}}.log uses: actions/upload-artifact@v4 if: failure() with: - name: config-${{ matrix.target }}.log + name: config-${{matrix.sys}}-${{matrix.target}}.log path: ${{ env.GITHUB_WORKSPACE }}/_build/config.log - name: Build GnuCOBOL @@ -83,34 +85,25 @@ jobs: sed '/AT_SETUP(\[temporary path invalid\])/a \ AT_SKIP_IF(\[true\])' \ -i tests/testsuite.src/used_binaries.at - make -C _build/tests check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" - make -C _build/tests test + make -C _build/tests checkall \ + --jobs=$(($(nproc)+1)) \ + TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || \ + make -C _build/tests check \ + TESTSUITEFLAGS="--recheck --verbose" - - name: Upload testsuite-${{ matrix.target }}.log + - name: Upload testsuite-${{matrix.sys}}-${{matrix.target}}.log uses: actions/upload-artifact@v4 with: - name: testsuite-${{ matrix.target }}.log + name: testsuite-${{matrix.sys}}-${{matrix.target}}.log path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log - - name: Install GnuCOBOL - shell: msys2 {0} - run: | - make -C _build install - find /opt/cobol > _build/install.log - - - name: Upload install-${{ matrix.target }}.log - uses: actions/upload-artifact@v4 - with: - name: install-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log - - name: Package GnuCOBOL shell: msys2 {0} run: | make -C _build distmingw - - name: Upload GnuCOBOL_mingw-${{ matrix.target }} + - name: Upload GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}} uses: actions/upload-artifact@v4 with: - name: GnuCOBOL_mingw-${{ matrix.target }} + name: GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}} path: ${{ env.GITHUB_WORKSPACE }}/_build/${{ env.DISTDIR }} From d45913dd76da5d3307e9bbc6fbe7bfababf210b6 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Mon, 26 Aug 2024 11:04:59 +0200 Subject: [PATCH 25/51] Enforce a 45 minutes timeout on Windows CI workflows --- .github/workflows/windows-msvc.yml | 2 +- .github/workflows/windows-msys1.yml | 2 +- .github/workflows/windows-msys2.yml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index dc20463a1..fec5ba697 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -41,8 +41,8 @@ jobs: target: - Debug - Release - runs-on: ${{ matrix.os }} + timeout-minutes: 45 steps: diff --git a/.github/workflows/windows-msys1.yml b/.github/workflows/windows-msys1.yml index 13df5f2fe..661344910 100644 --- a/.github/workflows/windows-msys1.yml +++ b/.github/workflows/windows-msys1.yml @@ -40,8 +40,8 @@ jobs: target: - debug - release - runs-on: ${{ matrix.os }} + timeout-minutes: 45 steps: diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 6b44890eb..1b3777799 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -19,6 +19,7 @@ jobs: - { os: windows-latest, target: debug, sys: clang64, env: clang-x86_64 } # - { target: debug, sys: mingw32, env: i686 } runs-on: ${{matrix.os}} + timeout-minutes: 45 steps: From fed0e25ca1f968c0d78effdd8e1b3e53959016fb Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 27 Aug 2024 09:23:07 +0200 Subject: [PATCH 26/51] Further adjustments to the CI for MacOS --- .github/workflows/macos.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 5e88ce185..7260b5d23 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -56,7 +56,6 @@ jobs: ../configure --enable-cobc-internal-checks \ --enable-hardening \ --prefix /opt/cobol/gnucobol-gcos \ - --exec-prefix /opt/cobol/gnucobol-gcos - name: Upload config.log uses: actions/upload-artifact@v4 @@ -69,8 +68,9 @@ jobs: run: | make -C _build --jobs=$((${NPROC}+1)) -# make install must be done before make check, otherwise execution of -# generated COBOL files fail for a missing /usr/local/lib/libcob.dylib + # make install must be done before make check, otherwise + # execution of generated COBOL files fail for a missing + # /usr/local/lib/libcob.dylib - name: make install run: | sudo make -C _build install @@ -84,7 +84,8 @@ jobs: - name: check run: | - make -C _build check TESTSUITEFLAGS="--jobs=$((${NPROC}+1))" + make -C _build check \ + TESTSUITEFLAGS="--jobs=$((${NPROC}+1))" - name: Upload testsuite.log uses: actions/upload-artifact@v4 From 5be2d04b849265806d602fb2a2d4acefdfe402df Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 27 Aug 2024 11:50:47 +0200 Subject: [PATCH 27/51] Stop using `-pedantic` flag in Coverage and Warnings workflow --- .github/workflows/ubuntu.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index daf9c13ef..6e815cc06 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -158,12 +158,15 @@ jobs: export TERM="vt100" echo "TERM=$TERM" >> $GITHUB_ENV - # note: w add additional C compiler syntax checks here to not need _another_ CI run + # note: add additional C compiler syntax checks here to not need + # _another_ CI run + # + # TODO: try and pass -pedantic via CPPFLAGS - name: configure run: | cd _build ../configure --enable-code-coverage \ - CPPFLAGS="-Werror=declaration-after-statement -pedantic" \ + CPPFLAGS="-Werror=declaration-after-statement" \ CC="gcc -std=c89" - uses: actions/upload-artifact@v4 From 34d0bd4b354ffde3b12bd114044b6ca32bb878fe Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 27 Aug 2024 11:51:17 +0200 Subject: [PATCH 28/51] Various improvements in Warnings and Coverage workflow --- .github/workflows/ubuntu.yml | 103 ++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 6e815cc06..4a3f1e8bc 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -13,12 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: - - ubuntu-latest - include: - - os: ubuntu-latest - skip_test: true - + os: [ ubuntu-latest ] runs-on: ${{ matrix.os }} steps: @@ -37,7 +32,7 @@ jobs: git config --global user.name github-actions git config --global user.email github-actions-bot@users.noreply.github.com - - name: bootstrap + - name: Bootstrap run: | ./build_aux/bootstrap @@ -62,7 +57,7 @@ jobs: echo "TERM=$TERM" >> $GITHUB_ENV echo "INSTALL_PATH=$(pwd)/_install" >> $GITHUB_ENV - - name: configure + - name: Configure run: | cd _build ../configure --enable-cobc-internal-checks \ @@ -78,12 +73,12 @@ jobs: name: config-${{ matrix.os }}.log path: _build/config.log - - name: make + - name: Build run: | make -C _build --jobs=$(($(nproc)+1)) # note: distcheck also creates the dist tarball - - name: distcheck + - name: Build distribution archive & run tests run: | make -C _build distcheck \ TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" \ @@ -107,27 +102,30 @@ jobs: if-no-files-found: error retention-days: 0 - - name: Cache newcob.val.Z - uses: actions/cache@v3 + - name: Cache newcob.val.tar.gz + uses: actions/cache@v4 id: newcob with: - path: _build/tests/cobol85/newcob.val.Z.cached + path: tests/cobol85/newcob.val.tar.gz.cached key: newcob + save-always: true - - name: Download newcob.val.Z + - name: Download newcob.val.tar.gz if: steps.newcob.outputs.cache-hit != 'true' run: | - cd _build/tests/cobol85 - make newcob.val.Z - ln -f newcob.val.Z newcob.val.Z.cached + make -C _build/tests/cobol85 newcob.val.tar.gz + ln -f _build/tests/cobol85/newcob.val.tar.gz \ + tests/cobol85/newcob.val.tar.gz.cached - name: NIST85 Test Suite run: | - cd _build/tests/cobol85 - ln -f newcob.val.Z.cached newcob.val.Z - make EXEC85 && make --jobs=$(($(nproc)+1)) test + ln -f tests/cobol85/newcob.val.tar.gz.cached \ + tests/cobol85/newcob.val.tar.gz + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) - - uses: actions/upload-artifact@v4 + - name: Upload NIST85 Test Suite results + uses: actions/upload-artifact@v4 with: name: NIST85 results on ${{ matrix.os }} path: | @@ -140,7 +138,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 # note: less dependencies as we don't generate a dist tarball, one additional for lcov - name: Install dependencies @@ -148,7 +147,7 @@ jobs: sudo apt-get install automake libtool libdb5.3-dev libxml2-dev \ libcjson-dev bison flex help2man gettext lcov - - name: bootstrap + - name: Bootstrap run: | ./build_aux/bootstrap @@ -162,40 +161,80 @@ jobs: # _another_ CI run # # TODO: try and pass -pedantic via CPPFLAGS - - name: configure + - name: Configure run: | cd _build ../configure --enable-code-coverage \ CPPFLAGS="-Werror=declaration-after-statement" \ CC="gcc -std=c89" - - uses: actions/upload-artifact@v4 + - name: Upload config.log + uses: actions/upload-artifact@v4 if: failure() with: name: config-${{ matrix.os }}.log path: _build/config.log - - name: make + - name: Build run: | make -C _build --jobs=$(($(nproc)+1)) - - name: coverage + - name: Coverage run: | - make -C _build check-code-coverage \ + # make -C _build check-code-coverage # <- (ignores errors) + make -C _build check \ TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" + make -C _build code-coverage-capture \ + CODE_COVERAGE_DIRECTORY="$(realpath .)/_build" - - uses: actions/upload-artifact@v4 + - name: Upload testsuite.log + uses: actions/upload-artifact@v4 if: failure() with: name: testsuite-${{ matrix.os }}.log path: _build/tests/testsuite.log - - uses: actions/upload-artifact@v4 + - name: Upload coverage report + uses: actions/upload-artifact@v4 with: name: coverage-${{ matrix.os }} - path: _build/GnuCOBOL-**-coverage/ + path: _build/GnuCOBOL-**-coverage + + - name: Cache newcob.val.tar.gz + uses: actions/cache@v4 + id: newcob + with: + path: tests/cobol85/newcob.val.tar.gz.cached + key: newcob + save-always: true + + - name: Download newcob.val.tar.gz + if: steps.newcob.outputs.cache-hit != 'true' + run: | + make -C _build/tests/cobol85 newcob.val.tar.gz + ln -f _build/tests/cobol85/newcob.val.tar.gz \ + tests/cobol85/newcob.val.tar.gz.cached + + - name: Extended coverage + run: | + ln -f tests/cobol85/newcob.val.tar.gz.cached \ + tests/cobol85/newcob.val.tar.gz + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) \ + --keep-going + make -C _build code-coverage-capture \ + CODE_COVERAGE_OUTPUT_DIRECTORY=extended-coverage \ + CODE_COVERAGE_OUTPUT_FILE=extended-coverage.info \ + CODE_COVERAGE_DIRECTORY="$(realpath .)/_build" + + - name: Upload extended coverage report + uses: actions/upload-artifact@v4 + with: + name: extended-coverage-${{ matrix.os }} + path: _build/extended-coverage - - uses: codecov/codecov-action@v2 + - name: Upload coverage to codecov + uses: codecov/codecov-action@v2 with: # token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos directory: _build From e14cfcae03c249650a3ba2ce7a24ded1f9ef2c91 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Tue, 27 Aug 2024 12:00:16 +0200 Subject: [PATCH 29/51] Fix lookup of `newcob.val` in MacOS workflow Note: https://www.itl.nist.gov/div897/ctg/suites/newcob.val.Z does not seem available anymore. --- .github/workflows/macos.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7260b5d23..62b8f5fa3 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -94,22 +94,24 @@ jobs: name: testsuite-${{ matrix.os }}.log path: _build/tests/testsuite.log - - name: Cache newcob.val.Z - uses: actions/cache@v3 + - name: Cache newcob.val.tar.gz + uses: actions/cache@v4 id: newcob with: - path: _build/tests/cobol85/newcob.val.Z.cached + path: tests/cobol85/newcob.val.tar.gz.cached key: newcob + save-always: true - - name: Download newcob.val.Z + - name: Download newcob.val.tar.gz if: steps.newcob.outputs.cache-hit != 'true' run: | - cd _build/tests/cobol85 - make newcob.val.Z - ln -f newcob.val.Z newcob.val.Z.cached + make -C _build/tests/cobol85 newcob.val.tar.gz + ln -f _build/tests/cobol85/newcob.val.tar.gz \ + tests/cobol85/newcob.val.tar.gz.cached - name: NIST85 Test Suite run: | - cd _build/tests/cobol85 - ln -f newcob.val.Z.cached newcob.val.Z - make EXEC85 && make --jobs=$(($(nproc)+1)) test + ln -f tests/cobol85/newcob.val.tar.gz.cached \ + tests/cobol85/newcob.val.tar.gz + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) From d4ea52e5afb03c68281d9ce6419be62cf78bc7d3 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 28 Aug 2024 08:46:14 +0200 Subject: [PATCH 30/51] Cache `newcob.val` instead of an archive --- .github/workflows/macos.yml | 18 ++++-------------- .github/workflows/ubuntu.yml | 32 ++++++-------------------------- 2 files changed, 10 insertions(+), 40 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 62b8f5fa3..92a0bdd6d 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -94,24 +94,14 @@ jobs: name: testsuite-${{ matrix.os }}.log path: _build/tests/testsuite.log - - name: Cache newcob.val.tar.gz + - name: Cache newcob.val uses: actions/cache@v4 - id: newcob with: - path: tests/cobol85/newcob.val.tar.gz.cached - key: newcob + path: _build/tests/cobol85/newcob.val + key: newcob-val save-always: true - - name: Download newcob.val.tar.gz - if: steps.newcob.outputs.cache-hit != 'true' - run: | - make -C _build/tests/cobol85 newcob.val.tar.gz - ln -f _build/tests/cobol85/newcob.val.tar.gz \ - tests/cobol85/newcob.val.tar.gz.cached - - name: NIST85 Test Suite run: | - ln -f tests/cobol85/newcob.val.tar.gz.cached \ - tests/cobol85/newcob.val.tar.gz make -C _build/tests/cobol85 EXEC85 test \ - --jobs=$(($(nproc)+1)) + --jobs=$((${NPROC}+1)) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 4a3f1e8bc..24493570e 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -102,25 +102,15 @@ jobs: if-no-files-found: error retention-days: 0 - - name: Cache newcob.val.tar.gz + - name: Cache newcob.val uses: actions/cache@v4 - id: newcob with: - path: tests/cobol85/newcob.val.tar.gz.cached - key: newcob + path: _build/tests/cobol85/newcob.val + key: newcob-val save-always: true - - name: Download newcob.val.tar.gz - if: steps.newcob.outputs.cache-hit != 'true' - run: | - make -C _build/tests/cobol85 newcob.val.tar.gz - ln -f _build/tests/cobol85/newcob.val.tar.gz \ - tests/cobol85/newcob.val.tar.gz.cached - - name: NIST85 Test Suite run: | - ln -f tests/cobol85/newcob.val.tar.gz.cached \ - tests/cobol85/newcob.val.tar.gz make -C _build/tests/cobol85 EXEC85 test \ --jobs=$(($(nproc)+1)) @@ -200,25 +190,15 @@ jobs: name: coverage-${{ matrix.os }} path: _build/GnuCOBOL-**-coverage - - name: Cache newcob.val.tar.gz + - name: Cache newcob.val uses: actions/cache@v4 - id: newcob with: - path: tests/cobol85/newcob.val.tar.gz.cached - key: newcob + path: _build/tests/cobol85/newcob.val + key: newcob-val save-always: true - - name: Download newcob.val.tar.gz - if: steps.newcob.outputs.cache-hit != 'true' - run: | - make -C _build/tests/cobol85 newcob.val.tar.gz - ln -f _build/tests/cobol85/newcob.val.tar.gz \ - tests/cobol85/newcob.val.tar.gz.cached - - name: Extended coverage run: | - ln -f tests/cobol85/newcob.val.tar.gz.cached \ - tests/cobol85/newcob.val.tar.gz make -C _build/tests/cobol85 EXEC85 test \ --jobs=$(($(nproc)+1)) \ --keep-going From 77522f50e0abb625ed2cca85c7a054786e14d888 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 28 Aug 2024 12:02:11 +0200 Subject: [PATCH 31/51] Run testsuite even on Debug target in Windows MSVC CI --- .github/workflows/windows-msvc.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index fec5ba697..134e7f18c 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -195,7 +195,6 @@ jobs: autom4te --lang=autotest -I ./testsuite.src ./testsuite.at -o ./testsuite - name: Run testsuite - continue-on-error: ${{ matrix.target == 'Debug' }} run: | cd tests set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" From c566c4abc0f46ceec1d19eb088baf0d1765bd2ce Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 28 Aug 2024 13:21:39 +0200 Subject: [PATCH 32/51] Cache `newcob.val` in Windows MSYS2 workflow as well --- .github/workflows/macos.yml | 1 + .github/workflows/ubuntu.yml | 2 ++ .github/workflows/windows-msys2.yml | 8 ++++++++ 3 files changed, 11 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 92a0bdd6d..7115b1f94 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -100,6 +100,7 @@ jobs: path: _build/tests/cobol85/newcob.val key: newcob-val save-always: true + enableCrossOsArchive: true - name: NIST85 Test Suite run: | diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 24493570e..edc22687c 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -108,6 +108,7 @@ jobs: path: _build/tests/cobol85/newcob.val key: newcob-val save-always: true + enableCrossOsArchive: true - name: NIST85 Test Suite run: | @@ -196,6 +197,7 @@ jobs: path: _build/tests/cobol85/newcob.val key: newcob-val save-always: true + enableCrossOsArchive: true - name: Extended coverage run: | diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 1b3777799..9652b5f29 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -80,6 +80,14 @@ jobs: run: | make -C _build --jobs=$(($(nproc)+1)) + - name: Cache newcob.val + uses: actions/cache@v4 + with: + path: _build/tests/cobol85/newcob.val + key: newcob-val + save-always: true + enableCrossOsArchive: true + - name: Run testuite shell: msys2 {0} run: | From e31b1ad2059a1f8b1b0c36d528ca1ef50d9ca176 Mon Sep 17 00:00:00 2001 From: Nicolas Berthier Date: Wed, 28 Aug 2024 15:14:39 +0200 Subject: [PATCH 33/51] Tar MSYS2 distribution archive to avoid EMFILE error --- .github/workflows/windows-msys2.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 9652b5f29..f2b5c13e9 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -111,8 +111,15 @@ jobs: run: | make -C _build distmingw - - name: Upload GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}} + - name: Tar GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}} + shell: msys2 {0} + run: | + cd _build + tar -cvf ../GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar \ + "${{ env.DISTDIR }}" + + - name: Upload GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar uses: actions/upload-artifact@v4 with: - name: GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}} - path: ${{ env.GITHUB_WORKSPACE }}/_build/${{ env.DISTDIR }} + name: GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar + path: GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar From 42d9e7de0eb8c898cb0e4f13d6cef81319667c33 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Fri, 6 Sep 2024 08:53:40 +0000 Subject: [PATCH 34/51] missing changelog entry for [r4915] --- bin/ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/ChangeLog b/bin/ChangeLog index acf8a135a..69bc366d7 100644 --- a/bin/ChangeLog +++ b/bin/ChangeLog @@ -9,6 +9,10 @@ * cob-config.in: echo in same order as arguments; add missing arguments (--bindir,--libdir,--datadir,--mandir,--includedir) +2023-01-02 Simon Sobisch + + * cobcrun.c: use libcob's cob_getenv_direct instead of getenv + 2022-10-18 Simon Sobisch * cobcrun.c: minor validation - check for empty parameters From 9744112d55609a6f9ac5992c49a4716db3200a29 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Sat, 7 Sep 2024 11:30:35 +0000 Subject: [PATCH 35/51] build system update build_aux: * ar-lib, config.guess, config.rpath, config.sub, texinfo.tex: updated to recent versions from https://git.savannah.gnu.org/cgit/gnulib.git/tree/build-aux/ configure: re-ordered gettext/conv checks --- build_aux/ChangeLog | 12 +- build_aux/ar-lib | 14 +- build_aux/config.guess | 71 +++- build_aux/config.rpath | 89 +++- build_aux/config.sub | 935 ++++++++++++++++++++++++++++++----------- build_aux/texinfo.tex | 542 ++++++++++++++---------- configure.ac | 73 ++-- 7 files changed, 1203 insertions(+), 533 deletions(-) diff --git a/build_aux/ChangeLog b/build_aux/ChangeLog index 667d414b0..1e84a10ea 100644 --- a/build_aux/ChangeLog +++ b/build_aux/ChangeLog @@ -1,4 +1,10 @@ +2024-09-02 Simon Sobisch + + * ar-lib, config.guess, config.rpath, config.sub, texinfo.tex: updated + to recent versions from + https://git.savannah.gnu.org/cgit/gnulib.git/tree/build-aux/ + 2023-06-03 Simon Sobisch * config.sub, texinfo.tex: updated to recent versions from @@ -22,13 +28,13 @@ * bootstrap: drop tarstamp.h generation, done via make * config.guess, config.sub: updated to recent versions from - git.savannah.gnu.org/gitweb/?p=config.git + https://git.savannah.gnu.org/cgit/config.git 2022-06-30 Simon Sobisch * config.guess, config.rpath, install-sh, mkinstalldirs, texinfo.tex: updated to recent versions from - git.savannah.gnu.org/gitweb/?p=config.git + https://git.savannah.gnu.org/cgit/config.git 2022-05-30 Simon Sobisch @@ -43,7 +49,7 @@ 2022-01-07 Simon Sobisch * config.sub, config.guess: updated to recent versions from - git.savannah.gnu.org/gitweb/?p=config.git to solve build issues + https://git.savannah.gnu.org/cgit/config.git to solve build issues on different machines 2021-10-11 Simon Sobisch diff --git a/build_aux/ar-lib b/build_aux/ar-lib index be8806a2f..7fbce26f0 100755 --- a/build_aux/ar-lib +++ b/build_aux/ar-lib @@ -2,9 +2,9 @@ # Wrapper for Microsoft lib.exe me=ar-lib -scriptversion=2019-07-04.01; # UTC +scriptversion=2024-06-19.01; # UTC -# Copyright (C) 2010-2019 Free Software Foundation, Inc. +# Copyright (C) 2010-2019,2024 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify @@ -105,11 +105,15 @@ case $1 in Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...] Members may be specified in a file named with @FILE. + +Report bugs to . +GNU Automake home page: . +General help using GNU software: . EOF exit $? ;; -v | --v*) - echo "$me, version $scriptversion" + echo "$me (GNU Automake) $scriptversion" exit $? ;; esac @@ -135,6 +139,10 @@ do AR="$AR $1" shift ;; + -nologo | -NOLOGO) + # We always invoke AR with -nologo, so don't need to add it again. + shift + ;; *) action=$1 shift diff --git a/build_aux/config.guess b/build_aux/config.guess index 980b02083..48a684601 100755 --- a/build_aux/config.guess +++ b/build_aux/config.guess @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-09-17' +timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ GUESS= # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -123,7 +123,7 @@ set_cc_for_build() { dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c89 c99 ; do + for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break @@ -155,6 +155,9 @@ Linux|GNU|GNU/*) set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ Linux|GNU|GNU/*) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ Linux|GNU|GNU/*) LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -628,7 +634,8 @@ EOF sed 's/^ //' << EOF > "$dummy.c" #include - main() + int + main () { if (!__power_pc()) exit(1); @@ -712,7 +719,8 @@ EOF #include #include - int main () + int + main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); @@ -904,7 +912,7 @@ EOF fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -976,7 +984,27 @@ EOF GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1042,6 +1070,15 @@ EOF k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; @@ -1197,7 +1234,7 @@ EOF GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1338,7 +1375,7 @@ EOF GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1560,6 +1597,9 @@ EOF *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? @@ -1583,6 +1623,7 @@ cat > "$dummy.c" <, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# -# The first argument passed to this file is the canonical host specification, -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld -# should be set by the caller. -# -# The set of defined variables is at the end of this script. # Known limitations: # - On IRIX 6.5 with CC="cc", the run time search patch must not be longer @@ -25,6 +17,81 @@ # known workaround is to choose shorter directory names for the build # directory and/or the installation directory. +# func_usage +# outputs to stdout the --help usage message. +func_usage () +{ + echo "\ +Usage: config.rpath [OPTION] HOST + +Prints shell variable assignments that describe how to hardcode a directory +for the lookup of shared libraries into a binary (executable or shared library). + +The first argument passed to this file is the canonical host specification, + CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +or + CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + +The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +should be set by the caller. + +The set of defined variables is at the end of this script. + +Options: + --help print this help and exit + --version print version information and exit + +Send patches and bug reports to ." +} + +# func_version +# outputs to stdout the --version message. +func_version () +{ + echo "config.rpath (GNU gnulib, module havelib)" + echo "Copyright (C) 2024 Free Software Foundation, Inc. +License: All-Permissive. +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law." + echo + printf 'Written by %s.\n' "Bruno Haible" +} + +# func_fatal_error message +# outputs to stderr a fatal error message, and terminates the program. +func_fatal_error () +{ + echo "config.rpath: *** $1" 1>&2 + echo "config.rpath: *** Stop." 1>&2 + exit 1 +} + +# Command-line option processing. +while test $# -gt 0; do + case "$1" in + --help | --hel | --he | --h ) + func_usage + exit 0 ;; + --version | --versio | --versi | --vers | --ver | --ve | --v ) + func_version + exit 0 ;; + -- ) # Stop option processing + shift; break ;; + -* ) + func_fatal_error "unrecognized option: $1" + ;; + * ) + break ;; + esac +done + +if test $# -gt 1; then + func_fatal_error "too many arguments" +fi +if test $# -lt 1; then + func_fatal_error "too few arguments" +fi + # All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a diff --git a/build_aux/config.sub b/build_aux/config.sub index de4259e40..4aaae46f6 100755 --- a/build_aux/config.sub +++ b/build_aux/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2023 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. -# shellcheck disable=SC2006,SC2268 # see below for rationale +# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale -timestamp='2023-01-21' +timestamp='2024-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2023 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -120,7 +120,6 @@ case $# in esac # Split fields of configuration type -# shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -142,10 +141,21 @@ case $1 in # parts maybe_os=$field2-$field3 case $maybe_os in - nto-qnx* | linux-* | uclinux-uclibc* \ - | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ - | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova* | managarm-*) + cloudabi*-eabi* \ + | kfreebsd*-gnu* \ + | knetbsd*-gnu* \ + | kopensolaris*-gnu* \ + | linux-* \ + | managarm-* \ + | netbsd*-eabi* \ + | netbsd*-gnu* \ + | nto-qnx* \ + | os2-emx* \ + | rtmk-nova* \ + | storm-chaos* \ + | uclinux-gnu* \ + | uclinux-uclibc* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -160,8 +170,12 @@ case $1 in esac ;; *-*) - # A lone config we happen to match not fitting any pattern case $field1-$field2 in + # Shorthands that happen to contain a single dash + convex-c[12] | convex-c3[248]) + basic_machine=$field2-convex + basic_os= + ;; decstation-3100) basic_machine=mips-dec basic_os= @@ -169,28 +183,88 @@ case $1 in *-*) # Second component is usually, but not always the OS case $field2 in - # Prevent following clause from handling this valid os + # Do not treat sunos as a manufacturer sun*os*) basic_machine=$field1 basic_os=$field2 ;; - zephyr*) - basic_machine=$field1-unknown - basic_os=$field2 - ;; # Manufacturers - dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ - | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ - | unicom* | ibm* | next | hp | isi* | apollo | altos* \ - | convergent* | ncr* | news | 32* | 3600* | 3100* \ - | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ - | ultra | tti* | harris | dolphin | highlevel | gould \ - | cbm | ns | masscomp | apple | axis | knuth | cray \ - | microblaze* | sim | cisco \ - | oki | wec | wrs | winbond) + 3100* \ + | 32* \ + | 3300* \ + | 3600* \ + | 7300* \ + | acorn \ + | altos* \ + | apollo \ + | apple \ + | atari \ + | att* \ + | axis \ + | be \ + | bull \ + | cbm \ + | ccur \ + | cisco \ + | commodore \ + | convergent* \ + | convex* \ + | cray \ + | crds \ + | dec* \ + | delta* \ + | dg \ + | digital \ + | dolphin \ + | encore* \ + | gould \ + | harris \ + | highlevel \ + | hitachi* \ + | hp \ + | ibm* \ + | intergraph \ + | isi* \ + | knuth \ + | masscomp \ + | microblaze* \ + | mips* \ + | motorola* \ + | ncr* \ + | news \ + | next \ + | ns \ + | oki \ + | omron* \ + | pc533* \ + | rebel \ + | rom68k \ + | rombug \ + | semi \ + | sequent* \ + | siemens \ + | sgi* \ + | siemens \ + | sim \ + | sni \ + | sony* \ + | stratus \ + | sun \ + | sun[234]* \ + | tektronix \ + | tti* \ + | ultra \ + | unicom* \ + | wec \ + | winbond \ + | wrs) basic_machine=$field1-$field2 basic_os= ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; *) basic_machine=$field1 basic_os=$field2 @@ -271,26 +345,6 @@ case $1 in basic_machine=arm-unknown basic_os=cegcc ;; - convex-c1) - basic_machine=c1-convex - basic_os=bsd - ;; - convex-c2) - basic_machine=c2-convex - basic_os=bsd - ;; - convex-c32) - basic_machine=c32-convex - basic_os=bsd - ;; - convex-c34) - basic_machine=c34-convex - basic_os=bsd - ;; - convex-c38) - basic_machine=c38-convex - basic_os=bsd - ;; cray) basic_machine=j90-cray basic_os=unicos @@ -713,15 +767,26 @@ case $basic_machine in vendor=dec basic_os=tops20 ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) + delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) cpu=m68k vendor=motorola ;; - dpx2*) + # This used to be dpx2*, but that gets the RS6000-based + # DPX/20 and the x86-based DPX/2-100 wrong. See + # https://oldskool.silicium.org/stations/bull_dpx20.htm + # https://www.feb-patrimoine.com/english/bull_dpx2.htm + # https://www.feb-patrimoine.com/english/unix_and_bull.htm + dpx2 | dpx2[23]00 | dpx2[23]xx) cpu=m68k vendor=bull - basic_os=sysv3 + ;; + dpx2100 | dpx21xx) + cpu=i386 + vendor=bull + ;; + dpx20) + cpu=rs6000 + vendor=bull ;; encore | umax | mmax) cpu=ns32k @@ -836,18 +901,6 @@ case $basic_machine in next | m*-next) cpu=m68k vendor=next - case $basic_os in - openstep*) - ;; - nextstep*) - ;; - ns2*) - basic_os=nextstep2 - ;; - *) - basic_os=nextstep3 - ;; - esac ;; np1) cpu=np1 @@ -936,14 +989,13 @@ case $basic_machine in ;; *-*) - # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1491,12 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1325,7 +1511,6 @@ case $basic_os in os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) - # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* | linux-mlibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) + ;; + uclinux-uclibc*- | uclinux-gnu*- ) ;; - uclinux-uclibc* ) + managarm-mlibc*- | managarm-kernel*- ) ;; - managarm-mlibc* | managarm-kernel* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* | -mlibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - -kernel* ) - echo "Invalid configuration \`$1': \`$os' needs explicit kernel." 1>&2 + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 exit 1 ;; - *-kernel* ) - echo "Invalid configuration \`$1': \`$kernel' does not support \`$os'." 1>&2 + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) ;; - nto-qnx*) + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; - os2-emx) + nto-qnx*-) ;; - *-eabi* | *-gnueabi*) + os2-emx-) ;; - -*) + rtmk-nova-) + ;; + *-eabi*- | *-gnueabi*-) + ;; + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1826,7 +2273,7 @@ case $vendor in *-riscix*) vendor=acorn ;; - *-sunos*) + *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) @@ -1896,7 +2343,7 @@ case $vendor in ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: diff --git a/build_aux/texinfo.tex b/build_aux/texinfo.tex index a32c84197..93d592193 100644 --- a/build_aux/texinfo.tex +++ b/build_aux/texinfo.tex @@ -3,9 +3,9 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2023-03-27.21} +\def\texinfoversion{2024-02-10.22} % -% Copyright 1985, 1986, 1988, 1990-2023 Free Software Foundation, Inc. +% Copyright 1985, 1986, 1988, 1990-2024 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -275,8 +275,7 @@ % \topmark doesn't work for the very first chapter (after the title % page or the contents), so we use \firstmark there -- this gets us % the mark with the chapter defs, unless the user sneaks in, e.g., -% @setcolor (or @url, or @link, etc.) between @contents and the very -% first @chapter. +% @setcolor (or @url etc.) between @contents and the very first @chapter. \def\gettopheadingmarks{% \ifcase0\the\savedtopmark\fi \ifx\thischapter\empty \ifcase0\firstmark\fi \fi @@ -427,42 +426,21 @@ } % First remove any @comment, then any @c comment. Pass the result on to -% \argcheckspaces. +% \argremovespace. \def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} -\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} - -% Each occurrence of `\^^M' or `\^^M' is replaced by a single space. -% -% \argremovec might leave us with trailing space, e.g., +\def\argremovec#1\c#2\ArgTerm{\argremovespace#1$ $\ArgTerm} +% \argremovec might leave us with trailing space, though; e.g., % @end itemize @c foo -% This space token undergoes the same procedure and is eventually removed -% by \finishparsearg. -% -\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} -\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} -\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% - \def\temp{#3}% - \ifx\temp\empty - % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: - \let\temp\finishparsearg - \else - \let\temp\argcheckspaces - \fi - % Put the space token in: - \temp#1 #3\ArgTerm -} +% Note that the argument cannot contain the TeX $, as its catcode is +% changed to \other when Texinfo source is read. +\def\argremovespace#1 $#2\ArgTerm{\finishparsearg#1$\ArgTerm} % If a _delimited_ argument is enclosed in braces, they get stripped; so % to get _exactly_ the rest of the line, we had to prevent such situation. -% We prepended an \empty token at the very beginning and we expand it now, -% just before passing the control to \argtorun. -% (Similarly, we have to think about #3 of \argcheckspacesY above: it is -% either the null string, or it ends with \^^M---thus there is no danger -% that a pair of braces would be stripped. -% -% But first, we have to remove the trailing space token. -% -\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} +% We prepended an \empty token at the very beginning and we expand it +% just before passing the control to \next. +% (But first, we have to remove the remaining $ or two.) +\def\finishparsearg#1$#2\ArgTerm{\expandafter\argtorun\expandafter{#1}} % \parseargdef - define a command taking an argument on the line @@ -4950,6 +4928,7 @@ \commondummyword\inforef {}% \commondummyword\kbd {}% \commondummyword\key {}% + \commondummyword\link {}% \commondummyword\math {}% \commondummyword\option {}% \commondummyword\pxref {}% @@ -5259,14 +5238,14 @@ % the current value of \escapechar. \def\escapeisbackslash{\escapechar=`\\} -% Use \ in index files by default. texi2dvi didn't support @ as the escape -% character (as it checked for "\entry" in the files, and not "@entry"). When -% the new version of texi2dvi has had a chance to become more prevalent, then -% the escape character can change back to @ again. This should be an easy -% change to make now because both @ and \ are only used as escape characters in -% index files, never standing for themselves. +% Uncomment to use \ in index files by default. Old texi2dvi (before 2019) +% didn't support @ as the escape character (as it checked for "\entry" in +% the files, and not "@entry"). +% In the future we can remove this flag and simplify the code for +% index files and backslashes, once the support is no longer likely to be +% useful. % -\set txiindexescapeisbackslash +% \set txiindexescapeisbackslash % Write the entry in \indextext to the index file. % @@ -5575,6 +5554,11 @@ \newdimen\entryrightmargin \entryrightmargin=0pt +% amount to indent subsequent lines in an entry when it spans more than +% one line. +\newdimen\entrycontskip +\entrycontskip=1em + % for PDF output, whether to make the text of the entry a link to the page % number. set for @contents and @shortcontents where there is only one % page number. @@ -5668,41 +5652,17 @@ \parfillskip=0pt plus -1fill % \advance\rightskip by \entryrightmargin - % Determine how far we can stretch into the margin. - % This allows, e.g., "Appendix H GNU Free Documentation License" to - % fit on one line in @letterpaper format. - \ifdim\entryrightmargin>2.1em - \dimen@i=2.1em - \else - \dimen@i=0em - \fi - \advance \parfillskip by 0pt minus 1\dimen@i % \dimen@ii = \hsize \advance\dimen@ii by -1\leftskip \advance\dimen@ii by -1\entryrightmargin - \advance\dimen@ii by 1\dimen@i \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line \ifdim\dimen@ > 0.8\dimen@ii % due to long index text - % Try to split the text roughly evenly. \dimen@ will be the length of - % the first line. - \dimen@ = 0.7\dimen@ - \dimen@ii = \hsize - \ifnum\dimen@>\dimen@ii - % If the entry is too long (for example, if it needs more than - % two lines), use all the space in the first line. - \dimen@ = \dimen@ii - \fi \advance\leftskip by 0pt plus 1fill % ragged right - \advance \dimen@ by 1\rightskip - \parshape = 2 0pt \dimen@ 0em \dimen@ii - % Ideally we'd add a finite glue at the end of the first line only, - % instead of using \parshape with explicit line lengths, but TeX - % doesn't seem to provide a way to do such a thing. % % Indent all lines but the first one. - \advance\leftskip by 1em - \advance\parindent by -1em + \advance\leftskip by \entrycontskip + \advance\parindent by -\entrycontskip \fi\fi \indent % start paragraph \unhbox\boxA @@ -5725,12 +5685,11 @@ \newskip\thinshrinkable \skip\thinshrinkable=.15em minus .15em -% Like plain.tex's \dotfill, except uses up at least 1 em. +% Like plain.tex's \dotfill, except uses up at least 0.5 em. % The filll stretch here overpowers both the fil and fill stretch to push % the page number to the right. \def\indexdotfill{\cleaders - \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll} - + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 0.5em plus 1filll} \def\primary #1{\line{#1\hfil}} @@ -5783,7 +5742,7 @@ % below is chosen so that the gutter has the same value (well, +-<1pt) % as it did when we hard-coded it. % - % We put the result in a separate register, \doublecolumhsize, so we + % We put the result in a separate register, \doublecolumnhsize, so we % can restore it in \pagesofar, after \hsize itself has (potentially) % been clobbered. % @@ -6178,8 +6137,7 @@ % normally unnmhead0 calls unnumberedzzz: \outer\parseargdef\unnumbered{\unnmhead0{#1}} \def\unnumberedzzz#1{% - \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 - \global\advance\unnumberedno by 1 + \global\advance\unnumberedno by 1 % % Since an unnumbered has no number, no prefix for figures. \global\let\chaplevelprefix = \empty @@ -6235,8 +6193,8 @@ % normally calls unnumberedseczzz: \outer\parseargdef\unnumberedsec{\unnmhead1{#1}} \def\unnumberedseczzz#1{% - \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 - \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% + \global\advance\unnumberedno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno}% } % Subsections. @@ -6259,9 +6217,8 @@ % normally calls unnumberedsubseczzz: \outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} \def\unnumberedsubseczzz#1{% - \global\subsubsecno=0 \global\advance\subsecno by 1 - \sectionheading{#1}{subsec}{Ynothing}% - {\the\unnumberedno.\the\secno.\the\subsecno}% + \global\advance\unnumberedno by 1 + \sectionheading{#1}{subsec}{Ynothing}{\the\unnumberedno}% } % Subsubsections. @@ -6285,9 +6242,8 @@ % normally unnumberedsubsubseczzz: \outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} \def\unnumberedsubsubseczzz#1{% - \global\advance\subsubsecno by 1 - \sectionheading{#1}{subsubsec}{Ynothing}% - {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% + \global\advance\unnumberedno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}{\the\unnumberedno}% } % These macros control what the section commands do, according @@ -6721,6 +6677,82 @@ \input \tocreadfilename } +% process toc file to find the maximum width of the section numbers for +% each chapter +\def\findsecnowidths{% + \begingroup + \setupdatafile + \activecatcodes + \secentryfonts + % Redefinitions + \def\numchapentry##1##2##3##4{% + \def\curchapname{secnowidth-##2}% + \curchapmax=0pt + }% + \let\appentry\numchapentry + % + \def\numsecentry##1##2##3##4{% + \def\cursecname{secnowidth-##2}% + \cursecmax=0pt + % + \setbox0=\hbox{##2}% + \ifdim\wd0>\curchapmax + \curchapmax=\wd0 + \expandafter\xdef\csname\curchapname\endcsname{\the\wd0}% + \fi + }% + \let\appsecentry\numsecentry + % + \def\numsubsecentry##1##2##3##4{% + \def\curssecname{secnowidth-##2}% + \curssecmax=0pt + % + \setbox0=\hbox{##2}% + \ifdim\wd0>\cursecmax + \cursecmax=\wd0 + \expandafter\xdef\csname\cursecname\endcsname{\the\wd0}% + \fi + }% + \let\appsubsecentry\numsubsecentry + % + \def\numsubsubsecentry##1##2##3##4{% + \setbox0=\hbox{##2}% + \ifdim\wd0>\curssecmax + \curssecmax=\wd0 + \expandafter\xdef\csname\curssecname\endcsname{\the\wd0}% + \fi + }% + \let\appsubsubsecentry\numsubsubsecentry + % + % Discard any output by outputting to dummy vbox, in case the toc file + % contains macros that we have not redefined above. + \setbox\dummybox\vbox\bgroup + \input \tocreadfilename\relax + \egroup + \endgroup +} +\newdimen\curchapmax +\newdimen\cursecmax +\newdimen\curssecmax + + +% set #1 to the maximum section width for #2 +\def\retrievesecnowidth#1#2{% + \expandafter\let\expandafter\savedsecnowidth \csname secnowidth-#2\endcsname + \ifx\savedsecnowidth\relax + #1=0pt + \else + #1=\savedsecnowidth + \fi +} +\newdimen\secnowidthchap +\secnowidthchap=0pt +\newdimen\secnowidthsec +\secnowidthsec=0pt +\newdimen\secnowidthssec +\secnowidthssec=0pt + + \newskip\contentsrightmargin \contentsrightmargin=1in \newcount\savepageno \newcount\lastnegativepageno \lastnegativepageno = -1 @@ -6766,6 +6798,7 @@ \startcontents{\putwordTOC}% \openin 1 \tocreadfilename\space \ifeof 1 \else + \findsecnowidths \readtocfile \fi \vfill \eject @@ -6793,6 +6826,7 @@ \rm \hyphenpenalty = 10000 \advance\baselineskip by 1pt % Open it up a little. + \extrasecnoskip=0.4pt \def\numsecentry##1##2##3##4{} \let\appsecentry = \numsecentry \let\unnsecentry = \numsecentry @@ -6828,8 +6862,6 @@ % This space should be enough, since a single number is .5em, and the % widest letter (M) is 1em, at least in the Computer Modern fonts. % But use \hss just in case. - % (This space doesn't include the extra space that gets added after - % the label; that gets put in by \shortchapentry above.) % % We'd like to right-justify chapter numbers, but that looks strange % with appendix letters. And right-justifying numbers and @@ -6839,10 +6871,15 @@ \hbox to 1em{#1\hss}% } -% These macros generate individual entries in the table of contents. -% The first argument is the chapter or section name. -% The last argument is the page number. -% The arguments in between are the chapter number, section number, ... +% These macros generate individual entries in the table of contents, +% and are read in from the *.toc file. +% +% The arguments are like: +% \def\numchapentry#1#2#3#4 +% #1 - the chapter or section name. +% #2 - section number +% #3 - level of section (e.g "chap", "sec") +% #4 - page number % Parts, in the main contents. Replace the part number, which doesn't % exist, with an empty box. Let's hope all the numbers have the same width. @@ -6855,7 +6892,7 @@ \vskip 0pt plus 5\baselineskip \penalty-300 \vskip 0pt plus -5\baselineskip - \dochapentry{\numeralbox\labelspace#1}{}% + \dochapentry{#1}{\numeralbox}{}% } % % Parts, in the short toc. @@ -6866,12 +6903,14 @@ } % Chapters, in the main contents. -\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +\def\numchapentry#1#2#3#4{% + \retrievesecnowidth\secnowidthchap{#2}% + \dochapentry{#1}{#2}{#4}% +} % Chapters, in the short toc. -% See comments in \dochapentry re vbox and related settings. \def\shortchapentry#1#2#3#4{% - \tocentry{\shortchaplabel{#2}\labelspace #1}{#4}% + \tocentry{#1}{\shortchaplabel{#2}}{#4}% } % Appendices, in the main contents. @@ -6882,67 +6921,111 @@ \setbox0 = \hbox{\putwordAppendix{} M}% \hbox to \wd0{\putwordAppendix{} #1\hss}} % -\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}} +\def\appentry#1#2#3#4{% + \retrievesecnowidth\secnowidthchap{#2}% + \dochapentry{\appendixbox{#2}\hskip.7em#1}{}{#4}% +} % Unnumbered chapters. -\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} -\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{#4}} +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{}{#4}} % Sections. -\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\def\numsecentry#1#2#3#4{\dosecentry{#1}{#2}{#4}} + +\def\numsecentry#1#2#3#4{% + \retrievesecnowidth\secnowidthsec{#2}% + \dosecentry{#1}{#2}{#4}% +} \let\appsecentry=\numsecentry -\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} +\def\unnsecentry#1#2#3#4{% + \retrievesecnowidth\secnowidthsec{#2}% + \dosecentry{#1}{}{#4}% +} % Subsections. -\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\def\numsubsecentry#1#2#3#4{% + \retrievesecnowidth\secnowidthssec{#2}% + \dosubsecentry{#1}{#2}{#4}% +} \let\appsubsecentry=\numsubsecentry -\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} +\def\unnsubsecentry#1#2#3#4{% + \retrievesecnowidth\secnowidthssec{#2}% + \dosubsecentry{#1}{}{#4}% +} % And subsubsections. -\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#2}{#4}} \let\appsubsubsecentry=\numsubsubsecentry -\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{}{#4}} % This parameter controls the indentation of the various levels. % Same as \defaultparindent. \newdimen\tocindent \tocindent = 15pt -% Now for the actual typesetting. In all these, #1 is the text and #2 is the -% page number. +% Now for the actual typesetting. In all these, #1 is the text, #2 is +% a section number if present, and #3 is the page number. % % If the toc has to be broken over pages, we want it to be at chapters % if at all possible; hence the \penalty. -\def\dochapentry#1#2{% +\def\dochapentry#1#2#3{% \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip \begingroup % Move the page numbers slightly to the right \advance\entryrightmargin by -0.05em \chapentryfonts - \tocentry{#1}{#2}% + \extrasecnoskip=0.4em % separate chapter number more + \tocentry{#1}{#2}{#3}% \endgroup \nobreak\vskip .25\baselineskip plus.1\baselineskip } -\def\dosecentry#1#2{\begingroup +\def\dosecentry#1#2#3{\begingroup + \secnowidth=\secnowidthchap \secentryfonts \leftskip=\tocindent - \tocentry{#1}{#2}% + \tocentry{#1}{#2}{#3}% \endgroup} -\def\dosubsecentry#1#2{\begingroup +\def\dosubsecentry#1#2#3{\begingroup + \secnowidth=\secnowidthsec \subsecentryfonts \leftskip=2\tocindent - \tocentry{#1}{#2}% + \tocentry{#1}{#2}{#3}% \endgroup} -\def\dosubsubsecentry#1#2{\begingroup +\def\dosubsubsecentry#1#2#3{\begingroup + \secnowidth=\secnowidthssec \subsubsecentryfonts \leftskip=3\tocindent - \tocentry{#1}{#2}% + \tocentry{#1}{#2}{#3}% \endgroup} -% We use the same \entry macro as for the index entries. -\let\tocentry = \entry +% Used for the maximum width of a section number so we can align +% section titles. +\newdimen\secnowidth +\secnowidth=0pt +\newdimen\extrasecnoskip +\extrasecnoskip=0pt -% Space between chapter (or whatever) number and the title. -\def\labelspace{\hskip1em \relax} +% \tocentry{TITLE}{SEC NO}{PAGE} +% +\def\tocentry#1#2#3{% + \def\secno{#2}% + \ifx\empty\secno + \entry{#1}{#3}% + \else + \ifdim 0pt=\secnowidth + \setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}% + \else + \advance\secnowidth by \labelspace + \advance\secnowidth by \extrasecnoskip + \setbox0=\hbox to \secnowidth{% + #2\hskip\labelspace\hskip\extrasecnoskip\hfill}% + \fi + \entrycontskip=\wd0 + \entry{\box0 #1}{#3}% + \fi +} +\newdimen\labelspace +\labelspace=0.6em \def\chapentryfonts{\secfonts \rm} \def\secentryfonts{\textfonts} @@ -7593,9 +7676,13 @@ \def\deflineheader#1 #2 #3\endheader{% \printdefname{#1}{}{#2}\magicamp\defunargs{#3\unskip}% } + \def\deftypeline{% \doingtypefntrue - \parseargusing\activeparens{\printdefunline\deflineheader}% + \parseargusing\activeparens{\printdefunline\deftypelineheader}% +} +\def\deftypelineheader#1 #2 #3 #4\endheader{% + \printdefname{#1}{#2}{#3}\magicamp\defunargs{#4\unskip}% } % \makedefun{deffoo} (\deffooheader parameters) { (\deffooheader expansion) } @@ -7787,6 +7874,8 @@ \tolerance=10000 \hbadness=10000 \exdentamount=\defbodyindent {% + \def\^^M{}% for line continuation + % % defun fonts. We use typewriter by default (used to be bold) because: % . we're printing identifiers, they should be in tt in principle. % . in languages with many accents, such as Czech or French, it's @@ -7819,6 +7908,7 @@ % Print arguments. Use slanted for @def*, typewriter for @deftype*. \def\defunargs#1{% \bgroup + \def\^^M{}% for line continuation \df \ifdoingtypefn \tt \else \sl \fi \ifflagclear{txicodevaristt}{}% {\def\var##1{{\setregularquotes \ttsl ##1}}}% @@ -8112,8 +8202,6 @@ \let\commondummyword\unmacrodo \xdef\macrolist{\macrolist}% \endgroup - \else - \errmessage{Macro #1 not defined}% \fi } @@ -8180,7 +8268,7 @@ % Read recursive and nonrecursive macro bodies. (They're different since % rec and nonrec macros end differently.) % -% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro +% We are in \macrobodyctxt, and the \xdef causes backslashes in the macro % body to be transformed. % Set \macrobody to the body of the macro, and call \macrodef. % @@ -8727,6 +8815,11 @@ \fi } +% @nodedescription, @nodedescriptionblock - do nothing for TeX +\parseargdef\nodedescription{} +\def\nodedescriptionblock{\doignore{nodedescriptionblock}} + + % @anchor{NAME} -- define xref target at arbitrary point. % \newcount\savesfregister @@ -8808,109 +8901,11 @@ \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup \unsepspaces % - % Get args without leading/trailing spaces. - \def\printedrefname{\ignorespaces #3}% - \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% - % + \getprintedrefname{#1}{#3}{#5}% \def\infofilename{\ignorespaces #4}% \setbox\infofilenamebox = \hbox{\infofilename\unskip}% % - \def\printedmanual{\ignorespaces #5}% - \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% - % - % If the printed reference name (arg #3) was not explicitly given in - % the @xref, figure out what we want to use. - \ifdim \wd\printedrefnamebox = 0pt - % No printed node name was explicitly given. - \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax - % Not auto section-title: use node name inside the square brackets. - \def\printedrefname{\ignorespaces #1}% - \else - % Auto section-title: use chapter/section title inside - % the square brackets if we have it. - \ifdim \wd\printedmanualbox > 0pt - % It is in another manual, so we don't have it; use node name. - \def\printedrefname{\ignorespaces #1}% - \else - \ifhavexrefs - % We (should) know the real title if we have the xref values. - \def\printedrefname{\refx{#1-title}}% - \else - % Otherwise just copy the Info node name. - \def\printedrefname{\ignorespaces #1}% - \fi% - \fi - \fi - \fi - % - % Make link in pdf output. - \ifpdf - % For pdfTeX and LuaTeX - {\indexnofonts - \makevalueexpandable - \turnoffactive - % This expands tokens, so do it after making catcode changes, so _ - % etc. don't get their TeX definitions. This ignores all spaces in - % #4, including (wrongly) those in the middle of the filename. - \getfilename{#4}% - % - % This (wrongly) does not take account of leading or trailing - % spaces in #1, which should be ignored. - \setpdfdestname{#1}% - % - \ifx\pdfdestname\empty - \def\pdfdestname{Top}% no empty targets - \fi - % - \leavevmode - \startlink attr{/Border [0 0 0]}% - \ifnum\filenamelength>0 - goto file{\the\filename.pdf} name{\pdfdestname}% - \else - goto name{\pdfmkpgn{\pdfdestname}}% - \fi - }% - \setcolor{\linkcolor}% - \else - \ifx\XeTeXrevision\thisisundefined - \else - % For XeTeX - {\indexnofonts - \makevalueexpandable - \turnoffactive - % This expands tokens, so do it after making catcode changes, so _ - % etc. don't get their TeX definitions. This ignores all spaces in - % #4, including (wrongly) those in the middle of the filename. - \getfilename{#4}% - % - % This (wrongly) does not take account of leading or trailing - % spaces in #1, which should be ignored. - \setpdfdestname{#1}% - % - \ifx\pdfdestname\empty - \def\pdfdestname{Top}% no empty targets - \fi - % - \leavevmode - \ifnum\filenamelength>0 - % With default settings, - % XeTeX (xdvipdfmx) replaces link destination names with integers. - % In this case, the replaced destination names of - % remote PDFs are no longer known. In order to avoid a replacement, - % you can use xdvipdfmx's command line option `-C 0x0010'. - % If you use XeTeX 0.99996+ (TeX Live 2016+), - % this command line option is no longer necessary - % because we can use the `dvipdfmx:config' special. - \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A - << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% - \else - \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A - << /S /GoTo /D (\pdfdestname) >> >>}% - \fi - }% - \setcolor{\linkcolor}% - \fi - \fi + \startxreflink{#1}{#4}% {% % Have to otherify everything special to allow the \csname to % include an _ in the xref name, etc. @@ -8991,6 +8986,93 @@ \endlink \endgroup} +% \getprintedrefname{NODE}{LABEL}{MANUAL} +% - set \printedrefname and \printedmanual +% +\def\getprintedrefname#1#2#3{% + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #2}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\printedmanual{\ignorespaces #3}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #2) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi +} + +% \startxreflink{NODE}{FILE} - start link in pdf output. +\def\startxreflink#1#2{% + \ifpdforxetex + % For pdfTeX and LuaTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #2, including (wrongly) those in the middle of the filename. + \getfilename{#2}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \ifpdf + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfdestname}% + \else + goto name{\pdfmkpgn{\pdfdestname}}% + \fi + \else % XeTeX + \ifnum\filenamelength>0 + % With default settings, + % XeTeX (xdvipdfmx) replaces link destination names with integers. + % In this case, the replaced destination names of + % remote PDFs are no longer known. In order to avoid a replacement, + % you can use xdvipdfmx's command line option `-C 0x0010'. + % If you use XeTeX 0.99996+ (TeX Live 2016+), + % this command line option is no longer necessary + % because we can use the `dvipdfmx:config' special. + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% + \else + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoTo /D (\pdfdestname) >> >>}% + \fi + \fi + }% + \setcolor{\linkcolor}% + \fi +} + % can be overridden in translation files \def\putpageref#1{% \space\putwordpage\tie\refx{#1-pg}} @@ -9028,6 +9110,21 @@ % \def\xrefprintnodename#1{[#1]} +% @link{NODENAME, LABEL, MANUAL} - create a "plain" link, with no +% page number. Not useful if printed on paper. +% +\def\link#1{\linkX[#1,,,]} +\def\linkX[#1,#2,#3,#4]{% + \begingroup + \unsepspaces + \getprintedrefname{#1}{#2}{#3}% + \startxreflink{#1}{#3}% + \printedrefname + \endlink + \endgroup +} + + % Things referred to by \setref. % \def\Ynothing{} @@ -11736,9 +11833,13 @@ \def\c{\loadconf\c}% % Definition for the first newline read in the file \def ^^M{\loadconf}% - % In case the first line has a whole-line command on it + % In case the first line has a whole-line or environment command on it \let\originalparsearg\parsearg% \def\parsearg{\loadconf\originalparsearg}% + % + % \startenvironment is in the expansion of commands defined with \envdef + \let\originalstartenvironment\startenvironment% + \def\startenvironment{\loadconf\startenvironment}% }} @@ -11766,6 +11867,7 @@ \enableemergencynewline \let\c=\comment \let\parsearg\originalparsearg + \let\startenvironment\originalstartenvironment % % Also turn back on active characters that might appear in the input % file name, in case not using a pre-dumped format. diff --git a/configure.ac b/configure.ac index d8719b571..9d9f387fd 100644 --- a/configure.ac +++ b/configure.ac @@ -908,6 +908,42 @@ AC_CHECK_LIB([$with_math], [__gmp_get_memory_functions], LIBS="$curr_libs" CPPFLAGS="$curr_cppflags" +# Checks for gettext. + +case $host_os in + darwin* | rhapsody*) + ;; + *) + gt_cv_func_CFPreferencesCopyAppValue=no + gt_cv_func_CFLocaleCopyCurrent=no + ;; +esac + +dnl Simon: removed, use --disable-nls instead +dnl # Disable for Cygwin +dnl AC_MSG_CHECKING([for __CYGWIN__]) +dnl AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +dnl #ifndef __CYGWIN__ +dnl # error macro not defined +dnl #endif]])], +dnl [enable_nls=no +dnl AC_MSG_RESULT([yes])], +dnl [AC_MSG_RESULT([no])]) + +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION([0.19.8]) +if test "x$LTLIBINTL" != x; then + if test "x$PROGRAMS_LIBS" != x; then + PROGRAMS_LIBS="$PROGRAMS_LIBS $LTLIBINTL" + else + PROGRAMS_LIBS="$LTLIBINTL" + fi + LIBCOB_LIBS="$LIBCOB_LIBS $LTLIBINTL" +fi + +# Checks for internationalization stuff +AM_LANGINFO_CODESET + AC_ARG_WITH([iconv], [AS_HELP_STRING([--with-iconv], [(GnuCOBOL) Use iconv for character set conversion (default: check)])], @@ -1275,17 +1311,6 @@ AC_CHECK_FUNCS([fdatasync sigaction fmemopen]) AC_CHECK_DECLS([fdatasync]) # also check for declaration, missing on MacOS... AC_CHECK_DECLS([fmemopen]) # also check for declaration, missing on AIX... -# Checks for gettext. - -case $host_os in - darwin* | rhapsody*) - ;; - *) - gt_cv_func_CFPreferencesCopyAppValue=no - gt_cv_func_CFLocaleCopyCurrent=no - ;; -esac - # Checks for ncurses/pdcurses/curses. AC_MSG_NOTICE([Checks for curses ...]) AC_ARG_VAR([CURSES_LIBS], [linker flags for curses lookup, overriding automatic lookup, to be used with explicit selection via --with-curses=arg]) @@ -1975,32 +2000,6 @@ if test "$gc_cv_attribute_constructor" = yes; then fi CFLAGS="$curr_cflags" -dnl Simon: removed, use --disable-nls instead -dnl # Disable for Cygwin -dnl AC_MSG_CHECKING([for __CYGWIN__]) -dnl AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -dnl #ifndef __CYGWIN__ -dnl # error macro not defined -dnl #endif]])], -dnl [enable_nls=no -dnl AC_MSG_RESULT([yes])], -dnl [AC_MSG_RESULT([no])]) - -AM_GNU_GETTEXT([external]) -AM_GNU_GETTEXT_VERSION([0.19.8]) -if test "x$LTLIBINTL" != x; then - if test "x$PROGRAMS_LIBS" != x; then - PROGRAMS_LIBS="$PROGRAMS_LIBS $LTLIBINTL" - else - PROGRAMS_LIBS="$LTLIBINTL" - fi - LIBCOB_LIBS="$LIBCOB_LIBS $LTLIBINTL" -fi - -# Checks for internationalization stuff -dnl currently not directly used: AM_ICONV -AM_LANGINFO_CODESET - # Check for perl, used for "make test" #AM_MISSING_PROG(PERL, perl) --> only use for tools that generate something AC_CHECK_PROG(PERL, perl, perl) From 97668518028eda1174b2235cbe5c22d61fe9cf8a Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Mon, 9 Sep 2024 12:37:21 +0000 Subject: [PATCH 36/51] work on "make checkmanual" README: add documentation for "make checkmanual" tests/run_prog_manual.sh.in: * adding testrunner tmux as alternative to screen * allow to override the deduced test runner by environment variable TESTRUNNER * new option to call with parameter "attach" and "kill" for either attaching to or killing test runner sessions in screen/tmux * enhance portability and use abs_builddir * (_test_with_screen): use separate SCREENDIR to ensure using system defaults and work around WSL regressions * (_test_with_cmd): work around cmd quoting by using a dynamically created sub command file --- ChangeLog | 4 + NEWS | 4 + README | 17 +++++ README.md | 22 +++++- tests/ChangeLog | 12 +++ tests/run_prog_manual.sh.in | 144 ++++++++++++++++++++++++++++-------- 6 files changed, 171 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f9c31240..878ba0b5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ +2024-09-09 Simon Sobisch + + * README: add documentation for "make checkmanual" + 2024-08-10 Simon Sobisch * DEPENDENCIES, NEWS: document usage of libiconv diff --git a/NEWS b/NEWS index 411ca2cc0..c8d40a37f 100644 --- a/NEWS +++ b/NEWS @@ -86,6 +86,10 @@ NEWS - user visible changes -*- outline -*- ** use the "default" -shared flag to build dynamic libraries on macOS so as to fix testuite issues with recent macOS versions +** "make checkmanual" was extended to be also usable with tmux and + allows to override the test runner and to attach for screen/tmux sessions, + see README for further details + * Known issues in 3.x ** testsuite: diff --git a/README b/README index 4b32ced96..6b5ce2ede 100644 --- a/README +++ b/README @@ -145,6 +145,23 @@ Tests make checkall + You may also optionally perform a series of semi-manual tests to + verify a working extended screenio. + make checkmanual + The test execution is automatic but the user needs to check for + the expected result. See tests/run_prog_manual.sh for tweaking the + test runner used (which is otherwise deduced from the environment), + either in that script or via TESTRUNNER environment variable. + +** NOTE ** + The semi-manual tests need either "xterm", GNU "screen" or "tmux" + installed and will run within a detached "cmd" on MSYS based + systems otherwise. + For running with screen or tmux execute the following from + a separate terminal, directly after running the testsuite: + tests/run_prog_manual.sh attach + ... and leave that using "exit" at the end of the tests + ============ The following is only interesting for advanced use. diff --git a/README.md b/README.md index 7106f6948..39890f5f7 100644 --- a/README.md +++ b/README.md @@ -88,13 +88,33 @@ If the the COBOL85 testsuite is not already in the build- or source-tree, `make test` will download it. For details see tests/cobol85/README. ** NOTE ** - The language interpreter "perl" is required to run COBOL85 tests. + The language interpreter `perl` is required to run COBOL85 tests. If you want to run both testsuites you can run * `make checkall` + + You may also optionally perform a series of semi-manual tests to + verify a working extended screenio. + + * `make checkmanual` + + The test execution is automatic but the user needs to check for + the expected result. See `tests/run_prog_manual.sh` for tweaking the + test runner used (which is otherwise deduced from the environment), + either in that script or via TESTRUNNER environment variable. + +** NOTE ** + The semi-manual tests need either `xterm`, GNU `screen` or `tmux` + installed and will run within a detached `cmd.exe` on MSYS based + systems otherwise. + For running with screen or tmux execute the following from + a separate terminal, directly after running the testsuite: + `tests/run_prog_manual.sh attach` + ... and leave that using `exit` at the end of the tests + Installation ============ diff --git a/tests/ChangeLog b/tests/ChangeLog index 6c28dd67f..610283051 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,4 +1,16 @@ +2024-09-09 Simon Sobisch + + * run_prog_manual.sh.in: adding testrunner tmux as alternative + to screen; allow to override the deduced test runner by environment + variable TESTRUNNER; new option to call with parameter "attach" and + "kill" for either attaching to or killing test runner sessions in + screen/tmux; enhance portability and use abs_builddir + * run_prog_manual.sh.in (_test_with_screen): use separate SCREENDIR + to ensure using system defaults and work around WSL regressions + * run_prog_manual.sh.in (_test_with_cmd): work around cmd quoting + by using a dynamically created sub command file + 2024-08-03 David Declerck * testsuite.src/run_file.at, testsuite.src/run_misc.at: diff --git a/tests/run_prog_manual.sh.in b/tests/run_prog_manual.sh.in index 982468ea1..aad4f79f2 100755 --- a/tests/run_prog_manual.sh.in +++ b/tests/run_prog_manual.sh.in @@ -2,7 +2,7 @@ # # run_prog_manual.sh gnucobol/tests # -# Copyright (C) 2014-2022 Free Software Foundation, Inc. +# Copyright (C) 2014-2022,2024 Free Software Foundation, Inc. # Written by Edward Hart, Simon Sobisch # # This file is part of GnuCOBOL. @@ -24,14 +24,40 @@ # code to the testsuite after the terminal ends. # You may change run_prog_manual.sh according to you needs, especially -# if you want to use a different terminal/terminal manager than xterm/screen -# or different options for these. - -abs_top_builddir="@abs_top_builddir@" - +# if you want to use a different test runner than the default ones. + +# test runner evaluation, you may want to override this in the +# generated file +case "$TESTRUNNER" in + xterm | screen | tmux | cmd) + # we do as instructed... + ;; + "") + if ( command -v xterm >/dev/null 2>&1) && test -n "$DISPLAY"; then + TESTRUNNER=xterm + elif command -v screen >/dev/null 2>&1; then + TESTRUNNER=screen + elif command -v tmux >/dev/null 2>&1; then + TESTRUNNER=tmux + elif test -n "$MSYSTEM"; then + TESTRUNNER=cmd + else + (>&2 echo "don't know which test runner to use, either install" + echo "one of the default supported ones (xterm, screen, tmux) or" + echo "adjust $0") + exit 1 + fi + ;; + *) + (>&2 echo "unknown test runner '""$TESTRUNNER""'") + exit 1 +esac + + +abs_builddir="@abs_builddir@" TIMEOUT=30 # timeout in seconds -if test ! -z "$MSYSTEM"; then +if test -n "$MSYSTEM"; then SLEEP_SCALE=1 # always possible, done in MSYS to reduce number of spawned processes else SLEEP_SCALE=0.1 # needs a "modern" sleep implementation @@ -43,33 +69,72 @@ TITLE="GnuCOBOL Manual Test Run - $DESC" _test_with_xterm () { xterm -T "$TITLE" \ -fa 'Liberation Mono' -fs 14 \ - -e "bash -c \"(\$COBCRUN_DIRECT $1 2>./syserr.log && echo \$? > ./result) || echo 1 > ./result\"" + -e "sh -c \"(\$COBCRUN_DIRECT $1 2>./syserr.log && echo \$? > ./result) || echo 1 > ./result\"" } -# Note: when using screen manager you have to -# run `screen -r "GCTESTS"` in a separate terminal -# within 5 seconds after starting the tests +export SCREENDIR="${abs_builddir}/screen" + +# Note: when using the GNU screen manager you have to either call +# this script with the parameter "attach" or +# run `screen -r "GCTESTS"` with appropriate SCREENDIR +# in a separate terminal within 5 seconds after starting the tests _test_with_screen () { - # check if screen session already exists, setup if not - screen -S "GCTESTS" -X select . 2>/dev/null 1>&2 - if test $? -ne 0; then + test -d "$SCREENDIR" || mkdir -p -m 700 "$SCREENDIR" + # check if screen session already exists, setup if not + if ! screen -S "GCTESTS" -X select . 2>/dev/null 1>&2; then # Note: you may need to adjust screen's terminal to get an output matching the actual running code later - screen -dmS "GCTESTS" -t "$TITLE" + screen -dmS "GCTESTS" -t "GCTESTS" # we have a fresh environment there - source the test config once - screen -S "GCTESTS" -X stuff ". \"${abs_top_builddir}/tests/atconfig\" && . \"${abs_top_builddir}/tests/atlocal\" + screen -S "GCTESTS" -X stuff "cd \"${abs_builddir}\" && . atconfig && . atlocal; echo " sleep 5 fi # run actual test in screen session - screen -S "GCTESTS" -X title $"TITLE" - screen -S "GCTESTS" -X exec ... bash -c "cd \"$PWD\" && ($COBCRUN_DIRECT $* 2>./syserr.log && echo $? > ./result) || echo 1 > ./result" + screen -S "GCTESTS" -X title "$TITLE" + screen -S "GCTESTS" -X exec ... sh -c "cd \"$PWD\" && ($COBCRUN_DIRECT $* 2>./syserr.log && echo $? > ./result) || echo 1 > ./result" +} +_attach_to_screen () { + test -d "$SCREENDIR" && (screen -r "GCTESTS" ; true) && exit + echo "no sessions with SCREENDIR='""$SCREENDIR""'" +} +_kill_screen () { + test -d "$SCREENDIR" && (screen -S "GCTESTS" -X kill ; rm -rf "$SCREENDIR") && exit + echo "no sessions with SCREENDIR='""$SCREENDIR""'" +} + + +# Note: when using the terminal multiplexer you have to either call +# this script with the parameter "attach" or +# run `tmux attach -t "=GCTESTS:0"` in a separate terminal +# within 5 seconds after starting the tests +_test_with_tmux () { + # check if tmux session already exists, setup if not + if ! tmux has-session -t "=GCTESTS" 2>/dev/null; then + # Note: you may need to adjust screen's terminal to get an output matching the actual running code later + tmux new-session -d -s "GCTESTS" + # we have a fresh environment there - source the test config once + tmux send-keys -t "=GCTESTS:0" "cd \"${abs_builddir}\" && . atconfig && . atlocal; echo" C-m + sleep 5 + fi + # run actual test in screen session + tmux rename-window -t "=GCTESTS:0" "$TITLE" + tmux send-keys -t "=GCTESTS:0" "sh -c \"cd \\\"$PWD\\\" && ($COBCRUN_DIRECT $* 2>./syserr.log && echo $? > ./result) || echo 1 > ./result; echo\"" C-m +} +_attach_to_tmux () { + tmux attach -t "=GCTESTS:0" +} +_kill_tmux () { + tmux has-session -t "=GCTESTS" 2>/dev/null && (tmux kill-session -t "=GCTESTS:0") && exit + echo "no sessions named GCTESTS" } _test_with_cmd () { - # run cmd to start a detached cmd (via cmd's start), and execute the tests there - cmd.exe /c "start \"$TITLE\" /wait cmd /v:on /c \"$COBCRUN_DIRECT $(echo $* | tr '/' '\\') 2>syserr.log & echo !errorlevel! >result\"" + # run cmd to start a detached cmd (via cmd's start), and execute the tests there, + # to work around quoting issues we create a sub-cmd + echo "$COBCRUN_DIRECT $(echo $* | tr '/' '\\') 2>syserr.log & echo !errorlevel! >result" > run_manual.cmd + cmd.exe /c "start \"$TITLE\" /wait cmd /v:on /c run_manual.cmd" #if test -f ./syserr.log; then # dos2unix -q ./syserr.log #fi @@ -89,22 +154,39 @@ _wait_result () { } -# actual test +# special run to attach / kill +if test "$1" = attach; then + case "$TESTRUNNER" in + screen) _attach_to_screen ;; + tmux) _attach_to_tmux ;; + *) echo "no need for external attach with test runner \"$TESTRUNNER\"" ;; + esac + exit +fi +if test "$1" = kill; then + case "$TESTRUNNER" in + screen) _kill_screen ;; + tmux) _kill_tmux ;; + *) echo "no need for external kill with test runner \"$TESTRUNNER\"" ;; + esac + exit +fi + +# actual test rm -f ./result ./syserr.log -if test ! -z "$DISPLAY"; then - _test_with_xterm $* || echo $? > ./result -elif test ! -z "$MSYSTEM"; then - _test_with_cmd $* || echo $? > ./result -else - _test_with_screen $* || echo $? > ./result -fi +case "$TESTRUNNER" in + xterm) _test_with_xterm $* || echo $? > ./result ;; + screen) _test_with_screen $* || echo $? > ./result ;; + tmux) _test_with_tmux $* || echo $? > ./result ;; + cmd) _test_with_cmd $* || echo $? > ./result ;; +esac _wait_result || { (>&2 echo "No result file after waiting for $TIMEOUT seconds!") - if test ! -z "$DISPLAY"; then - screen -S "GCTESTS" -X kill - fi + case "$TESTRUNNER" in + screen | tmux) $0 kill;; + esac echo 124 > ./result } if test -f ./syserr.log; then From a234462ff94b5f5feff62f87d2f097b1e7688a69 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Fri, 13 Sep 2024 21:13:03 +0000 Subject: [PATCH 37/51] testsuite environment update tests: * atlocal.in (set_utf8_locale): new function for the testsuite enabling tests to either run with UTF8 locale or skip * atlocal.in: use configure-setup for the grep binary * atlocal_win: updated to current atlocal.in [to be used for encoding and possibly screenio tests] --- tests/ChangeLog | 4 ++++ tests/atlocal.in | 53 ++++++++++++++++++++++++++++++--------------- tests/atlocal_win | 55 +++++++++++++++++++++++++++++++---------------- 3 files changed, 77 insertions(+), 35 deletions(-) diff --git a/tests/ChangeLog b/tests/ChangeLog index 610283051..a15ae66df 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -10,6 +10,10 @@ to ensure using system defaults and work around WSL regressions * run_prog_manual.sh.in (_test_with_cmd): work around cmd quoting by using a dynamically created sub command file + * atlocal.in (set_utf8_locale): new function for the testsuite + enabling tests to either run with UTF8 locale or skip + * atlocal.in: use configure-setup for the grep binary + * atlocal_win: updated to current atlocal.in 2024-08-03 David Declerck diff --git a/tests/atlocal.in b/tests/atlocal.in index 3d49ec140..68cb4ba1c 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -1,7 +1,7 @@ # # atlocal gnucobol/tests # -# Copyright (C) 2003-2012, 2014-2023 Free Software Foundation, Inc. +# Copyright (C) 2003-2012, 2014-2024 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart # # This file is part of GnuCOBOL. @@ -204,6 +204,25 @@ _return_path () { fi } +# as we run the testsuite in plain LC_ALL=C the system runs in a plain-as-possible environment; +# in the case that we need UTF8 encoding within tests, we try to find out if a working UTF-8 +# locale is available, if not then we return with 77 which will skip the spßecific test needing it +set_utf8_locale () { + # we need the locale binary to tell us how about the locales available + if [ -z "$(which locale)" ]; then + echo "Warning: no locale binary found." + exit 77 # return code for setting + fi + unset LC_ALL + if [ -z "$LC_ALL" ]; then export LC_ALL=$(locale -a | $GREP -i -E "C\.utf.*8" | head -n1); fi + if [ -z "$LC_ALL" ]; then export LC_ALL=$(locale -a | $GREP -i -E "en_US\.utf.*8" | head -n1); fi + if [ -z "$LC_ALL" ]; then export LC_ALL=$(locale -a | $GREP -i -E ".*\.utf.*8" | head -n1); fi + if [ -z "$LC_ALL" ]; then + echo "Warning: no UTF-8 locale found." + exit 77 + fi +} + # ensure we don't execute windows paths within programs generated by cygwin # by passing a hint if test "$OSTYPE" = "cygwin"; then @@ -256,8 +275,8 @@ export COB_UNIX_LF COB_RUNTIME_CONFIG="${abs_top_srcdir}/config/runtime_empty.cfg" export COB_RUNTIME_CONFIG for cobenv in $(${LOCAL_ENV} ${ABS_COBCRUN} --runtime-conf \ - | grep " env:" | cut -d: -f2 | cut -d= -f1 \ - | grep -v "PATH" | grep -v "TERM"); \ + | $GREP " env:" | cut -d: -f2 | cut -d= -f1 \ + | $GREP -v "PATH" | $GREP -v "TERM"); \ do _unset_option $cobenv; \ done @@ -266,8 +285,8 @@ ${LOCAL_ENV} ${ABS_COBC} --verbose --info > info.out # ... and also unset for the compiler if test "$GNUCOBOL_TEST_LOCAL" != "1"; then - for cobenv in $(grep "env:" info.out | cut -d: -f2 | cut -d= -f1 \ - | grep -v "PATH"); \ + for cobenv in $($GREP "env:" info.out | cut -d: -f2 | cut -d= -f1 \ + | $GREP -v "PATH"); \ do _unset_option $cobenv; \ done fi @@ -289,20 +308,20 @@ if test "$GNUCOBOL_TEST_LOCAL" != "1"; then COB_HAS_CURSES="@COB_HAS_CURSES@" else - COB_OBJECT_EXT="$(grep COB_OBJECT_EXT info.out | cut -d: -f2 | cut -b2-)" - COB_EXE_EXT="$(grep COB_EXE_EXT info.out | cut -d: -f2 | cut -b2-)" - COB_MODULE_EXT="$(grep COB_MODULE_EXT info.out | cut -d: -f2 | cut -b2-)" + COB_OBJECT_EXT="$($GREP COB_OBJECT_EXT info.out | cut -d: -f2 | cut -b2-)" + COB_EXE_EXT="$($GREP COB_EXE_EXT info.out | cut -d: -f2 | cut -b2-)" + COB_MODULE_EXT="$($GREP COB_MODULE_EXT info.out | cut -d: -f2 | cut -b2-)" - if test $(grep -i -c "little-endian" info.out) = 0; then + if test $($GREP -i -c "little-endian" info.out) = 0; then COB_BIGENDIAN="yes" else COB_BIGENDIAN="no" fi - COB_HAS_64_BIT_POINTER=$(grep "64bit-mode" info.out | cut -d: -f2 | cut -b2-) + COB_HAS_64_BIT_POINTER=$($GREP "64bit-mode" info.out | cut -d: -f2 | cut -b2-) - cob_indexed=$(grep -i "indexed file" info.out | cut -d: -f2) + cob_indexed=$($GREP -i "indexed file" info.out | cut -d: -f2) if test "x$cob_indexed" = "x"; then - cob_indexed=$(grep ISAM info.out | cut -d: -f2) + cob_indexed=$($GREP ISAM info.out | cut -d: -f2) fi case "$cob_indexed" in " disabled") COB_HAS_ISAM="no";; @@ -314,18 +333,18 @@ else *) echo "unknown entry for indexed handler: '"$cob_indexed"' please report" && exit 1;; esac - if test $(grep -i -c "XML library.*disabled" info.out) = 0; then + if test $($GREP -i -c "XML library.*disabled" info.out) = 0; then COB_HAS_XML2="yes" else COB_HAS_XML2="no" fi - if test $(grep -i -c "JSON library.*disabled" info.out) = 0; then + if test $($GREP -i -c "JSON library.*disabled" info.out) = 0; then COB_HAS_JSON="yes" else COB_HAS_JSON="no" fi # see note below - if test $(grep -i -c " screen .*disabled" info.out) = 0; then + if test $($GREP -i -c " screen .*disabled" info.out) = 0; then COB_HAS_CURSES="yes" else COB_HAS_CURSES="no" @@ -337,7 +356,7 @@ if test "x$MSYSTEM" != "x" -o "$OSTYPE" = "cygwin"; then # "Redirection is not supported" (at least with PDCurses "wincon" port) # --> disabling the tests for this feature # ncurses is known to work as long as TERM is appropriate - if test $(grep -i -c "ncurses" info.out) != 0; then + if test $($GREP -i -c "ncurses" info.out) != 0; then if test "x$MSYSTEM" != "x"; then TERM="" else @@ -348,7 +367,7 @@ if test "x$MSYSTEM" != "x" -o "$OSTYPE" = "cygwin"; then else # manual tests are executed in separate window # and are visible - so no need to handle it there - echo "$at_help_all" | grep -q "run_manual_screen" 2>/dev/null + echo "$at_help_all" | $GREP -q "run_manual_screen" 2>/dev/null if test $? -ne 0; then COB_HAS_CURSES="no" fi diff --git a/tests/atlocal_win b/tests/atlocal_win index 910fc301f..b6dec388f 100644 --- a/tests/atlocal_win +++ b/tests/atlocal_win @@ -5,7 +5,7 @@ # a not POSIX build (OrangeC or Visual Studio build for example) # in a POSIX environment (like MinGW or Cygwin, possibly WSL). # -# Copyright (C) 2003-2012, 2014-2023 Free Software Foundation, Inc. +# Copyright (C) 2003-2012, 2014-2024 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch, Edward Hart # # This file is part of GnuCOBOL. @@ -48,8 +48,8 @@ export LC_ALL unset LANG # define for performance checks (running code several thousand times) -# comment manually if not needed -COBOL_FLAGS="-DCHECK-PERF ${COBOL_FLAGS}" +# uncomment manually if wanted, or set via environment +# COBOL_FLAGS="-DCHECK-PERF ${COBOL_FLAGS}" FLAGS="-debug -Wall ${COBOL_FLAGS} -fdiagnostics-plain-output" # workaround to adjust the testsuite later: @@ -92,7 +92,7 @@ _return_path () { cygpath -pm "$1" else # check for WSL / Bash on Windows; ignore error messages (file not available) - if $(grep -q "Microsoft" /proc/sys/kernel/osrelease 2>/dev/null); then + if $($GREP -q "Microsoft" /proc/sys/kernel/osrelease 2>/dev/null); then echo "$1" | sed -E 's+^/mnt/(.{1})+\1:+' | sed 's+:$+:/+1' else echo "$1" @@ -100,6 +100,25 @@ _return_path () { fi } +# as we run the testsuite in plain LC_ALL=C the system runs in a plain-as-possible environment; +# in the case that we need UTF8 encoding within tests, we try to find out if a working UTF-8 +# locale is available, if not then we return with 77 which will skip the spßecific test needing it +set_utf8_locale () { + # we need the locale binary to tell us how about the locales available + if [ -z "$(which locale)" ]; then + echo "Warning: no locale binary found." + exit 77 # return code for setting + fi + unset LC_ALL + if [ -z "$LC_ALL" ]; then export LC_ALL=$(locale -a | $GREP -i -E "C\.utf.*8" | head -n1); fi + if [ -z "$LC_ALL" ]; then export LC_ALL=$(locale -a | $GREP -i -E "en_US\.utf.*8" | head -n1); fi + if [ -z "$LC_ALL" ]; then export LC_ALL=$(locale -a | $GREP -i -E ".*\.utf.*8" | head -n1); fi + if [ -z "$LC_ALL" ]; then + echo "Warning: no UTF-8 locale found." + exit 77 + fi +} + # Note: we explicit do not set COB_ON_CYGWIN here, # as this is file is about running non-cygwin binaries @@ -123,8 +142,8 @@ export COB_UNIX_LF COB_RUNTIME_CONFIG="$(_return_path "${abs_top_srcdir}/config/runtime_empty.cfg")" export COB_RUNTIME_CONFIG for cobenv in $(${LOCAL_ENV} ${COBCRUN} --runtime-conf \ - | grep " env:" | cut -d: -f2 | cut -d= -f1 \ - | grep -v "PATH" | grep -v "TERM"); \ + | $GREP " env:" | cut -d: -f2 | cut -d= -f1 \ + | $GREP -v "PATH" | $GREP -v "TERM"); \ do _unset_option $cobenv; \ done @@ -133,8 +152,8 @@ ${LOCAL_ENV} ${COBC} --verbose --info > info.out # ... and also unset for the compiler if test "$GNUCOBOL_TEST_LOCAL" != "1"; then - for cobenv in $(grep "env:" info.out | cut -d: -f2 | cut -d= -f1 \ - | grep -v "PATH"); \ + for cobenv in $($GREP "env:" info.out | cut -d: -f2 | cut -d= -f1 \ + | $GREP -v "PATH"); \ do _unset_option $cobenv; \ done fi @@ -148,20 +167,20 @@ export COB_MSG_FORMAT # different flags checked in the testsuite # note: kept intended to ease merge from atlocal.in - COB_OBJECT_EXT="$(grep COB_OBJECT_EXT info.out | cut -d: -f2 | cut -b2-)" + COB_OBJECT_EXT="$($GREP COB_OBJECT_EXT info.out | cut -d: -f2 | cut -b2-)" COB_EXE_EXT=".exe" COB_MODULE_EXT="dll" - if test $(grep -i -c "little-endian" info.out) = 0; then + if test $($GREP -i -c "little-endian" info.out) = 0; then COB_BIGENDIAN="yes" else COB_BIGENDIAN="no" fi - COB_HAS_64_BIT_POINTER=$(grep "64bit-mode" info.out | cut -d: -f2 | cut -b2-) + COB_HAS_64_BIT_POINTER=$($GREP "64bit-mode" info.out | cut -d: -f2 | cut -b2-) - cob_indexed=$(grep -i "indexed file" info.out | cut -d: -f2) + cob_indexed=$($GREP -i "indexed file" info.out | cut -d: -f2) if test "x$cob_indexed" = "x"; then - cob_indexed=$(grep ISAM info.out | cut -d: -f2) + cob_indexed=$($GREP ISAM info.out | cut -d: -f2) fi case "$cob_indexed" in " disabled") COB_HAS_ISAM="no";; @@ -173,18 +192,18 @@ export COB_MSG_FORMAT *) echo "unknown entry for indexed handler: '"$cob_indexed"' please report" && exit 1;; esac - if test $(grep -i -c "XML library.*disabled" info.out) = 0; then + if test $($GREP -i -c "XML library.*disabled" info.out) = 0; then COB_HAS_XML2="yes" else COB_HAS_XML2="no" fi - if test $(grep -i -c "JSON library.*disabled" info.out) = 0; then + if test $($GREP -i -c "JSON library.*disabled" info.out) = 0; then COB_HAS_JSON="yes" else COB_HAS_JSON="no" fi # see note below - if test $(grep -i -c " screen .*disabled" info.out) = 0; then + if test $($GREP -i -c " screen .*disabled" info.out) = 0; then COB_HAS_CURSES="yes" else COB_HAS_CURSES="no" @@ -196,7 +215,7 @@ if test "x$MSYSTEM" != "x" -o "$OSTYPE" = "cygwin"; then # "Redirection is not supported" (at least with PDCurses "wincon" port) # --> disabling the tests for this feature # ncurses is known to work as long as TERM is appropriate - if test $(grep -i -c "ncurses" info.out) != 0; then + if test $($GREP -i -c "ncurses" info.out) != 0; then if test "x$MSYSTEM" != "x"; then TERM="" else @@ -207,7 +226,7 @@ if test "x$MSYSTEM" != "x" -o "$OSTYPE" = "cygwin"; then else # manual tests are executed in separate window # and are visible - so no need to handle it there - echo "$at_help_all" | grep -q "run_manual_screen" 2>/dev/null + echo "$at_help_all" | $GREP -q "run_manual_screen" 2>/dev/null if test $? -ne 0; then COB_HAS_CURSES="no" fi From cd346a66aab8791abd8bc821b9cd4e5c248bd7a8 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Wed, 18 Sep 2024 11:13:05 +0000 Subject: [PATCH 38/51] minor doc changes --- ABOUT-NLS | 6 +++--- DEPENDENCIES | 2 +- DEPENDENCIES.md | 2 +- doc/gnucobol.texi | 18 +++++++++++------- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/ABOUT-NLS b/ABOUT-NLS index 186a3c65c..3cc828658 100644 --- a/ABOUT-NLS +++ b/ABOUT-NLS @@ -110,7 +110,7 @@ people who like their own language and write it well, and who are also able to synergize with other translators speaking the same language. Each translation team has its own mailing list. The up-to-date list of teams can be found at the Free Translation Project's homepage, -'https://translationproject.org/', in the "Teams" area. +'http://translationproject.org/', in the "Teams" area. If you'd like to volunteer to _work_ at translating messages, you should become a member of the translating team for your own language. @@ -1357,7 +1357,7 @@ mere existence a PO file and its wide availability in a distribution. If Jun 2014 seems to be old, you may fetch a more recent copy of this 'ABOUT-NLS' file on most GNU archive sites. The most up-to-date matrix with full percentage details can be found at -'https://translationproject.org/extra/matrix.html'. +'http://translationproject.org/extra/matrix.html'. 1.5 Using 'gettext' in new packages =================================== @@ -1376,4 +1376,4 @@ Free Translation Project is also available for packages which are not developed inside the GNU project. Therefore the information given above applies also for every other Free Software Project. Contact 'coordinator@translationproject.org' to make the '.pot' files available -to the translation teams. \ No newline at end of file +to the translation teams. diff --git a/DEPENDENCIES b/DEPENDENCIES index f0d54169b..94be483f7 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -137,7 +137,7 @@ The following libraries ARE required WHEN : JSON-C is distributed under Expat License. -5) charachter encoding support is needed and iconv is not provided +5) character encoding support is needed and iconv is not provided as part of libc BOTH runtime AND development components required. diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 289265bf5..b14b73815 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -120,7 +120,7 @@ Support for GENERATE JSON is provided by *one* of the following: JSON-C is distributed under Expat License. -charachter encoding support +character encoding support ---------------------------- Support for partial character encoding is provided directly, diff --git a/doc/gnucobol.texi b/doc/gnucobol.texi index af4eb9fd2..e1048c7b1 100644 --- a/doc/gnucobol.texi +++ b/doc/gnucobol.texi @@ -540,7 +540,8 @@ between paragraphs and sections. Warnings are diagnostic messages that report constructions that are not inherently erroneous but that are risky or suggest there may have been an error. -The following options do not enable specific warnings but control the kinds of diagnostics produced by @command{cobc}. +The following options do not enable specific warnings but control the kinds of +diagnostics produced by @command{cobc}. @table @code @item -fsyntax-only @@ -615,9 +616,10 @@ and that are easy to avoid (or modify to prevent the warning).@* The list of warning flags turned on by this option is shown in @option{--help}. @item -Wextra, -W -Enable every possible warning that is not dialect specific. This includes more information -than @option{-Wall} would normally provide.@* -(This option used to be called @option{-W}. The older name is still supported, but the newer name is more descriptive.) +Enable every possible warning that is not dialect specific. This includes more +information than @option{-Wall} would normally provide.@* +(This option used to be called @option{-W}. The older name is still supported, +but the newer name is more descriptive.) @item -W@var{warning} Enable single warning @var{warning}. @@ -629,7 +631,8 @@ Disable single warning @var{warning}. Warn if archaic features are used, such as continuation lines or the @code{NEXT SENTENCE} statement. @item -Wcall-params -Warn if non-01/77-level items are used as arguments in a @code{CALL} statement. This is @emph{not} set with @option{-Wall}. +Warn if non-01/77-level items are used as arguments in a @code{CALL} statement. +This is @emph{not} set with @option{-Wall}. @item -Wcolumn-overflow Warn if text after column 72 in FIXED format. This is @emph{not} set with @option{-Wall}. @@ -781,8 +784,9 @@ Compiler uses the given @var{dialect} to determine the reserved words. User-defined dialect configuration. @item -febcdic-table=@var{cconv-table}/@var{file} -EBCDIC/ASCII translation table to use; either read from @var{file}, or one of the existing @var{cconv-table} -from the configuration directory (see @code{cobc --info}) which have a .ttbl extension, for example @option{-febcdic-table=alternate}.@* +EBCDIC/ASCII translation table to use; either read from @var{file}, or one of +the existing @var{cconv-table} from the configuration directory (see @code{cobc --info}) +which have a .ttbl extension, for example @option{-febcdic-table=alternate}.@* See the @file{default.ttbl} file for detailed information about the format. @end table From 111d21f03445f7d6db0e5cfc93e5f49e9fa584ce Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Fri, 20 Sep 2024 07:10:52 +0000 Subject: [PATCH 39/51] Minor adjustments (testsuite, ChangeLog entries, C89) --- cobc/pplex.l | 1 + cobc/scanner.l | 3 +- config/ChangeLog | 8 ++++ tests/testsuite.src/syn_definition.at | 69 +++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/cobc/pplex.l b/cobc/pplex.l index 0b7105efb..68880bb79 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -85,6 +85,7 @@ static void insert_copy_arg (void); #include #include #include +#include #include #ifdef HAVE_STRINGS_H #include diff --git a/cobc/scanner.l b/cobc/scanner.l index 15f3d1871..8e199f8a2 100644 --- a/cobc/scanner.l +++ b/cobc/scanner.l @@ -85,6 +85,7 @@ static int yywrap (void) { #include #include +#include #include #ifdef HAVE_STRINGS_H #include @@ -1366,7 +1367,7 @@ scan_ebcdic_char (int c) buff, "(1..256)"); return '?'; } - c--; // in ordinal, i.e. 1..256 -> 0..255 + c--; /* in ordinal, i.e. 1..256 -> 0..255 */ #ifdef COB_EBCDIC_MACHINE return (cob_u8_t) c; #else diff --git a/config/ChangeLog b/config/ChangeLog index cd1a4744f..a23c513bb 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -44,11 +44,19 @@ * rm-strict.conf: enable indirect-redefines as this was added with later RM-COBOL versions +2023-02-20 Nicolas Berthier + + * general: add ebcdic-symbolic-characters + 2023-02-16 Fabrice Le Fessant * gcos.words: remove alias VALUES=VALUE, to correctly parse "VALUES ARE" +2023-01-28 Fabrice Le Fessant + + * default.conf: change default source reference-format to 'auto' + 2023-01-25 Simon Sobisch * ibm.words, mvs.words: re-add BINARY diff --git a/tests/testsuite.src/syn_definition.at b/tests/testsuite.src/syn_definition.at index 33889dd69..5f43cdc3e 100644 --- a/tests/testsuite.src/syn_definition.at +++ b/tests/testsuite.src/syn_definition.at @@ -2878,3 +2878,72 @@ prog.cob:6: error: 'DEPTHDR' is not defined AT_CLEANUP + +AT_SETUP([POINTER TO typedef-name]) +AT_KEYWORDS([POINTER TYPEDEF]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 data-type PIC X(10) USAGE DISPLAY IS TYPEDEF. + 01 data-ptr1 USAGE POINTER data-type. + 01 data-ptr2 USAGE POINTER TO data-type. + PROCEDURE DIVISION. + STOP RUN. + END PROGRAM prog. +]) + +AT_CHECK([$COMPILE_ONLY -Wno-pending prog.cob], [0], [], []) +AT_CLEANUP + + +AT_SETUP([FUNCTION-POINTER TO function-name]) +AT_KEYWORDS([FUNCTION-POINTER]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 fun-ptr1 USAGE FUNCTION-POINTER FUNCTION random. + 01 fun-ptr2 USAGE FUNCTION-POINTER TO FUNCTION random. + PROCEDURE DIVISION. + STOP RUN. + END PROGRAM prog. +]) + +AT_CHECK([$COMPILE_ONLY -Wno-pending prog.cob], [0], [], []) +AT_CLEANUP + + +AT_SETUP([PROGRAM-POINTER TO program-prototype]) +AT_KEYWORDS([PROGRAM-POINTER PROTOTYPE]) + +# currently fails -> investigate +AT_XFAIL_IF([true]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + + PROGRAM-ID. prog-proto IS PROTOTYPE. + PROCEDURE DIVISION. + END PROGRAM prog-proto. + + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + REPOSITORY. + PROGRAM prog-proto. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 prog-ptr1 USAGE PROGRAM-POINTER prog-proto. + 01 prog-ptr2 USAGE PROGRAM-POINTER TO prog-proto. + PROCEDURE DIVISION. + STOP RUN. + END PROGRAM prog. +]) + +AT_CHECK([$COMPILE_ONLY -Wno-unfinished prog.cob], [0], [], []) +AT_CLEANUP From 7b09c750ff7d354f0637678a6c1db425650d8359 Mon Sep 17 00:00:00 2001 From: chaat Date: Fri, 20 Sep 2024 21:39:45 +0000 Subject: [PATCH 40/51] Fix [bugs:#990] COBOL screen, problem positioning cursor on line 1 libcob/screenio.c: fix relational operator to use greater than or equal 0 --- libcob/ChangeLog | 4 ++ libcob/screenio.c | 2 +- tests/testsuite.src/run_manual_screen.at | 79 ++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 31bc7a0db..6db0c9c7c 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,8 @@ +2024-09-20 Chuck Haatvedt + + * screenio.c (cob_screen_get_all) fixed Bug #990 + 2024-08-28 David Declerck * intrinsics.c (cob_intr_random), move.c (cob_move_display_to_packed): diff --git a/libcob/screenio.c b/libcob/screenio.c index 17a3c9df0..3d874a49f 100644 --- a/libcob/screenio.c +++ b/libcob/screenio.c @@ -2411,7 +2411,7 @@ cob_screen_get_all (const int initial_curs, const int accept_timeout) int cursor_clause_line; int cursor_clause_col; get_cursor_from_program (&cursor_clause_line, &cursor_clause_col); - if (cursor_clause_line > 0) { + if (cursor_clause_line >= 0) { int fld_index = find_field_by_pos (initial_curs, cursor_clause_line, cursor_clause_col); if (fld_index >= 0) { curr_index = fld_index; diff --git a/tests/testsuite.src/run_manual_screen.at b/tests/testsuite.src/run_manual_screen.at index 8d64a5e15..a5ed5cb19 100644 --- a/tests/testsuite.src/run_manual_screen.at +++ b/tests/testsuite.src/run_manual_screen.at @@ -1138,7 +1138,7 @@ AT_DATA([prog.cob], [ 77 CMAGENTA PIC 9(05) COMP-5 VALUE 6. 77 CYELLOW PIC 9(05) COMP-5 VALUE 7. 77 CWHITE PIC 9(05) COMP-5 VALUE 8. - + 77 LIN PIC 99 COMP-5. 01 scr1 PIC X(80) @@ -1248,7 +1248,7 @@ AT_DATA([prog.cob], [[ & "BCOLOR=BLACK,". 77 CWHITE PIC X(99) VALUE "FCOLOR=WHITE, " & "BCOLOR=BLACK, ". - + 77 LIN PIC 99 COMP-5. 01 scr1 PIC X(75) @@ -1300,7 +1300,7 @@ AT_DATA([prog.cob], [[ * ADD 2 TO LIN PERFORM dspcol - MOVE "REVERSE," TO + MOVE "REVERSE," TO CBLACK (40:), CBLUE (40:), CGREEN (40:), CCYAN (40:), CRED (40:), CMAGENTA (40:), CYELLOW (40:), CWHITE (40:) ADD 1 TO LIN @@ -1312,12 +1312,12 @@ AT_DATA([prog.cob], [[ ADD 1 TO LIN DISPLAY scr9 AT LINE LIN COL 2 * - MOVE "HIGHLIGHT,NO REVERSE" TO + MOVE "HIGHLIGHT,NO REVERSE" TO CBLACK (50:), CBLUE (50:), CGREEN (50:), CCYAN (50:), CRED (50:), CMAGENTA (50:), CYELLOW (50:), CWHITE (50:) ADD 1 TO LIN PERFORM dspcol - MOVE "NO HIGH, BLINK" TO + MOVE "NO HIGH, BLINK" TO CBLACK (60:), CBLUE (60:), CGREEN (60:), CCYAN (60:), CRED (60:), CMAGENTA (60:), CYELLOW (60:), CWHITE (60:) MOVE 12 TO LIN @@ -1359,7 +1359,7 @@ AT_DATA([prog.cob], [[ WORKING-STORAGE SECTION. 01 success-flag PIC X VALUE 'Y'. 88 success VALUE 'Y', 'y'. - + 77 LIN-START PIC 99 COMP-5. 77 LIN PIC 99 COMP-5. @@ -3600,3 +3600,70 @@ AT_CHECK([$COMPILE prog.cob], [0], [], []) MANUAL_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) AT_CLEANUP + + +AT_SETUP([CURSOR position in line 1]) +AT_KEYWORDS([screen]) + +AT_SKIP_IF([test "$COB_HAS_CURSES" != "yes"]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. PROG. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SPECIAL-NAMES. + CURSOR IS CURSOR-POSITION. + + DATA DIVISION. + + WORKING-STORAGE SECTION. + + 01 CURSOR-POSITION. + 05 CSR-ROW-NUMBER PIC 9(03) VALUE 001. + 05 CSR-COL-NUMBER PIC 9(03) VALUE 005. + + 01 WORK-FIELDS. + 05 IN-ID PIC X(09) VALUE SPACES. + 05 TRAN-ID PIC X(03) VALUE 'ABC'. + + 01 SUCCESS-FLAG PIC X VALUE 'Y'. + 88 SUCCESS VALUE 'y', 'Y'. + + SCREEN SECTION. + + 01 EMPLOYEE-SCREEN + BACKGROUND-COLOR IS 0 + FOREGROUND-COLOR IS 7. + + 05 LINE 01 COL 01 AUTO PIC X(03) USING + TRAN-ID. + 05 LINE 01 COL 04 PIC X(01) VALUE + ','. + 05 LINE 01 COL 05 AUTO PIC X(09) USING + IN-ID. + + 05 LINE 5 VALUE 'cursor should be ' + & 'at line 1 and column 5'. + 05 LINE 6 VALUE 'go to line 10 ' + & 'and enter an "y" or "n" '. + 05 LINE 10 PIC X, REQUIRED USING success-flag. + + PROCEDURE DIVISION. + + DISPLAY EMPLOYEE-SCREEN. + ACCEPT EMPLOYEE-SCREEN. + + IF SUCCESS AND COB-CRT-STATUS = 0 + GOBACK RETURNING 0 + ELSE + GOBACK RETURNING 1 + END-IF. + +]) + +AT_CHECK([$COMPILE prog.cob], [0], [], []) +MANUAL_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP + From 2c000f51a11e45a7e25c28eb795437e24587c0d1 Mon Sep 17 00:00:00 2001 From: David Declerck Date: Sun, 22 Sep 2024 14:18:30 +0200 Subject: [PATCH 41/51] Update Windows workflows (upload testsuite.log on failure) --- .github/workflows/windows-msvc.yml | 1 + .github/workflows/windows-msys1.yml | 1 + .github/workflows/windows-msys2.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index 134e7f18c..b748e62d6 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -204,6 +204,7 @@ jobs: - name: Upload testsuite-${{ matrix.arch }}-${{ matrix.target }}.log uses: actions/upload-artifact@v4 + if: failure() with: name: testsuite-${{ matrix.arch }}-${{ matrix.target }}.log path: ${{ env.GITHUB_WORKSPACE }}/tests/testsuite.log diff --git a/.github/workflows/windows-msys1.yml b/.github/workflows/windows-msys1.yml index 661344910..67f3801c6 100644 --- a/.github/workflows/windows-msys1.yml +++ b/.github/workflows/windows-msys1.yml @@ -229,6 +229,7 @@ jobs: - name: Upload testsuite-${{ matrix.target }}.log uses: actions/upload-artifact@v4 + if: failure() with: name: testsuite-${{ matrix.target }}.log path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index f2b5c13e9..59ba117b5 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -102,6 +102,7 @@ jobs: - name: Upload testsuite-${{matrix.sys}}-${{matrix.target}}.log uses: actions/upload-artifact@v4 + if: failure() with: name: testsuite-${{matrix.sys}}-${{matrix.target}}.log path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log From 7ba5f9fcb116490a2fbe3e5c2afb9100a3e92c18 Mon Sep 17 00:00:00 2001 From: chaat Date: Mon, 23 Sep 2024 19:00:14 +0000 Subject: [PATCH 42/51] preparation for Multiple Window support by WINDOW pointer libcob/screenio.c: In preparation for Multiple Window support added static WINDOW pointer "mywin", all curses functions which either implicitly or explicitly referenced the stdscr WINDOW pointer were changed to use the window specific functions using mywin except the getch function remains unchanged. The wgetch function caused the mouse not to be recognized. --- libcob/ChangeLog | 10 ++ libcob/screenio.c | 290 +++++++++++++++++++++++++--------------------- 2 files changed, 165 insertions(+), 135 deletions(-) diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 6db0c9c7c..26dadfe99 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,14 @@ +2024-07-27 Chuck Haatvedt + + * screenio.c: In preparation for Multiple Window support + added static WINDOW pointer "mywin", all curses functions + which either implicitly or explicitly referenced the + stdscr WINDOW pointer were changed to use the window + specific functions using mywin except the getch function + remains unchanged. The wgetch function caused the mouse + not to be recognized. + 2024-09-20 Chuck Haatvedt * screenio.c (cob_screen_get_all) fixed Bug #990 diff --git a/libcob/screenio.c b/libcob/screenio.c index 3d874a49f..862509f74 100644 --- a/libcob/screenio.c +++ b/libcob/screenio.c @@ -161,6 +161,7 @@ static int accept_cursor_y; static int accept_cursor_x; static int pending_accept; static int got_sys_char; +static WINDOW *mywin; #ifdef HAVE_MOUSEMASK static unsigned int curr_setting_mouse_flags = UINT_MAX; #endif @@ -324,7 +325,7 @@ raise_ec_on_invalid_line_or_col (const int line, const int column) int max_y; int max_x; - getmaxyx (stdscr, max_y, max_x); + getmaxyx (mywin, max_y, max_x); if (line < 0 || line >= max_y) { cob_set_exception (COB_EC_SCREEN_LINE_NUMBER); } @@ -336,7 +337,7 @@ raise_ec_on_invalid_line_or_col (const int line, const int column) static int cob_move_cursor (const int line, const int column) { - int status = move (line, column); + int status = wmove (mywin, line, column); if (status == ERR) { raise_ec_on_invalid_line_or_col (line, column); @@ -348,7 +349,7 @@ void cob_set_cursor_pos (int line, int column) { init_cob_screen_if_needed (); - (void) move (line, column); + (void) wmove (mywin, line, column); } #if 0 /* currently unused */ @@ -358,9 +359,9 @@ cob_move_to_beg_of_last_line (void) int max_y; int max_x; - getmaxyx (stdscr, max_y, max_x); + getmaxyx (mywin, max_y, max_x); /* We don't need to check for exceptions here; it will always be fine */ - move (max_y, 0); + wmove (mywin, max_y, 0); COB_UNUSED (max_x); } @@ -413,11 +414,11 @@ cob_activate_color_pair (const short color_pair_number) int ret; #ifdef HAVE_COLOR_SET - ret = color_set (color_pair_number, NULL); + ret = wcolor_set (mywin, color_pair_number, NULL); #else - ret = attrset (COLOR_PAIR(color_pair_number)); + ret = wattrset (mywin, COLOR_PAIR(color_pair_number)); #endif - bkgdset (COLOR_PAIR(color_pair_number)); + wbkgdset (mywin, COLOR_PAIR(color_pair_number)); return ret; } @@ -956,9 +957,9 @@ cob_screen_attr (cob_field *fgc, cob_field *bgc, cob_flags_t attr, #endif /* apply attributes */ - attrset (A_NORMAL); + wattrset (mywin, A_NORMAL); if (styles != A_NORMAL) { - attron (styles); + wattron (mywin, styles); } /* apply colors */ @@ -975,24 +976,24 @@ cob_screen_attr (cob_field *fgc, cob_field *bgc, cob_flags_t attr, } /* BLANK SCREEN colors the whole screen. */ if (attr & COB_SCREEN_BLANK_SCREEN) { - getyx (stdscr, line, column); - clear (); + getyx (mywin, line, column); + wclear (mywin); cob_move_cursor (line, column); } if (stmt == DISPLAY_STATEMENT) { /* BLANK LINE colors the whole line. */ if (attr & COB_SCREEN_BLANK_LINE) { - getyx (stdscr, line, column); + getyx (mywin, line, column); cob_move_cursor (line, 0); - clrtoeol (); + wclrtoeol (mywin); cob_move_cursor (line, column); } if (attr & COB_SCREEN_ERASE_EOL) { - clrtoeol (); + wclrtoeol (mywin); } if (attr & COB_SCREEN_ERASE_EOS) { - clrtobot (); + wclrtobot (mywin); } } if (attr & COB_SCREEN_BELL) { @@ -1054,6 +1055,14 @@ cob_screen_init (void) cob_runtime_error (_("failed to initialize curses")); return 1; } + + /* set mywin pointer to mywin pointer for future + implementation of panels functionality + Note that stdscr WINDOW pointer can not + be altered as the keyboard and mouse + still require this pointer */ + mywin = stdscr; + cobglobptr->cob_screen_initialized = 1; #ifdef HAVE_USE_LEGACY_CODING use_legacy_coding (2); @@ -1069,7 +1078,7 @@ cob_screen_init (void) #endif cbreak (); - keypad (stdscr, 1); + keypad (mywin, 1); nonl (); noecho (); if (has_colors ()) { @@ -1114,8 +1123,8 @@ cob_screen_init (void) #endif } } - attrset (A_NORMAL); - getmaxyx (stdscr, COB_MAX_Y_COORD, COB_MAX_X_COORD); + wattrset (mywin, A_NORMAL); + getmaxyx (mywin, COB_MAX_Y_COORD, COB_MAX_X_COORD); cob_settings_screenio (); @@ -1317,7 +1326,7 @@ pass_cursor_to_program (void) cob_field *cursor_field = COB_MODULE_PTR->cursor_pos; int sline; int scolumn; - getyx (stdscr, sline, scolumn); + getyx (mywin, sline, scolumn); sline++; scolumn++; /* zero-based in curses */ if (COB_FIELD_IS_NUMERIC (cursor_field) && COB_FIELD_TYPE (cursor_field) != COB_TYPE_NUMERIC_DISPLAY) { @@ -1415,8 +1424,8 @@ raise_ec_on_truncation (const int item_size) int max_y; int max_x; - getyx (stdscr, y, x); - getmaxyx (stdscr, max_y, max_x); + getyx (mywin, y, x); + getmaxyx (mywin, max_y, max_x); if (x + item_size - 1 > max_x) { cob_set_exception (COB_EC_SCREEN_ITEM_TRUNCATED); @@ -1430,7 +1439,7 @@ static void cob_addnstr (const char *data, const int size) { raise_ec_on_truncation (size); - addnstr (data, size); + waddnstr (mywin, data, size); } /* variant of cob_addnstr that outputs each character separately, @@ -1446,182 +1455,182 @@ cob_addnstr_graph (const char *data, const int size) switch (c) { case 'j': /* lower-right corner */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_LRCORNER); + wadd_wch (mywin, WACS_LRCORNER); #else - addch (ACS_LRCORNER); + waddch (mywin, ACS_LRCORNER); #endif break; case 'J': /* lower-right corner, double */ #if defined (WACS_D_LRCORNER) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_LRCORNER); + wadd_wch (mywin, WACS_D_LRCORNER); #elif defined (ACS_D_LRCORNER) - addch (ACS_D_LRCORNER); + waddch (mywin, ACS_D_LRCORNER); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'k': /* upper-right corner */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_URCORNER); + wadd_wch (mywin, WACS_URCORNER); #else - addch (ACS_URCORNER); + waddch (mywin, ACS_URCORNER); #endif break; case 'K': /* upper-right corner, double */ #if defined (WACS_D_URCORNER) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_URCORNER); + wadd_wch (mywin, WACS_D_URCORNER); #elif defined (ACS_D_URCORNER) - addch (ACS_D_URCORNER); + waddch (mywin, ACS_D_URCORNER); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'm': /* lower-left corner */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_LLCORNER); + wadd_wch (mywin, WACS_LLCORNER); #else - addch (ACS_LLCORNER); + waddch (mywin, ACS_LLCORNER); #endif break; case 'M': /* lower-left corner, double */ #if defined (WACS_D_LLCORNER) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_LLCORNER); + wadd_wch (mywin, WACS_D_LLCORNER); #elif defined (ACS_D_LLCORNER) - addch (ACS_D_LLCORNER); + waddch (mywin, ACS_D_LLCORNER); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'l': /* upper-left corner */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_ULCORNER); + wadd_wch (mywin, WACS_ULCORNER); #else - addch (ACS_ULCORNER); + waddch (mywin, ACS_ULCORNER); #endif break; case 'L': /* upper-left corner, double */ #if defined (WACS_D_ULCORNER) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_ULCORNER); + wadd_wch (mywin, WACS_D_ULCORNER); #elif defined (ACS_D_ULCORNER) - addch (ACS_D_ULCORNER); + waddch (mywin, ACS_D_ULCORNER); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'n': /* plus */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_PLUS); + wadd_wch (mywin, WACS_PLUS); #else - addch (ACS_PLUS); + waddch (mywin, ACS_PLUS); #endif break; case 'N': /* plus, double */ #if defined (WACS_D_PLUS) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_PLUS); + wadd_wch (mywin, WACS_D_PLUS); #elif defined (ACS_D_PLUS) - addch (ACS_D_PLUS); + waddch (mywin, ACS_D_PLUS); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'q': /* horizontal line */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_HLINE); + wadd_wch (mywin, WACS_HLINE); #else - addch (ACS_HLINE); + waddch (mywin, ACS_HLINE); #endif break; case 'Q': /* horizontal line, double */ #if defined (WACS_D_HLINE) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_HLINE); + wadd_wch (mywin, WACS_D_HLINE); #elif defined (ACS_D_HLINE) - addch (ACS_D_HLINE); + waddch (mywin, ACS_D_HLINE); #else - addch ((const chtype)'-'); + waddch (mywin, (const chtype)'-'); #endif break; case 'x': /* vertical line */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_VLINE); + wadd_wch (mywin, WACS_VLINE); #else - addch (ACS_VLINE); + waddch (mywin, ACS_VLINE); #endif break; case 'X': /* vertical line, double */ #if defined (WACS_D_VLINE) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_VLINE); + wadd_wch (mywin, WACS_D_VLINE); #elif defined (ACS_D_VLINE) - addch (ACS_D_VLINE); + waddch (mywin, ACS_D_VLINE); #else - addch ((const chtype)'|'); + waddch (mywin, (const chtype)'|'); #endif break; case 't': /* left tee */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_LTEE); + wadd_wch (mywin, WACS_LTEE); #else - addch (ACS_LTEE); + waddch (mywin, ACS_LTEE); #endif break; case 'T': /* left tee , double */ #if defined (WACS_D_LTEE) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_LTEE); + wadd_wch (mywin, WACS_D_LTEE); #elif defined (ACS_D_LTEE) - addch (ACS_D_LTEE); + waddch (mywin, ACS_D_LTEE); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'u': /* right tee */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_RTEE); + wadd_wch (mywin, WACS_RTEE); #else - addch (ACS_RTEE); + waddch (mywin, ACS_RTEE); #endif break; case 'U': /* right tee , double */ #if defined (WACS_D_RTEE) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_RTEE); + wadd_wch (mywin, WACS_D_RTEE); #elif defined (ACS_D_RTEE) - addch (ACS_D_RTEE); + waddch (mywin, ACS_D_RTEE); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'v': /* bottom tee */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_BTEE); + wadd_wch (mywin, WACS_BTEE); #else - addch (ACS_BTEE); + waddch (mywin, ACS_BTEE); #endif break; case 'V': /* bottom tee , double */ #if defined (WACS_D_BTEE) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_BTEE); + wadd_wch (mywin, WACS_D_BTEE); #elif defined (ACS_D_BTEE) - addch (ACS_D_BTEE); + waddch (mywin, ACS_D_BTEE); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; case 'w': /* top tee */ #if defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_TTEE); + wadd_wch (mywin, WACS_TTEE); #else - addch (ACS_TTEE); + waddch (mywin, ACS_TTEE); #endif break; case 'W': /* top tee , double */ #if defined (WACS_D_TTEE) && defined (WITH_WIDE_FUNCTIONS) - add_wch (WACS_D_TTEE); + wadd_wch (mywin, WACS_D_TTEE); #elif defined (ACS_D_TTEE) - addch (ACS_D_TTEE); + waddch (mywin, ACS_D_TTEE); #else - addch ((const chtype)'+'); + waddch (mywin, (const chtype)'+'); #endif break; default: - addch ((const chtype)c); + waddch (mywin, (const chtype)c); } } } @@ -1630,14 +1639,14 @@ static void cob_addch (const chtype c) { raise_ec_on_truncation (1); - addch (c); + waddch (mywin, c); } /* Use only when raise_ec_on_truncation is called beforehand. */ static void cob_addch_no_trunc_check (const chtype c) { - addch (c); + waddch (mywin, c); } static void @@ -1838,7 +1847,7 @@ cob_screen_puts (cob_screen *s, cob_field *f, const cob_u32_t is_input, accept_cursor_x = column + f->size; } - refresh (); + wrefresh (mywin); } static COB_INLINE COB_A_INLINE int @@ -2025,7 +2034,7 @@ refresh_field (cob_screen *s) int y; int x; - getyx (stdscr, y, x); + getyx (mywin, y, x); cob_screen_puts (s, s->field, cobsetptr->cob_legacy, ACCEPT_STATEMENT); cob_move_cursor (y, x); } @@ -2438,9 +2447,9 @@ cob_screen_get_all (const int initial_curs, const int accept_timeout) default_prompt_char = COB_CH_UL; } - refresh (); + wrefresh (mywin); errno = 0; - timeout (accept_timeout); + wtimeout (mywin, accept_timeout); keyp = getch (); /* FIXME: modularize (cob_screen_get_all, field_accept) and @@ -2476,7 +2485,7 @@ cob_screen_get_all (const int initial_curs, const int accept_timeout) continue; } - getyx (stdscr, cline, ccolumn); + getyx (mywin, cline, ccolumn); switch (keyp) { case KEY_ENTER: @@ -2899,7 +2908,7 @@ cob_screen_get_all (const int initial_curs, const int accept_timeout) cob_beep (); } screen_return: - refresh (); + wrefresh (mywin); } static int @@ -2936,7 +2945,7 @@ cob_screen_moveyx (cob_screen *s) if (s->line || s->column || s->attr & (COB_SCREEN_LINE_PLUS | COB_SCREEN_LINE_MINUS | COB_SCREEN_COLUMN_PLUS | COB_SCREEN_COLUMN_MINUS)) { - getyx (stdscr, y, x); + getyx (mywin, y, x); if (x < 0 || y < 0) { /* not translated as "testing only" (should not happen) */ cob_runtime_warning ("negative values from getyx"); @@ -2974,7 +2983,7 @@ cob_screen_moveyx (cob_screen *s) } cob_move_cursor (line, column); - refresh (); + wrefresh (mywin); cob_current_y = line; cob_current_x = column; } @@ -3178,7 +3187,7 @@ screen_display (cob_screen *s, const int line, const int column) pending_accept = 1; } cob_screen_iterate (s); - refresh (); + wrefresh (mywin); } static int @@ -3324,10 +3333,10 @@ field_display (cob_field *f, cob_flags_t fattr, const int line, const int column if (fattr & COB_SCREEN_SCROLL_DOWN) { sline = -sline; } - scrollok (stdscr, 1); - scrl (sline); - scrollok (stdscr, 0); - refresh (); + scrollok (mywin, 1); + wscrl (mywin, sline); + scrollok (mywin, 0); + wrefresh (mywin); } sline = line; @@ -3375,7 +3384,7 @@ field_display (cob_field *f, cob_flags_t fattr, const int line, const int column } cob_move_cursor (sline, 0); } - refresh (); + wrefresh (mywin); } static void @@ -3436,10 +3445,10 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum if (fattr & COB_SCREEN_SCROLL_DOWN) { keyp = -keyp; } - scrollok (stdscr, 1); - scrl (keyp); - scrollok (stdscr, 0); - refresh (); + scrollok (mywin, 1); + wscrl (mywin, keyp); + scrollok (mywin, 0); + wrefresh (mywin); } cobglobptr->cob_exception_code = 0; @@ -3494,7 +3503,7 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum } } /* SIZE IS greater than field, blank out trailing screen */ - if (size_accept > (int)f->size) { + if (size_accept > f->size) { cob_addnch (size_accept - f->size, COB_CH_SP); } /* start position within the field, if specified (all 1-based) */ @@ -3520,11 +3529,11 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum if (cursor_clause_line == sline && cursor_clause_col > scolumn - && cursor_clause_col < scolumn + disp_size) { + && cursor_clause_col < scolumn + (int)disp_size) { cursor_off = cursor_clause_col - scolumn + 1; } } - move (sline, scolumn + cursor_off - 1); + wmove (mywin, sline, scolumn + cursor_off - 1); } } #if 0 /* RXWRXW - Screen update */ @@ -3549,14 +3558,14 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum } count = 0; - timeout (get_accept_timeout (ftimeout)); + wtimeout (mywin, get_accept_timeout (ftimeout)); /* Get characters from keyboard, processing each one. */ for (; ;) { /* Show prompt characters. */ if (f) { /* Get current line, column. */ - getyx (stdscr, cline, ccolumn); + getyx (mywin, cline, ccolumn); /* Trailing prompts. */ if (fattr & COB_SCREEN_NO_ECHO) { prompt_char = COB_CH_SP; @@ -3607,7 +3616,7 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum /* Cursor to current column. */ cob_move_cursor (cline, ccolumn); /* Refresh screen. */ - refresh (); + wrefresh (mywin); } errno = 0; @@ -3723,6 +3732,10 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum { int mline = mevent.y; int mcolumn = mevent.x; + if (!wmouse_trafo (mywin, &mline, &mcolumn, 0)) { + cob_beep (); + continue; + } mevent.bstate &= cob_mask_accept; if (mevent.bstate != 0) { fret = mouse_to_exception_code (mevent.bstate); @@ -3950,6 +3963,10 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum { int mline = mevent.y; int mcolumn = mevent.x; + if (!wmouse_trafo (mywin, &mline, &mcolumn, 0)) { + cob_beep (); + continue; + } /* handle depending on state */ if (mevent.bstate & BUTTON1_PRESSED && COB_MOUSE_FLAGS & 1) { @@ -4080,7 +4097,7 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum if (cursor) { /* horizontal position stored in CURSOR clause */ if (!COB_FIELD_CONSTANT (cursor)) { - getyx (stdscr, cline, ccolumn); + getyx (mywin, cline, ccolumn); if (cline == sline) { cob_set_int (cursor, ccolumn + 1 - scolumn); } @@ -4097,7 +4114,7 @@ field_accept (cob_field *f, cob_flags_t fattr, const int sline, const int scolum memset (COB_TERM_BUFF, ' ', size_accept); #endif } - refresh (); + wrefresh (mywin); } static void @@ -4109,7 +4126,7 @@ field_accept_from_curpos (cob_field *f, cob_field *fgc, size_t ccolumn; /* Get current line, column. */ - getyx (stdscr, cline, ccolumn); + getyx (mywin, cline, ccolumn); /* accept field */ field_accept (f, (cob_flags_t)fattr, cline, ccolumn, fgc, bgc, @@ -4125,7 +4142,7 @@ field_display_at_curpos (cob_field *f, size_t ccolumn; /* Get current line, column. */ - getyx (stdscr, cline, ccolumn); + getyx (mywin, cline, ccolumn); field_display (f, (cob_flags_t)fattr, cline, ccolumn, fgc, bgc, fscroll, size_is, NULL, NULL); @@ -4360,8 +4377,8 @@ cob_sys_clear_screen (void) { init_cob_screen_if_needed (); - clear (); - refresh (); + wclear (mywin); + wrefresh (mywin); cob_current_y = 0; cob_current_x = 0; return 0; @@ -4377,14 +4394,14 @@ cob_screen_set_mode (const cob_u32_t smode) if (!smode) { if (cobglobptr->cob_screen_initialized) { - refresh (); + wrefresh (mywin); def_prog_mode (); endwin (); } } else { if (cobglobptr->cob_screen_initialized) { reset_prog_mode (); - refresh (); + wrefresh (mywin); } else { cob_screen_init (); } @@ -4522,11 +4539,11 @@ cob_exit_screen (void) } cobglobptr->cob_screen_initialized = 0; #if 0 /* CHECKME: Shouldn't be necessary */ - clear (); + wclear (mywin); cob_move_to_beg_of_last_line (); #endif endwin (); /* ends curses' terminal mode */ - delwin (stdscr); /* free storage related to screen not active */ + delwin (mywin); /* free storage related to screen not active */ #ifdef HAVE_CURSES_FREEALL /* cleanup storage that would otherwise be shown to be "still reachable" with valgrind */ @@ -4558,6 +4575,8 @@ cob_exit_screen_from_signal (int ss_only) #if (!defined (NCURSES_VERSION_MAJOR) || NCURSES_VERSION_MAJOR < 6) \ && (!defined (PDC_BUILD) || PDC_BUILD < 4305) if (ss_only) return; +#else + COB_UNUSED (ss_only); #endif if (cobglobptr->cob_screen_initialized) { @@ -4767,7 +4786,7 @@ cob_sys_get_csr_pos (unsigned char *fld) init_cob_screen_if_needed (); #ifdef WITH_EXTENDED_SCREENIO - getyx (stdscr, cline, ccol); + getyx (mywin, cline, ccol); if (f && f->size == 4) { /* group with sizes up to 64k (2 * 2 bytes) as used by Fujitsu (likely with a limit of @@ -4864,7 +4883,7 @@ cob_sys_set_csr_pos (unsigned char *fld) cline = fld[0]; ccol= fld[1]; } - return move (cline, ccol); + return wmove (mywin, cline, ccol); #else COB_UNUSED (fld); return 0; @@ -4916,9 +4935,9 @@ cob_sys_set_scr_size (unsigned char *line, unsigned char *col) #endif } - /* save the current stdscr screen to a file */ +/* save the current mywin screen to a file */ int -cob_sys_scr_dump(unsigned char *parm) +cob_sys_scr_dump (unsigned char *parm) { #ifdef WITH_EXTENDED_SCREENIO int result; @@ -4928,24 +4947,25 @@ cob_sys_scr_dump(unsigned char *parm) COB_CHK_PARMS (CBL_GC_SCR_DUMP, 1); init_cob_screen_if_needed (); - if (filename && (filep = fopen(filename, "wb")) != NULL) - { - refresh(); - result = putwin(stdscr, filep); - fclose(filep); + if (filename && (filep = fopen (filename, "wb")) != NULL) { + refresh (); + result = putwin (mywin, filep); + fclose (filep); return result; } + COB_UNUSED (parm); return ERR; #else + COB_UNUSED (parm); return -1; #endif } - /* restore the current stdscr screen from a file */ -int cob_sys_scr_restore(unsigned char *parm) +/* restore the current mywin screen from a file */ +int cob_sys_scr_restore (unsigned char *parm) { #ifdef WITH_EXTENDED_SCREENIO int result; @@ -4955,22 +4975,22 @@ int cob_sys_scr_restore(unsigned char *parm) COB_CHK_PARMS (CBL_GC_SCR_RESTORE, 1); init_cob_screen_if_needed (); - if (filename && (filep = fopen(filename, "rb")) != NULL) - { - WINDOW *replacement = getwin(filep); - fclose(filep); + if (filename && (filep = fopen (filename, "rb")) != NULL) { + WINDOW *replacement = getwin (filep); + fclose (filep); - if (replacement) - { - result = overwrite(replacement, stdscr); - refresh(); - delwin(replacement); + if (replacement) { + result = overwrite (replacement, mywin); + refresh (); + delwin (replacement); return result; } } + COB_UNUSED (parm); return ERR; #else + COB_UNUSED (parm); return -1; #endif From 1104bda61e191efb343ba4fa13b71e484bf8b24f Mon Sep 17 00:00:00 2001 From: nberth Date: Wed, 25 Sep 2024 19:10:31 +0000 Subject: [PATCH 43/51] Check for incompatible data only when a receiver is of category numeric in MOVE or SET cobc: * typeck.c (cb_tree_is_numeric_ref_or_field, cb_tree_list_has_numeric_ref_or_field): new helper functions to check whether a given item is of category numeric (edited or not) * typeck.c (cb_emit_incompat_data_checks): use new helper function * typeck.c (cb_emit_move, cb_emit_set_to): do not check for incompatible data if no receiver field is of category numeric or numeric edited --- NEWS | 8 +++++++ cobc/ChangeLog | 9 ++++++++ cobc/typeck.c | 39 +++++++++++++++++++++++++-------- tests/testsuite.src/run_misc.at | 34 ++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index c8d40a37f..090f6a4ca 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,14 @@ NEWS - user visible changes -*- outline -*- more work in progress +* Changes that potentially effect recompilation of existing programs: + +** runtime checks for invalid numerical data in emitter fields of MOVE or SET + statements are now performed only when at least one receiver field + is of category numeric or numeric-edited. This enables programming + patterns where invalid numerical data (e.g, SPACES) encode "absent" + data + * Important Bugfixes ** #904: MOVE PACKED-DECIMAL unsigned to signed led to bad sign diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 2cb212623..91014b5db 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,13 @@ +2024-09-25 Nicolas Berthier + + * typeck.c (cb_tree_is_numeric_ref_or_field) + (cb_tree_list_has_numeric_ref_or_field): new helper functions to check + whether a given item is of category numeric (edited or not) + * typeck.c (cb_emit_incompat_data_checks): use new helper function + * typeck.c (cb_emit_move, cb_emit_set_to): do not check for incompatible + data if no receiver field is of category numeric or numeric edited + 2024-08-28 David Declerck * tree.c (char_to_precedence_idx, get_char_type_description, valid_char_order): diff --git a/cobc/typeck.c b/cobc/typeck.c index 1b2a5039a..391ebaba5 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -1055,16 +1055,31 @@ cb_emit_list (cb_tree l) return l; } +static COB_INLINE COB_A_INLINE int +cb_tree_is_numeric_ref_or_field (cb_tree x, int include_numeric_edited) { + int cat; + if (!x || !CB_REF_OR_FIELD_P (x)) { + return 0; + } + cat = CB_TREE_CATEGORY (x); + return (cat == CB_CATEGORY_NUMERIC + || (include_numeric_edited && cat == CB_CATEGORY_NUMERIC_EDITED)); +} + +static int +cb_tree_list_has_numeric_ref_or_field (cb_tree l) { + for (l; + l && !cb_tree_is_numeric_ref_or_field (CB_VALUE (l), 1); + l = CB_CHAIN (l)); + return (l != NULL); +} + static void cb_emit_incompat_data_checks (cb_tree x) { struct cb_field *f; - if (!x || x == cb_error_node) { - return; - } - if (!CB_REF_OR_FIELD_P (x) - || CB_TREE_CATEGORY (x) != CB_CATEGORY_NUMERIC) { + if (!cb_tree_is_numeric_ref_or_field (x, 0)) { return; } f = CB_FIELD_PTR (x); @@ -12884,8 +12899,11 @@ cb_emit_move (cb_tree src, cb_tree dsts) return; } - /* validate / fix-up source, if requested */ - cb_emit_incompat_data_checks (src); + /* validate / fix-up source, if at least one receiver is of category + numeric */ + if (cb_tree_list_has_numeric_ref_or_field (dsts)) { + cb_emit_incompat_data_checks (src); + } /* FIXME: this is way to much to cater for sum field */ src = cb_check_sum_field (src); @@ -13725,8 +13743,11 @@ cb_emit_set_to (cb_tree vars, cb_tree src) return; } - /* validate / fix-up source, if requested */ - cb_emit_incompat_data_checks (src); + /* validate / fix-up source, if at least one receiver is of category + numeric */ + if (cb_tree_list_has_numeric_ref_or_field (vars)) { + cb_emit_incompat_data_checks (src); + } /* Emit statements. */ for (l = vars; l; l = CB_CHAIN (l)) { diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 210a28758..914a8f4a1 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -1172,6 +1172,40 @@ AT_CHECK([$COBCRUN_DIRECT ./prog2], [1], [], AT_CLEANUP +AT_SETUP([MOVE of invalid data from numeric to alphanumeric item]) +AT_KEYWORDS([runmisc]) + +AT_DATA([prog.cob], [ + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 77 X-NUM PIC 9. + 77 X-ALN REDEFINES X-NUM PIC X. + 77 Y-ALN PIC X. + 77 Z-NUM PIC +9,9. + 77 Z-ALN REDEFINES Z-NUM PIC XX. + 77 T-ALN PIC XX. + PROCEDURE DIVISION. + MAIN. + MOVE SPACES TO X-ALN + MOVE X-NUM TO Y-ALN + IF Y-ALN NOT EQUAL " " THEN + DISPLAY "Y-ALN: '" Y-ALN "' (' ' EXPECTED)" + END-IF + MOVE SPACES TO Z-ALN + MOVE Z-NUM TO T-ALN + IF T-ALN NOT EQUAL " " THEN + DISPLAY "T-ALN: '" T-ALN "' (' ' EXPECTED)" + END-IF + STOP RUN. +]) + +AT_CHECK([$COMPILE prog.cob], [0], [], []) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP + + ## CALL statement AT_SETUP([Dynamic call with static linking]) From e3283da760178d18ba30fde5fccaeda057b1682d Mon Sep 17 00:00:00 2001 From: Simon Sobisch Date: Fri, 27 Sep 2024 12:20:25 +0000 Subject: [PATCH 44/51] CI: adding minimal build * based on CI-Dstribution, using download-artifact additional: * added NIST85 summary and duration files to the NIST result artifact * adjust artifact names to prevent conflicts --- .github/workflows/ubuntu.yml | 110 ++++++++++++++++++++++++++++++----- 1 file changed, 97 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index edc22687c..1a3df6462 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -1,26 +1,25 @@ name: Ubuntu Workflow on: + pull_request: branches: [ gcos4gnucobol-3.x ] push: # manual run in actions tab - for all branches workflow_dispatch: + jobs: + build: name: Build, test and provide nightly strategy: fail-fast: false matrix: - os: [ ubuntu-latest ] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - name: Checkout code - uses: actions/checkout@v4 - - name: Install packages run: | sudo apt-get update @@ -32,6 +31,10 @@ jobs: git config --global user.name github-actions git config --global user.email github-actions-bot@users.noreply.github.com + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - name: Checkout code + uses: actions/checkout@v4 + - name: Bootstrap run: | ./build_aux/bootstrap @@ -70,7 +73,7 @@ jobs: uses: actions/upload-artifact@v4 if: failure() with: - name: config-${{ matrix.os }}.log + name: config-${{ matrix.os }}-${{ github.job }}.log path: _build/config.log - name: Build @@ -91,7 +94,7 @@ jobs: if: failure() with: # Assume there's only one directory matching `_build/gnucobol-*`: - name: testsuite-${{ matrix.os }}.log + name: testsuite-${{ matrix.os }}-${{ github.job }}.log path: _build/gnucobol-${{ env.VERSION }}/_build/sub/tests/testsuite.log - name: Upload dist tarball @@ -118,10 +121,92 @@ jobs: - name: Upload NIST85 Test Suite results uses: actions/upload-artifact@v4 with: - name: NIST85 results on ${{ matrix.os }} + name: NIST85 results on ${{ matrix.os }}-${{ github.job }} path: | + _build/tests/cobol85/summary.* _build/tests/cobol85/**/*.log _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt + + minmal_build: + name: Build and test with minimal dependencies + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + needs: build + runs-on: ${{ matrix.os }} + + steps: + + - name: Install packages + run: | + sudo apt-get update + sudo apt-get install build-essential libgmp-dev + + - name: Get CI dist tarball + uses: actions/download-artifact@v4 + with: + name: gnucobol-ci source distribution + + - name: Build environment setup + run: | + tar -xvf gnucobol*.tar.* --strip-components=1 + mkdir _build + + - name: Configure + run: | + cd _build + ../configure --disable-dependency-tracking \ + --without-db --without-curses \ + --without-xml2 --without-json \ + --without-iconv --disable-nls + + - name: Upload config.log + uses: actions/upload-artifact@v4 + if: failure() + with: + name: config-${{ matrix.os }}-${{ github.job }}.log + path: _build/config.log + + - name: Build + run: | + make -C _build --jobs=$(($(nproc)+1)) + + - name: run internal tests + run: | + make -C _build check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || \ + make -C _build check TESTSUITEFLAGS="--recheck --verbose" + + - name: Upload testsuite.log + uses: actions/upload-artifact@v4 + if: failure() + with: + name: testsuite-${{ matrix.os }}-${{ github.job }}.log + path: _build/tests/testsuite.log + + - name: Cache newcob.val + uses: actions/cache@v4 + with: + path: _build/tests/cobol85/newcob.val + key: newcob-val + save-always: true + enableCrossOsArchive: true + + - name: NIST85 Test Suite + run: | + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) + + - name: Upload NIST85 Test Suite results + uses: actions/upload-artifact@v4 + with: + name: NIST85 results on ${{ matrix.os }}-${{ github.job }} + path: | + _build/tests/cobol85/summary.* + _build/tests/cobol85/**/*.log + _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt coverage: @@ -163,7 +248,7 @@ jobs: uses: actions/upload-artifact@v4 if: failure() with: - name: config-${{ matrix.os }}.log + name: config-${{ matrix.os }}-${{ github.job }}.log path: _build/config.log - name: Build @@ -182,13 +267,13 @@ jobs: uses: actions/upload-artifact@v4 if: failure() with: - name: testsuite-${{ matrix.os }}.log + name: testsuite-${{ matrix.os }}-${{ github.job }}.log path: _build/tests/testsuite.log - name: Upload coverage report uses: actions/upload-artifact@v4 with: - name: coverage-${{ matrix.os }} + name: coverage path: _build/GnuCOBOL-**-coverage - name: Cache newcob.val @@ -212,7 +297,7 @@ jobs: - name: Upload extended coverage report uses: actions/upload-artifact@v4 with: - name: extended-coverage-${{ matrix.os }} + name: extended-coverage path: _build/extended-coverage - name: Upload coverage to codecov @@ -223,4 +308,3 @@ jobs: # Shall fail until we have a working account on codecov.io fail_ci_if_error: false # optional (default = false) verbose: true # optional (default = false) - From 7b3047cb2616c6be935be3293e9bfeb377d10a13 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Fri, 27 Sep 2024 20:14:07 +0000 Subject: [PATCH 45/51] updaste for NIST85 * DEPENDENCIES: added perl for running NIST85 * tests/cobol85: * summary.pl: compute total duration and modules executed, output those to stderr at the end; close file handles * Makefile.am (summary.out): new target depending on summary.log * Makefile.am (summary.log): catch stderr of summary.pl into summary.out file and output that on stdout * Makefile.am (URL_NEWCOB_Z): replaced by web archive URL --- ChangeLog | 4 ++++ DEPENDENCIES | 8 +++++++ DEPENDENCIES.md | 9 ++++++++ tests/cobol85/ChangeLog | 13 ++++++++---- tests/cobol85/Makefile.am | 39 ++++++++++++++++++++-------------- tests/cobol85/summary.pl | 44 ++++++++++++++++++++++++++++----------- 6 files changed, 85 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 878ba0b5c..e99fe6546 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ +2024-09-27 Simon Sobisch + + * DEPENDENCIES: added perl for running NIST85 + 2024-09-09 Simon Sobisch * README: add documentation for "make checkmanual" diff --git a/DEPENDENCIES b/DEPENDENCIES index 94be483f7..1d2882ed5 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -151,6 +151,14 @@ The following libraries ARE required WHEN : utf8 source encoding needs an implementation of the iconv API. +6) The NIST COBOL85 testsuite sould be used for verification; + the test runner "make test" REQUIRES: + + o Perl >= 5.0005 - https://www.perl.org + + Perl is licensed under its Artistic License, or the GNU General Public License (GPL). + + See HACKING if you wish to hack the GnuCOBOL source or build directly from version control as this includes the list of additional tools necessary for this task. diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index b14b73815..2da3e8cc8 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -131,3 +131,12 @@ If this is not provided by libc, it is provided by: * [libiconv](https://www.gnu.org/software/libiconv/) GNU libiconv is distributed under GNU Lesser General Public License. + + +NIST COBOL85 testsuite +---------------------------- +To be able to run `make test`: + +* [Perl](https://www.perl.org) >= 5.0005 + + Perl is licensed under its Artistic License, or the GNU General Public License (GPL). diff --git a/tests/cobol85/ChangeLog b/tests/cobol85/ChangeLog index fa52b1d5f..9deb8f786 100644 --- a/tests/cobol85/ChangeLog +++ b/tests/cobol85/ChangeLog @@ -1,7 +1,12 @@ -2024-08-27 Nicolas Berthier +2024-09-27 Simon Sobisch - * Makefile.am: stop downloading "newcob.val.Z" from out-dated URL + * summary.pl: compute total duration and modules executed, + output those to stderr at the end; close file handles + * Makefile.am (summary.out): new target depending on summary.log + * Makefile.am (summary.log): catch stderr of summary.pl into + summary.out file and output that on stdout + * Makefile.am (URL_NEWCOB_Z): replaced by web archive URL 2023-06-02 Simon Sobisch @@ -61,7 +66,7 @@ 2020-11-21 Simon Sobisch - * Makefil.module.in: don't pass additional params to atlocal + * Makefile.module.in: don't pass additional params to atlocal * report.pl: now exporting at_group for more useful valgrind log names 2020-10-16 Simon Sobisch @@ -400,7 +405,7 @@ * SQ.txt, summary.txt : We now pass the LINAGE tests -Copyright 2005-2010,2015-2020,2022-2023 Free Software Foundation, Inc. +Copyright 2005-2010,2015-2020,2022-2024 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. diff --git a/tests/cobol85/Makefile.am b/tests/cobol85/Makefile.am index 1490ef85c..edc99d9be 100644 --- a/tests/cobol85/Makefile.am +++ b/tests/cobol85/Makefile.am @@ -1,7 +1,7 @@ # # Makefile gnucobol/tests/cobol85 # -# Copyright (C) 2002-2012, 2015-2023 Free Software Foundation, Inc. +# Copyright (C) 2002-2012, 2015-2024 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch # # This file is part of GnuCOBOL. @@ -24,22 +24,28 @@ RM = rm -rf -MODULES_ALL = NC SM IC SQ RL ST SG OB IF RW DB IX DBNOIX CM +MODULES_ALL = NC SQ IX IF ST IC RL SM SG OB DB DBNOIX RW CM # currently untested modules: CM +# note: MODULES should be kept in order to not change the order +# in the summary files; +# MODULES_RUN is kept in descending order of runtime duration +# to allow faster builds with multiple jobs if COB_MAKE_IX MODULES = NC SM IC SQ RL ST SG OB IF RW DB IX -MODULES_RUN = NC_RUN SM_RUN IC_RUN SQ_RUN RL_RUN \ - ST_RUN SG_RUN OB_RUN IF_RUN RW_RUN DB_RUN IX_RUN +MODULES_RUN = NC_RUN SQ_RUN IX_RUN IF_RUN ST_RUN \ + IC_RUN RL_RUN SM_RUN SG_RUN OB_RUN DB_RUN RW_RUN SUMMARY = summary.txt else MODULES = NC SM IC SQ RL ST SG OB IF RW DBNOIX -MODULES_RUN = NC_RUN SM_RUN IC_RUN SQ_RUN RL_RUN \ - ST_RUN SG_RUN OB_RUN IF_RUN RW_RUN DBNOIX_RUN +MODULES_RUN = NC_RUN SQ_RUN IX_RUN IF_RUN ST_RUN \ + IC_RUN RL_RUN SM_RUN SG_RUN OB_RUN DBNOIX_RUN RW_RUN SUMMARY = summarynoix.txt endif -URL_NEWCOB_Z = https://www.itl.nist.gov/div897/ctg/suites/newcob.val.Z +# currently down, leading to se report.txt) # then remove the rm of the file below -summary.log: +summary.log: duration.log @echo "Computing total test results..." - @$(PERL) "$(srcdir)/summary.pl" $(MODULES) > $@ + @$(PERL) "$(srcdir)/summary.pl" $(MODULES) 1> $@ 2>summary.out + @cat summary.out + +summary.out: summary.log diff: @echo "Comparing test results for each module" @@ -169,13 +178,11 @@ diff-summary: @diff $(DIFF_FLAGS) "$(srcdir)/$(SUMMARY)" "summary.log" @echo Done -# Note: $(URL_NEWCOB_Z) is out-dated and simply grabs an HTML file -# without error. -# newcob.val.Z: -# @echo "Trying to download newcob.val.Z..." -# @(which curl 1>/dev/null && curl $(CURL_FLAGS) "$(URL_NEWCOB_Z)" -o $@) || \ -# wget $(WGET_FLAGS) "$(URL_NEWCOB_Z)" || \ -# ($(RM) $@; echo "Downloading $@ failed"; false) +newcob.val.Z: + @echo "Trying to download newcob.val.Z..." + @(which curl 1>/dev/null && curl $(CURL_FLAGS) "$(URL_NEWCOB_Z)" -o $@) || \ + wget $(WGET_FLAGS) "$(URL_NEWCOB_Z)" || \ + ($(RM) $@; echo "Downloading $@ failed"; false) newcob.val.tar.gz: @echo "Trying to download newcob.val.tar.gz..." diff --git a/tests/cobol85/summary.pl b/tests/cobol85/summary.pl index c51850b91..b3cbbe5c0 100755 --- a/tests/cobol85/summary.pl +++ b/tests/cobol85/summary.pl @@ -1,7 +1,7 @@ # # gnucobol/tests/cobol85/summary.pl # -# Copyright (C) 2002-2012, 2017, 2020 Free Software Foundation, Inc. +# Copyright (C) 2002-2012, 2017, 2020, 2024 Free Software Foundation, Inc. # Written by Keisuke Nishida, Roger While, Simon Sobisch # # This file is part of GnuCOBOL. @@ -35,23 +35,27 @@ my $total_insp = 0; my $total_total = 0; +my $duration = 0; +my $tested_modules = ""; + print ("------ Directory Information ------- --- Total Tests Information ---\n"); print ("Module Programs Executed Error Crash Pass Fail Deleted Inspect Total\n"); print ("------ -------- -------- ----- ----- ----- ---- ------- ------- -----\n"); my $module; while ($module = shift) { - open(IN, "$module/report.txt") or die; - my $test; - my $pass; - my $fail; - my $delete; - my $inspect; - my $progs; - my $executed; - my $error; - my $crash; + my $test; + my $pass; + my $fail; + my $delete; + my $inspect; + my $progs; + my $executed; + my $error; + my $crash; + + open(IN, "$module/report.txt") or die; while () { if (/^Total *(\d+) *(\d+) *(\d+) *(\d+) *(\d+)/) { ($test, $pass, $fail, $delete, $inspect) = ($1, $2, $3, $4, $5); @@ -65,6 +69,8 @@ $crash = $1; } } + close(IN); + printf "%-6s %8d %8d %5d %5d %4d %4d %7d %7d %5d\n", $module, $progs, $executed, $error, $crash, $pass, $fail, $delete, $inspect, $test; @@ -77,10 +83,24 @@ $total_del += $delete; $total_insp += $inspect; $total_total += $test; + + $tested_modules = "$tested_modules$module "; + + open(IN, "$module/duration.txt") or die; + while () { + if (/^Total *([\d.,]+)/) { + $duration += $1; + last; # Exit the loop once 'Total' is found + } + } + close(IN); } print ("------ -------- -------- ----- ----- ----- ---- ------- ------- -----\n"); printf "Total %8d %8d %5d %5d %5d %4d %7d %7d %5d\n", $total_progs, $total_executed, $total_error, $total_crash, $total_pass, $total_fail, $total_del, $total_insp, $total_total; -print STDERR "Total executed programs : $total_executed - Total performed tests : $total_total\n\n"; + +print STDERR "Total executed programs : $total_executed - Total performed tests : $total_total\n"; +print STDERR "Modules tested : $tested_modules\n"; +print STDERR "Total duration : $duration seconds\n\n"; From 10daa94c89368eac5c84c8ce68d29ecbe0dc5188 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Fri, 27 Sep 2024 20:25:28 +0000 Subject: [PATCH 46/51] build system update * configure.ac: require autoconf 2.70 and drop check for lex-library with noyywrap option for AC_PROG_LEX * HACKING: document dependencies autoconf 2.70 and automake 1.16 and several smaller text updates * Makefile.am (checkmanual-code-coverage, checkall-code-coverage): new targets removing the need to do that manually * build_aux/ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4 cobc: * pplex.l, scanner.l: use noyywrap option instead of manually defining related code parts --- ChangeLog | 8 + HACKING | 18 +- Makefile.am | 15 +- build_aux/ChangeLog | 2 +- build_aux/ltmain.sh | 1312 +++++++++++++++++++++++++------------------ cobc/ChangeLog | 5 + cobc/pplex.l | 6 +- cobc/scanner.l | 6 +- configure.ac | 9 +- m4/libtool.m4 | 447 +++++++-------- m4/ltoptions.m4 | 108 ++-- m4/ltversion.m4 | 13 +- 12 files changed, 1102 insertions(+), 847 deletions(-) diff --git a/ChangeLog b/ChangeLog index e99fe6546..21d93b899 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,14 @@ 2024-09-27 Simon Sobisch + * build_aux/ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: + update libtool from 2.46 to 2.53, dropping all manual patches + * configure.ac: require autoconf 2.70 and drop check for lex-library with + noyywrap option for AC_PROG_LEX + * HACKING: document dependencies autoconf 2.70 and automake 1.16 and + several smaller text updates + * Makefile.am (checkmanual-code-coverage, checkall-code-coverage): new + targets removing the need to do that manually * DEPENDENCIES: added perl for running NIST85 2024-09-09 Simon Sobisch diff --git a/HACKING b/HACKING index 2d507ce4a..c9ad4cc49 100644 --- a/HACKING +++ b/HACKING @@ -16,18 +16,18 @@ following extra packages need to be installed with versions equal or greater. If you build from VCS the tools in the first 4 lists are always needed. For running "autogen.sh" (necessary after VCS checkout) / reconfigure: - o autoconf 2.64 - o automake 1.13 - o libtool 2.2.6 + o autoconf 2.70 + o automake 1.16 + o libtool 2.2.6 (2.5.3 highly+ suggested, can be easily installed locally) o m4 1.4.12 -If you modify top-level configure.ac or Makefile.am in any directory then -you will need to run "autoreconf -I m4" to regenerate the necessary files. +If you modify top-level configure.ac or Makefile.am in any directory and rerun +"make", the build system will regenerate the necessary files. -If you want to update to a newer automake/libtool version or get errors -about wrong version numbers in m4 run "autoreconf -vfi -I m4" instead. +If you want to update to a different automake/libtool version or get errors +about wrong version numbers in m4 run "autogen.sh install" instead. -For compiling (when changing flex/bison sources): +For compiling (when changing pparser/scanner sources): o Bison 2.3 (will be changed to 3.6 with GnuCOBOL 4) o Flex 2.5.35 @@ -108,4 +108,4 @@ OR # if you want to compare with an There should be no difference shown as long as the "old version" passed the same tests as the new version - given the example above: there was no support for REPORT WRITER in 2.2 so there would be an expected failure -of the RW tests). +of the RW tests. diff --git a/Makefile.am b/Makefile.am index 5e0001e75..d92eb165b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -166,9 +166,18 @@ vcs-update: distbin distbin-gzip distbin-bzip2 distbin-lzip distbin-xz test: all - cd tests && $(MAKE) $(AM_MAKEFLAGS) test + cd tests && $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) test checkmanual: all - cd tests && $(MAKE) $(AM_MAKEFLAGS) checkmanual + cd tests && $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) checkmanual checkall: check test - + +@CODE_COVERAGE_ENABLED_TRUE@checkmanual-code-coverage: +@CODE_COVERAGE_ENABLED_TRUE@ -$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -k checkmanual +@CODE_COVERAGE_ENABLED_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +@CODE_COVERAGE_ENABLED_FALSE@checkmanual-code-coverage: check-code-coverage + +@CODE_COVERAGE_ENABLED_TRUE@checkall-code-coverage: +@CODE_COVERAGE_ENABLED_TRUE@ -$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -k checkall +@CODE_COVERAGE_ENABLED_TRUE@ $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +@CODE_COVERAGE_ENABLED_FALSE@checkall-code-coverage: check-code-coverage diff --git a/build_aux/ChangeLog b/build_aux/ChangeLog index 1e84a10ea..186b572eb 100644 --- a/build_aux/ChangeLog +++ b/build_aux/ChangeLog @@ -186,7 +186,7 @@ without uname(1) [removed 2014-01-25] from old version -Copyright 2015-2023 Free Software Foundation, Inc. +Copyright 2015-2024 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this notice are preserved. diff --git a/build_aux/ltmain.sh b/build_aux/ltmain.sh index 9c3dc576e..def0a431a 100755 --- a/build_aux/ltmain.sh +++ b/build_aux/ltmain.sh @@ -1,12 +1,12 @@ -#! /bin/sh +#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2014-01-03.01 +## by inline-source v2019-02-19.15 -# libtool (GNU libtool) 2.4.6 +# libtool (GNU libtool) 2.5.3 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996-2015, 2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -26,13 +26,13 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.6 -package_revision=2.4.6 +VERSION=2.5.3 +package_revision=2.5.3 ## ------ ## @@ -64,34 +64,25 @@ package_revision=2.4.6 # libraries, which are installed to $pkgauxdir. # Set a version string for this script. -scriptversion=2015-01-20.17; # UTC +scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 -# Copyright (C) 2004-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2004-2019, 2021, 2023-2024 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# Please report bugs or propose patches to gary@gnu.org. +# Please report bugs or propose patches to: +# ## ------ ## @@ -139,9 +130,12 @@ do _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# These NLS vars are set unconditionally (bootstrap issue #24). Unset those +# in case the environment reset is needed later and the $save_* variant is not +# defined (see the code above). +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' @@ -149,7 +143,7 @@ nl=' ' IFS="$sp $nl" -# There are apparently some retarded systems that use ';' as a PATH separator! +# There are apparently some systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { @@ -159,6 +153,26 @@ if test "${PATH_SEPARATOR+set}" != set; then fi +# func_unset VAR +# -------------- +# Portably unset VAR. +# In some shells, an 'unset VAR' statement leaves a non-zero return +# status if VAR is already unset, which might be problematic if the +# statement is used at the end of a function (thus poisoning its return +# value) or when 'set -e' is active (causing even a spurious abort of +# the script in this case). +func_unset () +{ + { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } +} + + +# Make sure CDPATH doesn't cause `cd` commands to output the target dir. +func_unset CDPATH + +# Make sure ${,E,F}GREP behave sanely. +func_unset GREP_OPTIONS + ## ------------------------- ## ## Locate command utilities. ## @@ -259,7 +273,7 @@ test -z "$SED" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } @@ -295,7 +309,7 @@ test -z "$GREP" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } @@ -360,6 +374,35 @@ sed_double_backslash="\ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" +# require_check_ifs_backslash +# --------------------------- +# Check if we can use backslash as IFS='\' separator, and set +# $check_ifs_backshlash_broken to ':' or 'false'. +require_check_ifs_backslash=func_require_check_ifs_backslash +func_require_check_ifs_backslash () +{ + _G_save_IFS=$IFS + IFS='\' + _G_check_ifs_backshlash='a\\b' + for _G_i in $_G_check_ifs_backshlash + do + case $_G_i in + a) + check_ifs_backshlash_broken=false + ;; + '') + break + ;; + *) + check_ifs_backshlash_broken=: + break + ;; + esac + done + IFS=$_G_save_IFS + require_check_ifs_backslash=: +} + ## ----------------- ## ## Global variables. ## @@ -580,16 +623,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then { $debug_cmd - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1=\$$1\\ \$func_quote_arg_result" } fi @@ -1091,85 +1134,203 @@ func_relative_path () } -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () +# func_quote_portable EVAL ARG +# ---------------------------- +# Internal function to portably implement func_quote_arg. Note that we still +# keep attention to performance here so we as much as possible try to avoid +# calling sed binary (so far O(N) complexity as long as func_append is O(1)). +func_quote_portable () { $debug_cmd - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in - *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + $require_check_ifs_backslash + + func_quote_portable_result=$2 + + # one-time-loop (easy break) + while true + do + if $1; then + func_quote_portable_result=`$ECHO "$2" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` + break fi - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" + # Quote for eval. + case $func_quote_portable_result in + *[\\\`\"\$]*) + # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string + # contains the shell wildcard characters. + case $check_ifs_backshlash_broken$func_quote_portable_result in + :*|*[\[\*\?]*) + func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ + | $SED "$sed_quote_subst"` + break + ;; + esac + + func_quote_portable_old_IFS=$IFS + for _G_char in '\' '`' '"' '$' + do + # STATE($1) PREV($2) SEPARATOR($3) + set start "" "" + func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy + IFS=$_G_char + for _G_part in $func_quote_portable_result + do + case $1 in + quote) + func_append func_quote_portable_result "$3$2" + set quote "$_G_part" "\\$_G_char" + ;; + start) + set first "" "" + func_quote_portable_result= + ;; + first) + set quote "$_G_part" "" + ;; + esac + done + done + IFS=$func_quote_portable_old_IFS ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; + *) ;; esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift + break done + + func_quote_portable_unquoted_result=$func_quote_portable_result + case $func_quote_portable_result in + # double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # many bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_portable_result=\"$func_quote_portable_result\" + ;; + esac } -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - $debug_cmd +# func_quotefast_eval ARG +# ----------------------- +# Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', +# but optimized for speed. Result is stored in $func_quotefast_eval. +if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then + printf -v _GL_test_printf_tilde %q '~' + if test '\~' = "$_GL_test_printf_tilde"; then + func_quotefast_eval () + { + printf -v func_quotefast_eval_result %q "$1" + } + else + # Broken older Bash implementations. Make those faster too if possible. + func_quotefast_eval () + { + case $1 in + '~'*) + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + ;; + *) + printf -v func_quotefast_eval_result %q "$1" + ;; + esac + } + fi +else + func_quotefast_eval () + { + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + } +fi - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; + +# func_quote_arg MODEs ARG +# ------------------------ +# Quote one ARG to be evaled later. MODEs argument may contain zero or more +# specifiers listed below separated by ',' character. This function returns two +# values: +# i) func_quote_arg_result +# double-quoted (when needed), suitable for a subsequent eval +# ii) func_quote_arg_unquoted_result +# has all characters that are still active within double +# quotes backslashified. Available only if 'unquoted' is specified. +# +# Available modes: +# ---------------- +# 'eval' (default) +# - escape shell special characters +# 'expand' +# - the same as 'eval'; but do not quote variable references +# 'pretty' +# - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might +# be used later in func_quote to get output like: 'echo "a b"' instead +# of 'echo a\ b'. This is slower than default on some shells. +# 'unquoted' +# - produce also $func_quote_arg_unquoted_result which does not contain +# wrapping double-quotes. +# +# Examples for 'func_quote_arg pretty,unquoted string': +# +# string | *_result | *_unquoted_result +# ------------+-----------------------+------------------- +# " | \" | \" +# a b | "a b" | a b +# "a b" | "\"a b\"" | \"a b\" +# * | "*" | * +# z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" +# +# Examples for 'func_quote_arg pretty,unquoted,expand string': +# +# string | *_result | *_unquoted_result +# --------------+---------------------+-------------------- +# z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" +func_quote_arg () +{ + _G_quote_expand=false + case ,$1, in + *,expand,*) + _G_quote_expand=: + ;; esac - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" + case ,$1, in + *,pretty,*|*,expand,*|*,unquoted,*) + func_quote_portable $_G_quote_expand "$2" + func_quote_arg_result=$func_quote_portable_result + func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result + ;; + *) + # Faster quote-for-eval for some shells. + func_quotefast_eval "$2" + func_quote_arg_result=$func_quotefast_eval_result ;; esac +} + - func_quote_for_expand_result=$_G_arg +# func_quote MODEs ARGs... +# ------------------------ +# Quote all ARGs to be evaled later and join them into single command. See +# func_quote_arg's description for more info. +func_quote () +{ + $debug_cmd + _G_func_quote_mode=$1 ; shift + func_quote_result= + while test 0 -lt $#; do + func_quote_arg "$_G_func_quote_mode" "$1" + if test -n "$func_quote_result"; then + func_append func_quote_result " $func_quote_arg_result" + else + func_append func_quote_result "$func_quote_arg_result" + fi + shift + done } @@ -1215,8 +1376,8 @@ func_show_eval () _G_cmd=$1 _G_fail_exp=${2-':'} - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" + func_quote_arg pretty,expand "$_G_cmd" + eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" @@ -1241,8 +1402,8 @@ func_show_eval_locale () _G_fail_exp=${2-':'} $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$_G_cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || { @@ -1369,30 +1530,26 @@ func_lt_ver () # End: #! /bin/sh -# Set a version string for this script. -scriptversion=2014-01-07.03; # UTC - # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2010-2019, 2021, 2023-2024 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Please report bugs or propose patches to: +# -# Please report bugs or propose patches to gary@gnu.org. +# Set a version string for this script. +scriptversion=2019-02-19.15; # UTC ## ------ ## @@ -1415,7 +1572,7 @@ scriptversion=2014-01-07.03; # UTC # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. +# starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the @@ -1427,7 +1584,7 @@ scriptversion=2014-01-07.03; # UTC # to display verbose messages only when your user has specified # '--verbose'. # -# After sourcing this file, you can plug processing for additional +# After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. @@ -1476,8 +1633,8 @@ fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## # This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. +# in the main code. A hook is just a list of function names that can be +# run in order later on. # func_hookable FUNC_NAME # ----------------------- @@ -1510,7 +1667,8 @@ func_add_hook () # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +# Remove HOOK_FUNC from the list of hook functions to be called by +# FUNC_NAME. func_remove_hook () { $debug_cmd @@ -1519,10 +1677,28 @@ func_remove_hook () } +# func_propagate_result FUNC_NAME_A FUNC_NAME_B +# --------------------------------------------- +# If the *_result variable of FUNC_NAME_A _is set_, assign its value to +# *_result variable of FUNC_NAME_B. +func_propagate_result () +{ + $debug_cmd + + func_propagate_result_result=: + if eval "test \"\${${1}_result+set}\" = set" + then + eval "${2}_result=\$${1}_result" + else + func_propagate_result_result=false + fi +} + + # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more +# It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. @@ -1532,22 +1708,19 @@ func_run_hooks () case " $hookable_fns " in *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; + *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' - - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift + func_unset "${_G_hook}_result" + eval $_G_hook '${1+"$@"}' + func_propagate_result $_G_hook func_run_hooks + if $func_propagate_result_result; then + eval set dummy "$func_run_hooks_result"; shift + fi done - - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result } @@ -1557,10 +1730,18 @@ func_run_hooks () ## --------------- ## # In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, remove any -# options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. Like this: +# full positional parameter list from your hook function. You may remove +# or edit any options that you action, and then pass back the remaining +# unprocessed options in '_result', escaped +# suitably for 'eval'. +# +# The '_result' variable is automatically unset +# before your hook gets called; for best performance, only set the +# *_result variable when necessary (i.e. don't call the 'func_quote' +# function unnecessarily because it can be an expensive operation on some +# machines). +# +# Like this: # # my_options_prep () # { @@ -1570,9 +1751,8 @@ func_run_hooks () # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' -# -# func_quote_for_eval ${1+"$@"} -# my_options_prep_result=$func_quote_for_eval_result +# # No change in '$@' (ignored completely by this hook). Leave +# # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # @@ -1581,25 +1761,36 @@ func_run_hooks () # { # $debug_cmd # -# # Note that for efficiency, we parse as many options as we can +# args_changed=false +# +# # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in -# --silent|-s) opt_silent=: ;; +# --silent|-s) opt_silent=: +# args_changed=: +# ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift +# args_changed=: # ;; -# *) set dummy "$_G_opt" "$*"; shift; break ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@" in case we need it later, +# # if $args_changed was set to 'true'. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result +# # Only call 'func_quote' here if we processed at least one argument. +# if $args_changed; then +# func_quote eval ${1+"$@"} +# my_silent_option_result=$func_quote_result +# fi # } # func_add_hook func_parse_options my_silent_option # @@ -1610,17 +1801,26 @@ func_run_hooks () # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." -# -# func_quote_for_eval ${1+"$@"} -# my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # -# You'll alse need to manually amend $usage_message to reflect the extra +# You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + func_run_hooks func_options ${1+"$@"} + func_propagate_result func_run_hooks func_options_finish +} + + # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the @@ -1630,17 +1830,27 @@ func_options () { $debug_cmd - func_options_prep ${1+"$@"} - eval func_parse_options \ - ${func_options_prep_result+"$func_options_prep_result"} - eval func_validate_options \ - ${func_parse_options_result+"$func_parse_options_result"} + _G_options_quoted=false - eval func_run_hooks func_options \ - ${func_validate_options_result+"$func_validate_options_result"} + for my_func in options_prep parse_options validate_options options_finish + do + func_unset func_${my_func}_result + func_unset func_run_hooks_result + eval func_$my_func '${1+"$@"}' + func_propagate_result func_$my_func func_options + if $func_propagate_result_result; then + eval set dummy "$func_options_result"; shift + _G_options_quoted=: + fi + done - # save modified positional parameters for caller - func_options_result=$func_run_hooks_result + $_G_options_quoted || { + # As we (func_options) are top-level options-parser function and + # nobody quoted "$@" for us yet, we need to do it explicitly for + # caller. + func_quote eval ${1+"$@"} + func_options_result=$func_quote_result + } } @@ -1649,9 +1859,8 @@ func_options () # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and -# needs to propogate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning. +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { @@ -1662,9 +1871,7 @@ func_options_prep () opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} - - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result + func_propagate_result func_run_hooks func_options_prep } @@ -1676,25 +1883,32 @@ func_parse_options () { $debug_cmd - func_parse_options_result= - + _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} - - # Adjust func_parse_options positional parameters to match - eval set dummy "$func_run_hooks_result"; shift + func_propagate_result func_run_hooks func_parse_options + if $func_propagate_result_result; then + eval set dummy "$func_parse_options_result"; shift + # Even though we may have changed "$@", we passed the "$@" array + # down into the hook and it quoted it for us (because we are in + # this if-branch). No need to quote it again. + _G_parse_options_requote=false + fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break + # We expect that one of the options parsed in this function matches + # and thus we remove _G_opt from "$@" and need to re-quote. + _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" + func_echo "enabling shell trace mode" >&2 $debug_cmd ;; @@ -1704,7 +1918,10 @@ func_parse_options () ;; --warnings|--warning|-W) - test $# = 0 && func_missing_arg $_G_opt && break + if test $# = 0 && func_missing_arg $_G_opt; then + _G_parse_options_requote=: + break + fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above @@ -1757,15 +1974,24 @@ func_parse_options () shift ;; - --) break ;; + --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; esac + + if $_G_match_parse_options; then + _G_parse_options_requote=: + fi done - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result + if $_G_parse_options_requote; then + # save modified positional parameters for caller + func_quote eval ${1+"$@"} + func_parse_options_result=$func_quote_result + fi } @@ -1782,12 +2008,10 @@ func_validate_options () test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} + func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE - - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result } @@ -1843,8 +2067,8 @@ func_missing_arg () # func_split_equals STRING # ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. +# Set func_split_equals_lhs and func_split_equals_rhs shell variables +# after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ @@ -1859,8 +2083,9 @@ then func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= + if test "x$func_split_equals_lhs" = "x$1"; then + func_split_equals_rhs= + fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. @@ -1870,7 +2095,7 @@ else func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ + test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals @@ -1896,7 +2121,7 @@ else { $debug_cmd - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt @@ -1938,31 +2163,44 @@ func_usage_message () # func_version # ------------ # Echo version message to standard output and exit. +# The version message is extracted from the calling file's header +# comments, with leading '# ' stripped: +# 1. First display the progname and version +# 2. Followed by the header comment line matching /^# Written by / +# 3. Then a blank line followed by the first following line matching +# /^# Copyright / +# 4. Immediately followed by any lines between the previous matches, +# except lines preceding the intervening completely blank line. +# For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more - } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p + /^# Written by /!b + s|^# ||; p; n + + :fwd2blnk + /./ { + n + b fwd2blnk } - /^# Written by / { - s|^# || - p + p; n + + :holdwrnt + s|^# || + s|^# *$|| + /^Copyright /!{ + /./H + n + b holdwrnt } - /^warranty; /q' < "$progpath" + + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + G + s|\(\n\)\n*|\1|g + p; q' < "$progpath" exit $? } @@ -1972,12 +2210,12 @@ func_version () # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. -scriptversion='(GNU libtool) 2.4.6' +scriptversion='(GNU libtool) 2.5.3' # func_echo ARG... @@ -2068,13 +2306,13 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 + version: $progname (GNU libtool) 2.5.3 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . -GNU libtool home page: . -General help using GNU software: ." +GNU libtool home page: . +General help using GNU software: ." exit 0 } @@ -2124,7 +2362,7 @@ fi # a configuration failure hint, and exit. func_fatal_configuration () { - func__fatal_error ${1+"$@"} \ + func_fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } @@ -2270,6 +2508,8 @@ libtool_options_prep () nonopt= preserve_args= + _G_rc_lt_options_prep=: + # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) @@ -2293,11 +2533,16 @@ libtool_options_prep () uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; + *) + _G_rc_lt_options_prep=false + ;; esac - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote eval ${1+"$@"} + libtool_options_prep_result=$func_quote_result + fi } func_add_hook func_options_prep libtool_options_prep @@ -2309,9 +2554,12 @@ libtool_parse_options () { $debug_cmd + _G_rc_lt_parse_options=false + # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do + _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -2386,15 +2634,20 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote eval ${1+"$@"} + libtool_parse_options_result=$func_quote_result + fi } func_add_hook func_parse_options libtool_parse_options @@ -2415,10 +2668,10 @@ libtool_validate_options () # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" - case $host in + case $host_os in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 - *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + cygwin* | mingw* | windows* | pw32* | cegcc* | solaris2* | os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; @@ -2451,8 +2704,8 @@ libtool_validate_options () } # Pass back the unparsed argument list - func_quote_for_eval ${1+"$@"} - libtool_validate_options_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options @@ -2750,7 +3003,7 @@ EOF # func_convert_core_file_wine_to_w32 ARG # Helper function used by file name conversion functions when $build is *nix, -# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# and $host is mingw, windows, cygwin, or some other w32 environment. Relies on a # correctly configured wine environment available, with the winepath program # in $build's $PATH. # @@ -2782,9 +3035,10 @@ func_convert_core_file_wine_to_w32 () # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. +# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. Assumes ARG has no leading or trailing path separator +# characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. @@ -3418,8 +3672,8 @@ func_mode_compile () esac done - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ + func_quote_arg pretty "$libobj" + test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" @@ -3439,7 +3693,7 @@ func_mode_compile () # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) + cygwin* | mingw* | windows* | pw32* | os2* | cegcc*) pic_mode=default ;; esac @@ -3492,8 +3746,8 @@ compiler." func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result + func_quote_arg pretty "$srcfile" + qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then @@ -3648,7 +3902,8 @@ This mode accepts the following additional options: -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler + -Wc,FLAG + -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. @@ -3754,6 +4009,8 @@ The following components of LINK-COMMAND are treated specially: -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wa,FLAG + -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) @@ -4096,8 +4353,8 @@ func_mode_install () case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " + func_quote_arg pretty "$nonopt" + install_prog="$func_quote_arg_result " arg=$1 shift else @@ -4107,8 +4364,8 @@ func_mode_install () # The real first argument should be the name of the installation program. # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; @@ -4165,12 +4422,12 @@ func_mode_install () esac # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then - func_quote_for_eval "$arg2" + func_quote_arg pretty "$arg2" fi - func_append install_shared_prog " $func_quote_for_eval_result" + func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ @@ -4181,8 +4438,8 @@ func_mode_install () if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" + func_quote_arg pretty "$install_override_mode" + func_append install_shared_prog " -m $func_quote_arg_result" fi fi @@ -4313,7 +4570,7 @@ func_mode_install () 'exit $?' tstripme=$stripme case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= @@ -4426,7 +4683,7 @@ func_mode_install () # Do a test to see if this is really a libtool program. case $host in - *cygwin* | *mingw*) + *cygwin* | *mingw* | *windows*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result @@ -4478,8 +4735,8 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$relink_command" + eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else @@ -4654,7 +4911,7 @@ extern \"C\" { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; @@ -4666,7 +4923,7 @@ extern \"C\" { eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; @@ -4680,7 +4937,7 @@ extern \"C\" { func_basename "$dlprefile" name=$func_basename_result case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" @@ -4706,8 +4963,16 @@ extern \"C\" { eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + case $host in + i[3456]86-*-mingw32*) + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + ;; + *) + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/__nm_//' >> '$nlist'" + ;; + esac } else # not an import lib $opt_dry_run || { @@ -4855,7 +5120,7 @@ static const void *lt_preloaded_setup() { # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` @@ -4931,7 +5196,7 @@ func_win32_libid () *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || @@ -5198,7 +5463,7 @@ func_extract_archives () # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw +# incorporate the script contents within a cygwin/mingw/windows # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. @@ -5206,7 +5471,7 @@ func_extract_archives () # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is -# the $objdir directory. This is a cygwin/mingw-specific +# the $objdir directory. This is a cygwin/mingw/windows-specific # behavior. func_emit_wrapper () { @@ -5258,7 +5523,8 @@ else if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + func_quote_arg pretty "$ECHO" + qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. @@ -5268,7 +5534,7 @@ func_fallback_echo () \$1 _LTECHO_EOF' } - ECHO=\"$qECHO\" + ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to @@ -5330,7 +5596,7 @@ func_exec_program_core () " case $host in # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) + *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 @@ -5398,7 +5664,7 @@ func_exec_program () file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done - # Usually 'no', except on cygwin/mingw when embedded into + # Usually 'no', except on cygwin/mingw/windows when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then @@ -5530,7 +5796,7 @@ EOF #endif #include #include -#if defined (_WIN32) && !defined (__GNUC__) +#if defined _WIN32 && !defined __GNUC__ # include # include # include @@ -5555,7 +5821,7 @@ EOF /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ -int _putenv (const char *); +_CRTIMP int __cdecl _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ @@ -5753,7 +6019,7 @@ main (int argc, char *argv[]) { EOF case $host in - *mingw* | *cygwin* ) + *mingw* | *windows* | *cygwin* ) # make stdout use "unix" line endings echo " setmode(1,_O_BINARY);" ;; @@ -5772,7 +6038,7 @@ EOF { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and - have already dealt with, above (inluding dump-script), then + have already dealt with, above (including dump-script), then report an error. Otherwise, targets might begin to believe they are allowed to use options in the LTWRAPPER_OPTION_PREFIX namespace. The first time any user complains about this, we'll @@ -5856,7 +6122,7 @@ EOF EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" { char* p; @@ -5898,7 +6164,7 @@ EOF EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ newargz = prepare_spawn (newargz); @@ -6317,7 +6583,7 @@ lt_update_lib_path (const char *name, const char *value) EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). @@ -6492,7 +6758,7 @@ func_mode_link () $debug_cmd case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra @@ -6556,10 +6822,12 @@ func_mode_link () xrpath= perm_rpath= temp_rpath= + temp_rpath_tail= thread_safe=no vinfo= vinfo_number=no weak_libs= + rpath_arg= single_module=$wl-single_module func_infer_tag $base_compile @@ -6611,9 +6879,9 @@ func_mode_link () while test "$#" -gt 0; do arg=$1 shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" + func_quote_arg pretty,unquoted "$arg" + qarg=$func_quote_arg_unquoted_result + func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then @@ -6822,7 +7090,7 @@ func_mode_link () case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) - func_fatal_error "only absolute run-paths are allowed" + func_fatal_error "argument to -rpath is not absolute: $arg" ;; esac if test rpath = "$prev"; then @@ -6849,6 +7117,13 @@ func_mode_link () prev= continue ;; + xassembler) + func_append compiler_flags " -Xassembler $qarg" + prev= + func_append compile_command " -Xassembler $qarg" + func_append finalize_command " -Xassembler $qarg" + continue + ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" @@ -6991,7 +7266,7 @@ func_mode_link () ;; esac case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; @@ -7011,7 +7286,7 @@ func_mode_link () -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; @@ -7019,7 +7294,7 @@ func_mode_link () # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; @@ -7039,7 +7314,7 @@ func_mode_link () esac elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -7069,9 +7344,21 @@ func_mode_link () prev=xcompiler continue ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. + -pthread) + case $host in + *solaris2*) ;; + *) + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + ;; + esac + continue + ;; + -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -7094,7 +7381,7 @@ func_mode_link () -no-install) case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" @@ -7154,7 +7441,7 @@ func_mode_link () dir=$lt_sysroot$func_stripname_result ;; *) - func_fatal_error "only absolute run-paths are allowed" + func_fatal_error "argument ($arg) to '-R' is not an absolute path: $dir" ;; esac case "$xrpath " in @@ -7211,9 +7498,9 @@ func_mode_link () save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" + func_quote_arg pretty "$flag" + func_append arg " $func_quote_arg_result" + func_append compiler_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" @@ -7227,16 +7514,21 @@ func_mode_link () save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" + func_quote_arg pretty "$flag" + func_append arg " $wl$func_quote_arg_result" + func_append compiler_flags " $wl$func_quote_arg_result" + func_append linker_flags " $func_quote_arg_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; + -Xassembler) + prev=xassembler + continue + ;; + -Xcompiler) prev=xcompiler continue @@ -7254,8 +7546,8 @@ func_mode_link () # -msg_* for osf cc -msg_*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; # Flags to be passed through unchanged, with rationale: @@ -7272,12 +7564,33 @@ func_mode_link () # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang + # -fdiagnostics-color* simply affects output + # -frecord-gcc-switches used to verify flags were respected + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fno-sanitize* Clang/GCC memory and address sanitizer + # -shared-libsan Link with shared sanitizer runtimes (Clang) + # -static-libsan Link with static sanitizer runtimes (Clang) + # -no-canonical-prefixes Do not expand any symbolic links + # -fuse-ld=* Linker select flags for GCC + # -static-* direct GCC to link specific libraries statically + # -fcilkplus Cilk Plus language extension features for C/C++ + # -rtlib=* select c runtime lib with clang + # --unwindlib=* select unwinder library with clang + # -f{file|debug|macro|profile}-prefix-map=* needed for lto linking + # -Wa,* Pass flags directly to the assembler + # -Werror, -Werror=* Report (specified) warnings as errors -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-no-canonical-prefixes| \ + -stdlib=*|-rtlib=*|--unwindlib=*| \ + -specs=*|-fsanitize=*|-fno-sanitize*|-shared-libsan|-static-libsan| \ + -ffile-prefix-map=*|-fdebug-prefix-map=*|-fmacro-prefix-map=*|-fprofile-prefix-map=*| \ + -fdiagnostics-color*|-frecord-gcc-switches| \ + -fuse-ld=*|-static-*|-fcilkplus|-Wa,*|-Werror|-Werror=*) + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" @@ -7298,15 +7611,15 @@ func_mode_link () continue else # Otherwise treat like 'Some other compiler flag' below - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result fi ;; # Some other compiler flag. -* | +*) - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; *.$objext) @@ -7426,15 +7739,27 @@ func_mode_link () *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg=$func_quote_for_eval_result + func_quote_arg pretty "$arg" + arg=$func_quote_arg_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" + if test -n "$rpath_arg"; then + func_append finalize_rpath " ${arg##*,}" + unset rpath_arg + else + case $arg in + -Wl,-rpath,*) + func_append finalize_rpath " ${arg##*,}";; + -Wl,-rpath) + rpath_arg=1;; + *) + func_append compile_command " $arg" + func_append finalize_command " $arg" + esac + fi fi done # argument parsing loop @@ -7605,7 +7930,7 @@ func_mode_link () found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" @@ -7782,18 +8107,15 @@ func_mode_link () ;; esac if $valid_a_lib; then - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" + func_warning "Linking the shared library $output against the static library $deplib is not portable!" deplibs="$deplib $deplibs" else - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." + func_warning "Trying to link with static lib archive $deplib." + func_warning "I have the capability to make that library automatically link in when" + func_warning "you link to this library. But I can only do this if you have a" + func_warning "shared version of the library, which you do not appear to have" + func_warning "because the file extensions .$libext of this argument makes me believe" + func_warning "that it is just a static archive that I should not use here." fi ;; esac @@ -7988,7 +8310,7 @@ func_mode_link () fi case $host in # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present @@ -8088,7 +8410,10 @@ func_mode_link () # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; + *) case $absdir in + "$progdir/"*) func_append temp_rpath "$absdir:" ;; + *) func_append temp_rpath_tail "$absdir:" ;; + esac esac fi @@ -8100,7 +8425,9 @@ func_mode_link () *) case "$compile_rpath " in *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; + *) case $absdir in + "$progdir/"*) func_append compile_rpath " $absdir" ;; + esac esac ;; esac @@ -8131,8 +8458,8 @@ func_mode_link () fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc* | *os2*) + case $host_os in + cygwin* | mingw* | windows* | cegcc* | os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no @@ -8158,11 +8485,11 @@ func_mode_link () if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" + func_warning "Linking the executable $output against the loadable module" else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" + func_warning "Linking the shared library $output against the loadable module" fi - $ECHO "*** $linklib is not portable!" + func_warning "$linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then @@ -8174,7 +8501,9 @@ func_mode_link () *) case "$compile_rpath " in *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; + *) case $absdir in + "$progdir/"*) func_append compile_rpath " $absdir" ;; + esac esac ;; esac @@ -8201,8 +8530,8 @@ func_mode_link () soname=$dlname elif test -n "$soname_spec"; then # bleh windows - case $host in - *cygwin* | mingw* | *cegcc* | *os2*) + case $host_os in + cygwin* | mingw* | windows* | cegcc* | os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major @@ -8257,11 +8586,10 @@ func_mode_link () if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" + func_warning "lib $linklib is a module, not a shared library" if test -z "$old_library"; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" + func_warning "And there doesn't seem to be a static archive available" + func_warning "The link will probably fail, sorry" else add=$dir/$old_library fi @@ -8344,7 +8672,7 @@ func_mode_link () test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then - add_dir=-L$libdir + add_dir=-L$lt_sysroot$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in @@ -8361,7 +8689,7 @@ func_mode_link () fi else # We cannot seem to hardcode it, guess we'll fake it. - add_dir=-L$libdir + add_dir=-L$lt_sysroot$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -8401,21 +8729,19 @@ func_mode_link () # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system cannot link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." + func_warning "This system cannot link to static lib archive $lib." + func_warning "I have the capability to make that library automatically link in when" + func_warning "you link to this library. But I can only do this if you have a" + func_warning "shared version of the library, which you do not appear to have." if test yes = "$module"; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + func_warning "But as you try to build a module library, libtool will still create " + func_warning "a static module, that should work as long as the dlopening application" + func_warning "is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using 'nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** 'nm' from GNU binutils and a full rebuild may help." + func_warning "However, this would only work if libtool was able to extract symbol" + func_warning "lists from a program, using 'nm' or equivalent, but libtool could" + func_warning "not find such a program. So, this module is probably useless." + func_warning "'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module @@ -8538,6 +8864,8 @@ func_mode_link () fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs + + func_append temp_rpath "$temp_rpath_tail" if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" @@ -8575,42 +8903,46 @@ func_mode_link () # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: new_libs="$deplib $new_libs" for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; + if $opt_preserve_dup_deps; then + new_libs="$deplib $new_libs" + else + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. And if not possible for portability + # reasons, then --preserve-dup-deps should be used. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; esac - ;; - esac + fi done tmp_libs= for deplib in $new_libs; do @@ -8632,7 +8964,7 @@ func_mode_link () test CXX = "$tagname" && { case $host_os in linux*) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi @@ -8742,9 +9074,7 @@ func_mode_link () if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" + func_warning "Linking the shared library $output against the non-libtool objects $objs is not portable!" func_append libobjs " $objs" fi fi @@ -8805,13 +9135,13 @@ func_mode_link () # case $version_type in # correct linux to gnu/linux during the next big refactor - darwin|freebsd-elf|linux|osf|windows|none) + darwin|freebsd-elf|linux|midnightbsd-elf|osf|qnx|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; - freebsd-aout|qnx|sunos) + freebsd-aout|sco|sunos) current=$number_major revision=$number_minor age=0 @@ -8896,7 +9226,7 @@ func_mode_link () versuffix=.$current.$revision ;; - freebsd-elf) + freebsd-elf | midnightbsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision @@ -8958,8 +9288,9 @@ func_mode_link () ;; qnx) - major=.$current - versuffix=.$current + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision ;; sco) @@ -9112,7 +9443,7 @@ func_mode_link () if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) @@ -9122,7 +9453,7 @@ func_mode_link () *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) @@ -9163,108 +9494,6 @@ func_mode_link () # implementing what was already the behavior. newdeplibs=$deplibs ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c < + + * plex.l, scanner.l: use noyywrap option instead of manually + defining related code parts + 2024-09-25 Nicolas Berthier * typeck.c (cb_tree_is_numeric_ref_or_field) diff --git a/cobc/pplex.l b/cobc/pplex.l index 68880bb79..ff73ff912 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -25,6 +25,7 @@ %option prefix="pp" %option stack +%option noyywrap %option noyy_top_state %option noyy_scan_buffer @@ -54,11 +55,6 @@ #undef YY_BUF_SIZE #define YY_BUF_SIZE 32768 -#define YY_SKIP_YYWRAP -static int ppwrap (void) { - return 1; -} - static void insert_copy_arg (void); #define PPLEX_BUFF_LEN 512 diff --git a/cobc/scanner.l b/cobc/scanner.l index 8e199f8a2..878e660e9 100644 --- a/cobc/scanner.l +++ b/cobc/scanner.l @@ -24,6 +24,7 @@ %option case-insensitive %option never-interactive %option nodefault +%option noyywrap %option noyy_scan_buffer %option noyy_scan_bytes @@ -52,11 +53,6 @@ #undef YY_BUF_SIZE #define YY_BUF_SIZE 32768 -#define YY_SKIP_YYWRAP -static int yywrap (void) { - return 1; -} - #define YY_INPUT(buf,result,max_size) \ { \ if (fgets (buf, (int)max_size, yyin) == NULL) { \ diff --git a/configure.ac b/configure.ac index 9d9f387fd..d17fe1540 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,11 @@ dnl You should have received a copy of the GNU General Public License dnl along with GnuCOBOL. If not, see . dnl -AC_PREREQ([2.67]) # note: 2.67 is the one found in old msys, 2.69 is commonly available +# note: old environments only have autoconf 2.69 or even (old msys) 2.67 +# just do a "make dist" on a modern system and get the taball back +# to the ancient one... (which would likely also not have the necessary +# automake package either) +AC_PREREQ([2.70]) AC_INIT([GnuCOBOL], [3.3-dev], @@ -541,6 +545,9 @@ dnl CHECKME: do we want disable-static (mind libsupport) dnl if yes then drop AM_PROG_AR + build_aux/ar-lib LT_INIT([dlopen win32-dll]) +dnl We declare %noyywrap in the lexer files so we use the noyywrap +dnl option here to skip the search for that function. +AC_PROG_LEX([noyywrap]) AX_PROG_FLEX AX_PROG_BISON diff --git a/m4/libtool.m4 b/m4/libtool.m4 index b6a7da5a8..e5ddacee9 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -1,6 +1,7 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996-2001, 2003-2019 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2019, 2021-2024 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -8,13 +9,13 @@ # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl -# Copyright (C) 2014 Free Software Foundation, Inc. +# Copyright (C) 2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of of the License, or +# the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you @@ -28,10 +29,10 @@ m4_define([_LT_COPYING], [dnl # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . ]) -# serial 58 LT_INIT +# serial 62 LT_INIT # LT_PREREQ(VERSION) @@ -59,7 +60,7 @@ esac # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], -[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +[AC_PREREQ([2.64])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl @@ -181,6 +182,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl @@ -614,7 +616,7 @@ m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation +# AC_OUTPUT is called), in case it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} @@ -649,9 +651,9 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. -Copyright (C) 2011 Free Software Foundation, Inc. +Copyright (C) 2024 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." +gives unlimited permission to copy, distribute and modify it." while test 0 != $[#] do @@ -728,7 +730,6 @@ _LT_CONFIG_SAVE_COMMANDS([ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. @@ -778,7 +779,7 @@ _LT_EOF # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || @@ -973,6 +974,7 @@ _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE + # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ @@ -1023,6 +1025,21 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ rm -f conftest.* fi]) + # Feature test to disable chained fixups since it is not + # compatible with '-undefined dynamic_lookup' + AC_CACHE_CHECK([for -no_fixup_chains linker flag], + [lt_cv_support_no_fixup_chains], + [ save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([],[])], + lt_cv_support_no_fixup_chains=yes, + lt_cv_support_no_fixup_chains=no + ) + LDFLAGS=$save_LDFLAGS + ] + ) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no @@ -1047,7 +1064,7 @@ _LT_EOF echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF -int main() { return 0;} +int main(void) { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err @@ -1067,17 +1084,16 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*|11.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' + if test yes = "$lt_cv_support_no_fixup_chains"; then + AS_VAR_APPEND([_lt_dar_allow_undefined], [' $wl-no_fixup_chains']) + fi + ;; esac ;; esac @@ -1126,12 +1142,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], [ if test yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1245,7 +1261,8 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) +[m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot @@ -1258,11 +1275,13 @@ lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` + # Trim trailing / since we'll always append absolute paths and we want + # to avoid //, if only for less confusing output for the user. + lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'` fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -1292,7 +1311,7 @@ ia64-*-hpux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -1309,7 +1328,7 @@ ia64-*-hpux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -1321,7 +1340,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -1343,7 +1362,7 @@ mips64*-*linux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -1351,7 +1370,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -1359,7 +1378,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -1370,7 +1389,7 @@ mips64*-*linux*) ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) +s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when @@ -1379,14 +1398,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in + x86_64-*linux*|x86_64-gnu*) + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -1414,7 +1433,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) @@ -1454,7 +1473,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -1497,7 +1516,7 @@ _LT_DECL([], [AR], [1], [The archiver]) # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have -# higher priority because thats what people were doing historically (setting +# higher priority because that's what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. @@ -1547,7 +1566,7 @@ AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) -AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_REQUIRE([AC_PROG_RANLIB]) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) @@ -1558,15 +1577,8 @@ old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -1705,7 +1717,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -1727,7 +1739,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1770,7 +1782,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -1887,11 +1899,11 @@ else /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); +int fnord (void) __attribute__((visibility("default"))); #endif -int fnord () { return 42; } -int main () +int fnord (void) { return 42; } +int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; @@ -1948,7 +1960,7 @@ else lt_cv_dlopen_self=yes ;; - mingw* | pw32* | cegcc*) + mingw* | windows* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; @@ -2316,7 +2328,7 @@ if test yes = "$GCC"; then *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` @@ -2374,7 +2386,7 @@ BEGIN {RS = " "; FS = "/|\n";} { # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` @@ -2449,7 +2461,7 @@ aix[[4-9]]*) # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the @@ -2543,7 +2555,7 @@ bsdi[[45]]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no @@ -2554,6 +2566,19 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds + # If user builds GCC with mulitlibs enabled, + # it should just install on $(libdir) + # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. + if test yes = $multilib; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' + else postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ @@ -2563,6 +2588,7 @@ cygwin* | mingw* | pw32* | cegcc*) if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' + fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' @@ -2571,17 +2597,17 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' @@ -2594,7 +2620,7 @@ m4_if([$1], [],[ library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -2607,7 +2633,7 @@ m4_if([$1], [],[ done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -2677,7 +2703,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -2701,7 +2727,21 @@ freebsd* | dragonfly*) need_version=yes ;; esac - shlibpath_var=LD_LIBRARY_PATH + case $host_cpu in + powerpc64) + # On FreeBSD bi-arch platforms, a different variable is used for 32-bit + # binaries. See . + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[int test_pointer_size[sizeof (void *) - 5]; + ]])], + [shlibpath_var=LD_LIBRARY_PATH], + [shlibpath_var=LD_32_LIBRARY_PATH]) + ;; + *) + shlibpath_var=LD_LIBRARY_PATH + ;; + esac case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes @@ -2842,7 +2882,7 @@ linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no - library_names_spec='$libname$release$shared_ext' + library_names_spec='$libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH @@ -2854,8 +2894,9 @@ linux*android*) hardcode_into_libs=yes dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + # -rpath works at least for libraries that are not overridden by + # libraries installed in system locations. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; # This must be glibc/ELF. @@ -2889,7 +2930,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) # before this can be enabled. hardcode_into_libs=yes - # Ideally, we could use ldconfig to report *all* directores which are + # Ideally, we could use ldconfig to report *all* directories which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, @@ -2909,18 +2950,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) dynamic_linker='GNU/Linux ld.so' ;; -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - netbsd*) version_type=sunos need_lib_prefix=no @@ -2958,7 +2987,7 @@ newsos6) dynamic_linker='ldqnx.so' ;; -openbsd* | bitrig*) +openbsd*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no @@ -3290,7 +3319,7 @@ if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in - *-*-mingw*) + *-*-mingw* | *-*-windows*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) @@ -3399,7 +3428,7 @@ case $reload_flag in esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi @@ -3471,7 +3500,6 @@ lt_cv_deplibs_check_method='unknown' # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure @@ -3488,7 +3516,7 @@ beos*) bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -3498,7 +3526,7 @@ cygwin*) lt_cv_file_magic_cmd='func_win32_libid' ;; -mingw* | pw32*) +mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. @@ -3507,7 +3535,7 @@ mingw* | pw32*) lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; @@ -3522,14 +3550,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -3543,7 +3571,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' @@ -3580,7 +3608,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; -netbsd* | netbsdelf*-gnu) +netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -3590,7 +3618,7 @@ netbsd* | netbsdelf*-gnu) newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -3598,7 +3626,7 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd* | bitrig*) +openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else @@ -3662,7 +3690,7 @@ file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in - mingw* | pw32*) + mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else @@ -3714,16 +3742,16 @@ else # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; + mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -3749,7 +3777,7 @@ else # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -3805,7 +3833,7 @@ lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in @@ -3837,16 +3865,16 @@ _LT_DECL([], [sharedlib_from_linklib_cmd], [1], m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_manifest_tool], + [lt_cv_path_manifest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes + lt_cv_path_manifest_tool=yes fi rm -f conftest*]) -if test yes != "$lt_cv_path_mainfest_tool"; then +if test yes != "$lt_cv_path_manifest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl @@ -3875,7 +3903,7 @@ AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) @@ -3950,7 +3978,7 @@ case $host_os in aix*) symcode='[[BCDT]]' ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) @@ -3965,7 +3993,7 @@ osf*) symcode='[[BCDEGQRST]]' ;; solaris*) - symcode='[[BDRT]]' + symcode='[[BCDRT]]' ;; sco3.2v5*) symcode='[[DT]]' @@ -3989,7 +4017,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -4007,20 +4035,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -4029,7 +4057,7 @@ $lt_c_name_lib_hook\ # Handle CRLF in mingw tool chain opt_cr= case $build_os in -mingw*) +mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac @@ -4062,9 +4090,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -4080,7 +4108,7 @@ void nm_test_func(void){} #ifdef __cplusplus } #endif -int main(){nm_test_var='a';nm_test_func();return(0);} +int main(void){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then @@ -4256,7 +4284,7 @@ m4_if([$1], [CXX], [ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -4332,7 +4360,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], @@ -4351,7 +4379,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) @@ -4434,7 +4462,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4458,7 +4486,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd* | netbsdelf*-gnu) + netbsd*) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -4580,7 +4608,7 @@ m4_if([$1], [CXX], [ # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -4684,7 +4712,7 @@ m4_if([$1], [CXX], [ esac ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], @@ -4726,6 +4754,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + *flang* | ftn) + # Flang compiler. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -4770,7 +4804,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4959,7 +4993,7 @@ m4_if([$1], [CXX], [ pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) case $cc_basename in cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' @@ -5017,7 +5051,7 @@ dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. @@ -5029,7 +5063,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd* | bitrig*) + openbsd*) with_gnu_ld=no ;; esac @@ -5078,7 +5112,7 @@ dnl Note also adjust exclude_expsyms for C++ above. _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -5132,7 +5166,7 @@ _LT_EOF fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' @@ -5188,7 +5222,7 @@ _LT_EOF cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; @@ -5205,7 +5239,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -5248,7 +5282,7 @@ _LT_EOF _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes @@ -5260,7 +5294,7 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi @@ -5276,7 +5310,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -5287,7 +5321,7 @@ _LT_EOF fi ;; - netbsd* | netbsdelf*-gnu) + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -5589,7 +5623,7 @@ _LT_EOF _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is @@ -5606,14 +5640,14 @@ _LT_EOF # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' @@ -5685,7 +5719,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5829,7 +5863,7 @@ _LT_EOF esac ;; - netbsd* | netbsdelf*-gnu) + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -5851,7 +5885,7 @@ _LT_EOF *nto* | *qnx*) ;; - openbsd* | bitrig*) + openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -5894,7 +5928,7 @@ _LT_EOF cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; @@ -6188,7 +6222,7 @@ _LT_TAGDECL([], [hardcode_direct], [0], _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting $shlibpath_var if the + "absolute", i.e. impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR @@ -6246,7 +6280,7 @@ _LT_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' +lt_simple_link_test_code='int main(void){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other @@ -6435,8 +6469,7 @@ if test yes != "$_lt_caught_CXX_error"; then wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= @@ -6456,7 +6489,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' else GXX=no @@ -6665,7 +6698,7 @@ if test yes != "$_lt_caught_CXX_error"; then esac ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC @@ -6764,7 +6797,7 @@ if test yes != "$_lt_caught_CXX_error"; then cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' ;; @@ -6797,7 +6830,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes @@ -6832,7 +6865,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6897,7 +6930,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6934,7 +6967,7 @@ if test yes != "$_lt_caught_CXX_error"; then # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in @@ -7074,13 +7107,13 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' @@ -7145,7 +7178,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - openbsd* | bitrig*) + openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -7236,7 +7269,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' else # FIXME: insert proper C++ library support @@ -7320,7 +7353,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7331,7 +7364,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' @@ -7569,10 +7602,11 @@ if AC_TRY_EVAL(ac_compile); then case $prev$p in -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. + # Some compilers place space between "-{L,R,l}" and the path. # Remove the space. - if test x-L = "$p" || - test x-R = "$p"; then + if test x-L = x"$p" || + test x-R = x"$p" || + test x-l = x"$p"; then prev=$p continue fi @@ -8226,6 +8260,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) +# _LT_DECL_FILECMD +# ---------------- +# Check for a file(cmd) program that can be used to detect file type and magic +m4_defun([_LT_DECL_FILECMD], +[AC_CHECK_PROG([FILECMD], [file], [file], [:]) +_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) +])# _LD_DECL_FILECMD + # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates @@ -8238,73 +8280,6 @@ _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f "$lt_ac_sed" && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test 10 -lt "$lt_ac_count" && break - lt_ac_count=`expr $lt_ac_count + 1` - if test "$lt_ac_count" -gt "$lt_ac_max"; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) @@ -8351,7 +8326,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) @@ -8364,7 +8339,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd, ;; *-*-cygwin* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) @@ -8390,9 +8365,9 @@ AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in - *-*-mingw* ) + *-*-mingw* | *-*-windows* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4 index 94b082976..25caa8902 100644 --- a/m4/ltoptions.m4 +++ b/m4/ltoptions.m4 @@ -1,14 +1,14 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2024 Free +# Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 8 ltoptions.m4 +# serial 10 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) @@ -128,7 +128,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) +*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) @@ -323,29 +323,39 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- -# implement the --with-aix-soname flag, and support the `aix-soname=aix' -# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT -# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +# implement the --enable-aix-soname configure option, and support the +# `aix-soname=aix' and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. +# DEFAULT is either `aix', `both', or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) - AC_ARG_WITH([aix-soname], - [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + AC_ARG_ENABLE([aix-soname], + [AS_HELP_STRING([--enable-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], - [case $withval in - aix|svr4|both) - ;; - *) - AC_MSG_ERROR([Unknown argument to --with-aix-soname]) - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname], - [AC_CACHE_VAL([lt_cv_with_aix_soname], - [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) - with_aix_soname=$lt_cv_with_aix_soname]) + [case $enableval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --enable-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$enable_aix_soname], + [_AC_ENABLE_IF([with], [aix-soname], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)]) + enable_aix_soname=$lt_cv_with_aix_soname]) + with_aix_soname=$enable_aix_soname AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member @@ -376,30 +386,50 @@ LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) # _LT_WITH_PIC([MODE]) # -------------------- -# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# implement the --enable-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], +[AC_ARG_ENABLE([pic], + [AS_HELP_STRING([--enable-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [pic_mode=m4_default([$1], [default])]) + case $enableval in + yes|no) pic_mode=$enableval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [dnl Continue to support --with-pic and --without-pic, for backward + dnl compatibility. + _AC_ENABLE_IF([with], [pic], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])])] + ) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC diff --git a/m4/ltversion.m4 b/m4/ltversion.m4 index fa04b52a3..149c9719f 100644 --- a/m4/ltversion.m4 +++ b/m4/ltversion.m4 @@ -1,6 +1,7 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2019, 2021-2024 Free Software Foundation, +# Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +10,15 @@ # @configure_input@ -# serial 4179 ltversion.m4 +# serial 4392 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) +m4_define([LT_PACKAGE_VERSION], [2.5.3]) +m4_define([LT_PACKAGE_REVISION], [2.5.3]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' +[macro_version='2.5.3' +macro_revision='2.5.3' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) From 903ba84ff9db736109d025159ee368c6e47ddb99 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Sun, 29 Sep 2024 18:26:16 +0000 Subject: [PATCH 47/51] assorted updates configure.ac: * drop COB_LI_IS_LL in favor of existing COB_32_BIT_LONG * (cjson=local): use CJSON_CFLAGS and CJSON_LIBS also for this case, fix include not to use quotes cobc: * cobc.c (cobc_print_info): drop COB_LI_IS_LL in favor of existing COB_32_BIT_LONG * typeck.c (cb_tree_list_has_numeric_ref_or_field): cleanup * typeck.c (cb_emit_accept): always check position * cobc.c, flag.def: make scope optional for -fdump libcob: * fileio.c (cob_fd_file_open) [_WIN32]: workaround for MinGW bug in locking * common.h, common.c (cob_cleanup_thread): fix declaration * common.c: drop includes found in coblocal.h * common.c (cob_alloc_module): changed type and name of cob_mod_ptr * common.h, coblocal.h: added pragma once for better supporting clangd in single-file mode * intrinsic.c: speedup for NUMVAL related functions --- ChangeLog | 12 ++++++--- Makefile.am | 4 +-- build_windows/config.h.in | 4 --- cobc/ChangeLog | 11 +++++++++ cobc/cobc.c | 6 ++--- cobc/flag.def | 5 ++-- cobc/typeck.c | 16 +++++++----- configure.ac | 18 +++++--------- libcob/ChangeLog | 44 ++++++++++++++++++++++++--------- libcob/coblocal.h | 4 ++- libcob/common.c | 20 +++++++-------- libcob/common.h | 6 +++-- libcob/fileio.c | 30 ++++++++++++++-------- libcob/intrinsic.c | 30 ++++++++++++---------- libcob/numeric.c | 20 +++++++-------- libcob/screenio.c | 10 ++++---- tests/testsuite.src/syn_misc.at | 2 +- 17 files changed, 145 insertions(+), 97 deletions(-) diff --git a/ChangeLog b/ChangeLog index 21d93b899..ab1e792a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,20 @@ +2024-09-29 Simon Sobisch + + * configure.ac: drop COB_LI_IS_LL in favor of existing COB_32_BIT_LONG + * configure.ac (cjson=local): use CJSON_CFLAGS and CJSON_LIBS also for + this case, fix include not to use quotes + 2024-09-27 Simon Sobisch - * build_aux/ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: - update libtool from 2.46 to 2.53, dropping all manual patches - * configure.ac: require autoconf 2.70 and drop check for lex-library with + * configure.ac: require autoconf 2.70 and drop check for lex-library with noyywrap option for AC_PROG_LEX * HACKING: document dependencies autoconf 2.70 and automake 1.16 and several smaller text updates * Makefile.am (checkmanual-code-coverage, checkall-code-coverage): new targets removing the need to do that manually + * build_aux/ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: + update libtool from 2.46 to 2.53, dropping all manual patches * DEPENDENCIES: added perl for running NIST85 2024-09-09 Simon Sobisch diff --git a/Makefile.am b/Makefile.am index d92eb165b..266d6f889 100644 --- a/Makefile.am +++ b/Makefile.am @@ -166,9 +166,9 @@ vcs-update: distbin distbin-gzip distbin-bzip2 distbin-lzip distbin-xz test: all - cd tests && $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) test + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C tests test checkmanual: all - cd tests && $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) checkmanual + $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C tests checkmanual checkall: check test diff --git a/build_windows/config.h.in b/build_windows/config.h.in index e294ff951..d7294dc64 100644 --- a/build_windows/config.h.in +++ b/build_windows/config.h.in @@ -306,10 +306,6 @@ #define COB_LIBS "libcob.l" #endif - -/* long int is long long */ -/* #undef COB_LI_IS_LL */ - /* Module extension */ #define COB_MODULE_EXT "dll" diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 0bcd3a6db..758de798d 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,8 +1,14 @@ +2024-09-29 Simon Sobisch + + * cobc.c (cobc_print_info): drop COB_LI_IS_LL + in favor of existing COB_32_BIT_LONG + 2024-09-27 Simon Sobisch * plex.l, scanner.l: use noyywrap option instead of manually defining related code parts + * typeck.c (cb_tree_list_has_numeric_ref_or_field): cleanup 2024-09-25 Nicolas Berthier @@ -13,6 +19,11 @@ * typeck.c (cb_emit_move, cb_emit_set_to): do not check for incompatible data if no receiver field is of category numeric or numeric edited +2024-09-03 Simon Sobisch + + * typeck.c (cb_emit_accept): always check position + * cobc.c, flag.def: make scope optional for -fdump + 2024-08-28 David Declerck * tree.c (char_to_precedence_idx, get_char_type_description, valid_char_order): diff --git a/cobc/cobc.c b/cobc/cobc.c index f44c62f75..1ab3214bc 100644 --- a/cobc/cobc.c +++ b/cobc/cobc.c @@ -2704,7 +2704,7 @@ cobc_print_info (void) cobc_var_print ("64bit-mode", _("no"), 0); #endif -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG cobc_var_print ("BINARY-C-LONG", _("8 bytes"), 0); #else cobc_var_print ("BINARY-C-LONG", _("4 bytes"), 0); @@ -2797,7 +2797,7 @@ cobc_def_dump_opts (const char *opt, const int on) int dump_to_set; cb_old_trace = 0; /* Use new methods */ - if (!cb_strcasecmp (opt, "ALL")) { + if (!opt || !cb_strcasecmp (opt, "ALL")) { if (on) { cb_flag_dump = COB_DUMP_ALL; } else { @@ -3287,7 +3287,7 @@ process_command_line (const int argc, char **argv) break; case CB_FLAG_GETOPT_DUMP: - /* -fdump= : Add sections for dump code generation */ + /* -fdump[=] : Add sections for dump code generation */ cobc_def_dump_opts (cob_optarg, 1); break; diff --git a/cobc/flag.def b/cobc/flag.def index ad6f720c5..96c8765ab 100644 --- a/cobc/flag.def +++ b/cobc/flag.def @@ -82,9 +82,10 @@ CB_FLAG_NQ (0, "ec", CB_FLAG_GETOPT_EC, CB_FLAG_NQ (0, "no-ec", CB_FLAG_GETOPT_NO_EC, " -fno-ec=\tdisable code generation for ") -CB_FLAG_NQ (1, "dump", CB_FLAG_GETOPT_DUMP, +CB_FLAG_OP (1, "dump", CB_FLAG_GETOPT_DUMP, _(" -fdump= dump data fields on abort, may be\n" - " a combination of: ALL, WS, LS, RD, FD, SC, LO")) + " a combination of: ALL, WS, LS, RD, FD, SC, LO\n" + " default if no scope specified: ALL")) CB_FLAG_OP (0, "no-dump", CB_FLAG_GETOPT_NO_DUMP, _(" -fno-dump= exclude data fields from dumping on abort, may\n" " be a combination of: ALL, WS, LS, RD, FD, SC, LO\n" diff --git a/cobc/typeck.c b/cobc/typeck.c index 391ebaba5..3f87068dd 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -1056,7 +1056,8 @@ cb_emit_list (cb_tree l) } static COB_INLINE COB_A_INLINE int -cb_tree_is_numeric_ref_or_field (cb_tree x, int include_numeric_edited) { +cb_tree_is_numeric_ref_or_field (cb_tree x, int include_numeric_edited) +{ int cat; if (!x || !CB_REF_OR_FIELD_P (x)) { return 0; @@ -1067,8 +1068,9 @@ cb_tree_is_numeric_ref_or_field (cb_tree x, int include_numeric_edited) { } static int -cb_tree_list_has_numeric_ref_or_field (cb_tree l) { - for (l; +cb_tree_list_has_numeric_ref_or_field (cb_tree l) +{ + for (; l && !cb_tree_is_numeric_ref_or_field (CB_VALUE (l), 1); l = CB_CHAIN (l)); return (l != NULL); @@ -3939,6 +3941,7 @@ validate_alphabet (cb_tree alphabet) ap->high_val_char = maxchar; alphabet_valid = 1; + n = 0; /* keep analyzer happy */ for (l = ap->custom_list; l; l = CB_CHAIN (l)) { x = CB_VALUE (l); @@ -8258,7 +8261,9 @@ cb_emit_accept (cb_tree var, cb_tree pos, struct cb_attr_struct *attr_ptr) if (cb_listing_xref) { cobc_xref_set_receiving (var); } - + if (cb_validate_one (pos)) { + return; + } if (attr_ptr) { fgc = attr_ptr->fgc; bgc = attr_ptr->bgc; @@ -8270,8 +8275,7 @@ cb_emit_accept (cb_tree var, cb_tree pos, struct cb_attr_struct *attr_ptr) cursor = attr_ptr->cursor; color = attr_ptr->color; disp_attrs = attr_ptr->dispattrs; - if (cb_validate_one (pos) - || cb_validate_one (fgc) + if (cb_validate_one (fgc) || cb_validate_one (bgc) || cb_validate_one (scroll) || cb_validate_one (timeout) diff --git a/configure.ac b/configure.ac index d17fe1540..b7a516ab0 100644 --- a/configure.ac +++ b/configure.ac @@ -174,7 +174,6 @@ AH_TEMPLATE([COB_EXE_EXT], [Executable extension]) AH_TEMPLATE([COB_KEYWORD_INLINE], [Keyword for inline]) AH_TEMPLATE([COB_NO_SELFOPEN], [Can not dlopen self]) AH_TEMPLATE([COB_COMPUTED_GOTO], [Compilation of computed gotos works]) -AH_TEMPLATE([COB_LI_IS_LL], [long int is long long]) AH_TEMPLATE([COB_32_BIT_LONG], [long int is 32 bits]) AH_TEMPLATE([COB_64_BIT_POINTER], [Pointers are longer than 32 bits]) AH_TEMPLATE([WITH_CURSES], [curses library for extended SCREEN I/O]) @@ -999,7 +998,7 @@ AS_IF([test "$with_xml2" = yes -o "$with_xml2" = check], [ XML2_LIBS="-lxml2" fi LIBS="$LIBS $LIBCOB_LIBS_extern $XML2_LIBS" - # note: PKG_CONFIG and xml2-config set -I /path/to/libxml2 which contains a "libxml" folder where + # note: PKG_CONFIG and xml2-config set -I/path/to/libxml2 which contains a "libxml" folder where # all the files we look for are included for header in xmlwriter xmlversion uri parser tree; do AC_CHECK_HEADER([libxml/$header.h], [], @@ -1080,8 +1079,8 @@ AS_IF([test "$USE_JSON" = "cjson" -o "$USE_JSON" = "local" -o "$USE_JSON" = chec with_cjson_local=no AS_IF([test -e ./libcob/cJSON.c], [AC_MSG_CHECKING([whether linking of ./libcob/cJSON.c works]) - CPPFLAGS="$curr_cppflags -I./libcob" - LIBS="$LIBS $LIBCOB_LIBS_extern" + CPPFLAGS="$curr_cppflags -I./libcob $CJSON_CFLAGS" + LIBS="$LIBS $LIBCOB_LIBS_extern $CJSON_LIBS" AC_LINK_IFELSE([ AC_LANG_PROGRAM([[#include "cJSON.c"]], [[#if (CJSON_VERSION_MAJOR * 100 + CJSON_VERSION_MINOR) < 103 @@ -1098,8 +1097,8 @@ AS_IF([test "$USE_JSON" = "cjson" -o "$USE_JSON" = "local" -o "$USE_JSON" = chec if test "$with_cjson_local" = no; then AS_IF([test -e "$srcdir/libcob/cJSON.c"], [AC_MSG_CHECKING([whether linking of "$srcdir/libcob/cJSON.c" works]) - CPPFLAGS="$curr_cppflags -I\"$srcdir/libcob\"" - LIBS="$LIBS $LIBCOB_LIBS_extern" + CPPFLAGS="$curr_cppflags -I$srcdir/libcob $CJSON_CFLAGS" + LIBS="$LIBS $LIBCOB_LIBS_extern $CJSON_LIBS" AC_LINK_IFELSE([ AC_LANG_PROGRAM([[#include "cJSON.c"]], [[#if (CJSON_VERSION_MAJOR * 100 + CJSON_VERSION_MINOR) < 103 @@ -1108,7 +1107,7 @@ AS_IF([test "$USE_JSON" = "cjson" -o "$USE_JSON" = "local" -o "$USE_JSON" = chec cJSON_CreateNull ();]])], [AC_MSG_RESULT([yes]) AC_DEFINE([WITH_CJSON], [1]) - with_cjson_local="yes (in \"$srcdir/libcob\")"], + with_cjson_local="yes (in $srcdir/libcob)"], [AC_MSG_RESULT([no])] ) LIBS="$curr_libs"] @@ -1933,11 +1932,6 @@ AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(void *) -AC_MSG_CHECKING([whether size of long int = size of long long]) -AS_IF([test "$ac_cv_sizeof_long_int" = "$ac_cv_sizeof_long_long"], - [AC_DEFINE([COB_LI_IS_LL], [1]) AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no])]) - AC_MSG_CHECKING([whether long is 32 bits]) AS_IF([test "$ac_cv_sizeof_long" = 4], [AC_DEFINE([COB_32_BIT_LONG], [1]) AC_MSG_RESULT([yes])], diff --git a/libcob/ChangeLog b/libcob/ChangeLog index 26dadfe99..9056a9101 100644 --- a/libcob/ChangeLog +++ b/libcob/ChangeLog @@ -1,4 +1,9 @@ +2024-09-29 Simon Sobisch + + * numeric.c, common.c (print_info_detailed): drop COB_LI_IS_LL + in favor of existing COB_32_BIT_LONG + 2024-07-27 Chuck Haatvedt * screenio.c: In preparation for Multiple Window support @@ -31,6 +36,20 @@ * screenio.c (cob_settings_screenio): implemented runtime config to hide the cursor +2024-08-11 Simon Sobisch + + * fileio.c (cob_fd_file_open) [_WIN32]: workaround for MinGW bug in locking + +2024-08-09 Simon Sobisch + + * common.h, common.c (cob_cleanup_thread): fix declaration + * common.c: drop includes found in coblocal.h + * common.c (cob_alloc_module): changed type and name of cob_mod_ptr + +2024-08-06 Simon Sobisch + + * intrinsic.c: speedup for NUMVAL related functions + 2024-07-29 Chuck Haatvedt * move.c (optimized_move_display_to_edited): fixed small bug @@ -84,10 +103,10 @@ 2024-05-30 Chuck Haatvedt - fix errors caught by the Sanitizer functionality of GCC. This - change did not resolve all of the issues found as some of them - were in Berkeley DB and some were intentional in the memory - corruption logic which has been implemented in the runtime. + fix errors caught by the Sanitizer functionality of GCC. This + change did not resolve all of the issues found as some of them + were in Berkeley DB and some were intentional in the memory + corruption logic which has been implemented in the runtime. * move.c (the cob_move_display_to_packed function was rewritten to fix the out of bounds memory addressing issues and also to make @@ -97,8 +116,8 @@ 2024-05-30 Chuck Haatvedt - fix errors in filio.c when building with VISAM 2.2. This issue - occurred when using a partial key with a sequential read previous. + fix errors in filio.c when building with VISAM 2.2. This issue + occurred when using a partial key with a sequential read previous. * fileio.c (indexed_start_internal), (indexed_start) and (indexed_read_next): added a new field, partial_key_length, @@ -129,7 +148,7 @@ 2024-07-19 Simon Sobisch - * coblocal.h (COB_TLS): add a new attribute for thread local static. + * coblocal.h (COB_TLS): add a new attribute for thread local static * common.h, common.c (cob_cleanup_thread): add a cleanup function for threads 2024-05-15 Simon Sobisch @@ -167,8 +186,9 @@ * fileio.c (cob_path_to_absolute): extracted from insert and cob_set_main_argv0 -2024-03-10 Alfredo Tupone +2024-01-31 Gwyn Ciesla + Bug #941 build issue * common.c: add missing include libxml/parser.h 2024-02-26 Boris Eng @@ -776,7 +796,7 @@ after suggestions by Chuck Haatvedt * termio.c (pretty_display_numeric): fix GCC warning with {{ 0 }} * termio.c (display_alnum_dump): slightly rewritten to fix compiler warnings - * cconv.c (cob_load_collation), common.c, intrinisic.c (cob_intr_random), + * cconv.c (cob_load_collation), common.c, intrinsic.c (cob_intr_random), termio.c: minor adjustments to fix compiler warnings * fileio.c (copy_fcd_to_file): fixed memory issues with writing to assign and select name @@ -836,7 +856,7 @@ after suggestions by Chuck Haatvedt * common.c (cob_move_packed_to_display, cob_packed_get_int, cob_packed_get_long_long): minor performance improvements and similar code to numeric.c - * intrinisic.c (calculate_start_end_for_numval): only skip leading spaces + * intrinsic.c (calculate_start_end_for_numval): only skip leading spaces and zeros, but not leading low-values 2023-01-25 Simon Sobisch @@ -1136,8 +1156,8 @@ after suggestions by Chuck Haatvedt 2022-10-17 Simon Sobisch * common.c (cob_debug_open, cob_trace_print), intrinsic.c - (cob_intr_hex_to_char): prefer extending switch over use of topupper - * call.c, common.c, intrinisic.c, screenio.c: directly call toupper/tolower + (cob_intr_hex_to_char): prefer extending switch over use of topupper + * call.c, common.c, intrinsic.c, screenio.c: directly call toupper/tolower without previous check of islower/isupper * system.def, common.c (cob_sys_runtime_error_proc): implement CBL_RUNTIME_ERROR diff --git a/libcob/coblocal.h b/libcob/coblocal.h index 5fa04d7f9..11eaf23fd 100644 --- a/libcob/coblocal.h +++ b/libcob/coblocal.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2007-2012, 2014-2023 Free Software Foundation, Inc. + Copyright (C) 2007-2012, 2014-2024 Free Software Foundation, Inc. Written by Roger While, Simon Sobisch, Ron Norman This file is part of GnuCOBOL. @@ -22,6 +22,8 @@ #ifndef COB_LOCAL_H #define COB_LOCAL_H +#pragma once + /* We use this file to define/prototype things that should not be exported to user space */ diff --git a/libcob/common.c b/libcob/common.c index 7ecf0c926..c6a83ac25 100644 --- a/libcob/common.c +++ b/libcob/common.c @@ -29,14 +29,10 @@ #endif #endif -#include #include #include #include #include -#ifdef HAVE_STRINGS_H -#include -#endif #include #include #include @@ -277,7 +273,7 @@ const int MAX_MODULE_ITERS = 10240; struct cob_alloc_module { struct cob_alloc_module *next; /* Pointer to next */ - void *cob_pointer; /* Pointer to malloced space */ + cob_module *cob_mod_ptr; /* Pointer to malloced module space */ }; /* EXTERNAL structure */ @@ -785,7 +781,7 @@ cob_exit_common_modules (void) - currently used for: decimals - and remove it from the internal module list */ for (ptr = cob_module_list; ptr; ptr = nxt) { - mod = ptr->cob_pointer; + mod = ptr->cob_mod_ptr; nxt = ptr->next; if (mod && mod->module_cancel.funcint) { mod->module_active = 0; @@ -3247,7 +3243,7 @@ cob_module_global_enter (cob_module **module, cob_global **mglobal, *module = cob_cache_malloc (sizeof (cob_module)); /* Add to list of all modules activated */ mod_ptr = cob_malloc (sizeof (struct cob_alloc_module)); - mod_ptr->cob_pointer = *module; + mod_ptr->cob_mod_ptr = *module; mod_ptr->next = cob_module_list; cob_module_list = mod_ptr; #if 0 /* cob_call_name_hash and cob_call_from_c are rw-branch only features @@ -3329,7 +3325,7 @@ cob_module_free (cob_module **module) prv = NULL; /* Remove from list of all modules activated */ for (ptr = cob_module_list; ptr; ptr = ptr->next) { - if (ptr->cob_pointer == *module) { + if (ptr->cob_mod_ptr == *module) { if (prv == NULL) { cob_module_list = ptr->next; } else { @@ -3341,7 +3337,8 @@ cob_module_free (cob_module **module) prv = ptr; } -#if 0 /* cob_module->param_buf and cob_module->param_field are rw-branch only features +#if 0 /* cob_module->param_buf and cob_module->param_field are + trunk (previously rw-branch) only features for now - TODO: activate on merge of r1547 */ && !cobglobptr->cob_call_from_c if ((*module)->param_buf != NULL) @@ -9769,7 +9766,7 @@ print_info_detailed (const int verbose) var_print ("64bit-mode", _("no"), "", 0); #endif -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG var_print ("BINARY-C-LONG", _("8 bytes"), "", 0); #else var_print ("BINARY-C-LONG", _("4 bytes"), "", 0); @@ -11221,7 +11218,8 @@ init_statement_list (void) } #endif -void cob_cleanup_thread () +void +cob_cleanup_thread (void) { cob_exit_strings (); } diff --git a/libcob/common.h b/libcob/common.h index cbdbadff6..c268eed79 100644 --- a/libcob/common.h +++ b/libcob/common.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2012, 2014-2023 Free Software Foundation, Inc. + Copyright (C) 2002-2012, 2014-2024 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman, Edward Hart @@ -22,6 +22,8 @@ #ifndef COB_COMMON_H #define COB_COMMON_H +#pragma once + #include /* for size_t */ /* Only define cob_decimal if we have the necessary mpz_t from gmp.h/mpir.h @@ -1682,7 +1684,7 @@ COB_EXPIMP void cob_runtime_hint (const char *, ...) COB_A_FORMAT12; COB_EXPIMP void cob_runtime_error (const char *, ...) COB_A_FORMAT12; COB_EXPIMP void cob_runtime_warning (const char *, ...) COB_A_FORMAT12; -COB_EXPIMP void cob_cleanup_thread (); +COB_EXPIMP void cob_cleanup_thread (void); /* General functions */ diff --git a/libcob/fileio.c b/libcob/fileio.c index e3d8a51b0..f5bbc61cf 100644 --- a/libcob/fileio.c +++ b/libcob/fileio.c @@ -1824,12 +1824,17 @@ cob_fd_file_open (cob_file *f, char *filename, HANDLE osHandle = (HANDLE)_get_osfhandle (fd); if (osHandle != INVALID_HANDLE_VALUE) { DWORD flags = LOCKFILE_FAIL_IMMEDIATELY; - OVERLAPPED fromStart = {0}; + OVERLAPPED fromStart = { 0 }; if (mode != COB_OPEN_INPUT) flags |= LOCKFILE_EXCLUSIVE_LOCK; if (!LockFileEx (osHandle, flags, 0, MAXDWORD, MAXDWORD, &fromStart)) { - f->open_mode = COB_OPEN_CLOSED; - close (fd); - return COB_STATUS_61_FILE_SHARING; + DWORD err = GetLastError (); + /* normally that return value would not happen, we use it to + work around call errors happening on MSYS */ + if (err != ERROR_INVALID_FUNCTION) { + f->open_mode = COB_OPEN_CLOSED; + close (fd); + return COB_STATUS_61_FILE_SHARING; + } } } } @@ -2087,10 +2092,15 @@ cob_file_open (cob_file *f, char *filename, OVERLAPPED fromStart = {0}; if (mode != COB_OPEN_INPUT) flags |= LOCKFILE_EXCLUSIVE_LOCK; if (!LockFileEx (osHandle, flags, 0, MAXDWORD, MAXDWORD, &fromStart)) { - f->open_mode = COB_OPEN_CLOSED; - f->fd = -1; - fclose (fp); - return COB_STATUS_61_FILE_SHARING; + DWORD err = GetLastError (); + /* normally that return value would not happen, we use it to + work around call errors happening on MSYS */ + if (err != ERROR_INVALID_FUNCTION) { + f->open_mode = COB_OPEN_CLOSED; + fclose (fp); + f->fd = -1; + return COB_STATUS_61_FILE_SHARING; + } } } } @@ -7074,7 +7084,7 @@ cob_savekey (cob_file *f, int idx, unsigned char *data) /* System routines */ /* stores the field's rtrimmed string content into a fresh allocated - string, which later needs to be passed to cob_free */ + string, which later needs to be passed to cob_free */ static void * cob_str_from_fld (const cob_field *f) { @@ -7104,7 +7114,7 @@ cob_str_from_fld (const cob_field *f) } while (data <= end) { -#if 0 /* Quotes in file */ +#if 0 /* Quotes in file, per MF, stopping at first space outside */ if (*data == '"') { quote_switch = !quote_switch; data++; diff --git a/libcob/intrinsic.c b/libcob/intrinsic.c index 785fa3b1b..727f7f6f6 100644 --- a/libcob/intrinsic.c +++ b/libcob/intrinsic.c @@ -716,6 +716,7 @@ int cob_check_numval_f (const cob_field *srcfield) { unsigned char *p = srcfield->data; + const unsigned int fsize = (unsigned int)srcfield->size; size_t plus_minus; size_t digits; size_t decimal_seen; @@ -724,10 +725,10 @@ cob_check_numval_f (const cob_field *srcfield) size_t break_needed; size_t exponent; size_t e_plus_minus; - int n; + unsigned int n; const unsigned char dec_pt = COB_MODULE_PTR->decimal_point; - if (!srcfield->size) { + if (!fsize) { return 1; } @@ -743,7 +744,7 @@ cob_check_numval_f (const cob_field *srcfield) e_plus_minus = 0; /* Check leading positions */ - for (n = 0; n < (int)srcfield->size; ++n, ++p) { + for (n = 0; n < fsize; ++n, ++p) { switch (*p) { case '0': case '1': @@ -781,11 +782,11 @@ cob_check_numval_f (const cob_field *srcfield) } } - if (n == (int)srcfield->size) { + if (n == fsize) { return n + 1; } - for (; n < (int)srcfield->size; ++n, ++p) { + for (; n < fsize; ++n, ++p) { switch (*p) { case '0': case '1': @@ -1445,7 +1446,7 @@ calculate_start_end_for_numval (cob_field *srcfield, unsigned char **pp, unsigned char **pp_end) { unsigned char *p = srcfield->data; - unsigned char *p_end; + register unsigned char *p_end; if (srcfield->size == 0 || p == NULL) { @@ -1479,7 +1480,7 @@ enum numval_type { static cob_field * numval (cob_field *srcfield, cob_field *currency, const enum numval_type type) { - unsigned char *final_buff = NULL; + unsigned char final_buff [COB_MAX_DIGITS + 1] = { 0 }; unsigned char *p, *p_end; unsigned char *currency_data = NULL; size_t datasize; @@ -1511,14 +1512,19 @@ numval (cob_field *srcfield, cob_field *currency, const enum numval_type type) cob_alloc_set_field_uint (0); return curr_field; } - /* not wasting buffer space (COBOL2022: 35/34 max)... */ + /* not wasting buffer space (COBOL2023: 35/34 max)... */ if (datasize > COB_MAX_DIGITS) { +#ifdef INVALID_NUMVAL_IS_ZERO + cob_set_exception (COB_EC_ARGUMENT_FUNCTION); + cob_alloc_set_field_uint (0); + return curr_field; +#else + /* Should this truncate or raise an exception? + What about COBOL2025 new max? */ datasize = COB_MAX_DIGITS; +#endif } - /* acquire temp buffer long enugh */ - final_buff = cob_malloc (datasize + 1U); - sign = 0; digits = 0; decimal_digits = 0; @@ -1648,8 +1654,6 @@ numval (cob_field *srcfield, cob_field *currency, const enum numval_type type) } } - cob_free (final_buff); - if (exception) { cob_set_exception (COB_EC_ARGUMENT_FUNCTION); } diff --git a/libcob/numeric.c b/libcob/numeric.c index fe1425429..36b868a3a 100644 --- a/libcob/numeric.c +++ b/libcob/numeric.c @@ -372,7 +372,7 @@ cob_decimal_clear (cob_decimal *d) void cob_decimal_set_ullint (cob_decimal *d, const cob_u64_t n) { -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG mpz_set_ui (d->value, (cob_uli_t)n); #else mpz_set_ui (d->value, (cob_uli_t)(n >> 32)); @@ -386,7 +386,7 @@ cob_decimal_set_ullint (cob_decimal *d, const cob_u64_t n) void cob_decimal_set_llint (cob_decimal *d, const cob_s64_t n) { -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG mpz_set_si (d->value, (cob_sli_t)n); #else cob_u64_t uval; @@ -455,7 +455,7 @@ cob_decimal_print (cob_decimal *d, FILE *fp) } #define MAX_LLI_DIGITS_PLUS_1 20 -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG #define MAX_LI_DIGITS_PLUS_1 20 #else #define MAX_LI_DIGITS_PLUS_1 10 @@ -497,7 +497,7 @@ const cob_uli_t cob_pow_10_uli_val[MAX_LI_DIGITS_PLUS_1] = { , 10000000 , 100000000 , 1000000000UL -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG , 10000000000 , 100000000000 , 1000000000000 @@ -701,7 +701,7 @@ cob_decimal_set_ieee64dec (cob_decimal *d, const cob_field *f) d->scale = 0; return; } -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG mpz_set_ui (d->value, data); #else mpz_set_ui (d->value, (cob_uli_t)(data >> 32)); @@ -810,7 +810,7 @@ cob_decimal_set_ieee128dec (cob_decimal *d, const cob_field *f) d->scale = 0; return; } -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG mpz_set_ui (d->value, COB_128_MSW(data)); mpz_mul_2exp (d->value, d->value, 64UL); mpz_add_ui (d->value, d->value, COB_128_LSW(data)); @@ -1187,7 +1187,7 @@ cob_decimal_set_packed (cob_decimal *d, cob_field *f) val = val * 10 + (*p >> 4); } -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG mpz_set_ui (d->value, (cob_uli_t)val); #else cob_decimal_set_ullint (d, val); @@ -1676,7 +1676,7 @@ cob_decimal_set_binary (cob_decimal *d, cob_field *f) } #endif -#elif defined(COB_LI_IS_LL) +#ifndef COB_32_BIT_LONG if (COB_FIELD_HAVE_SIGN (f)) { mpz_set_si (d->value, cob_binary_get_sint64 (f)); } else { @@ -1779,7 +1779,7 @@ cob_decimal_get_binary (cob_decimal *d, cob_field *f, const int opt) } } } -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG if (!field_sign || (overflow && !(opt & COB_STORE_TRUNC_ON_OVERFLOW))) { cob_binary_set_uint64 (f, mpz_get_ui (d->value)); } else { @@ -3707,7 +3707,7 @@ cob_cmp_llint (cob_field *f1, const cob_s64_t n) } else { if (n >= 0) return -1; } -#ifdef COB_LI_IS_LL +#ifndef COB_32_BIT_LONG mpz_set_si (cob_d2.value, (cob_sli_t)n); #else { diff --git a/libcob/screenio.c b/libcob/screenio.c index 862509f74..e0512cc19 100644 --- a/libcob/screenio.c +++ b/libcob/screenio.c @@ -843,7 +843,7 @@ adjust_attr_from_control_field (cob_flags_t *attr, cob_field *control, continue; } - /* normal attribute - apply and go on*/ + /* normal attribute - apply and go on */ if (control_attr->cobflag != 0) { if (no_indicator == 0) { *attr |= control_attr->cobflag; @@ -3300,10 +3300,10 @@ field_display (cob_field *f, cob_flags_t fattr, const int line, const int column cob_field *fgc, cob_field *bgc, cob_field *fscroll, cob_field *size_is, cob_field *control, cob_field *color) { - int sline; - int scolumn; - int size_display, fsize; - int status; + int sline; + int scolumn; + int size_display, fsize; + int status; char fig_const; /* figurative constant character */ /* LCOV_EXCL_START */ diff --git a/tests/testsuite.src/syn_misc.at b/tests/testsuite.src/syn_misc.at index 6a4107e7d..06e8f75c0 100644 --- a/tests/testsuite.src/syn_misc.at +++ b/tests/testsuite.src/syn_misc.at @@ -7559,7 +7559,7 @@ AT_DATA([prog.cob], [ AT_CAPTURE_FILE([prog.c]) AT_CHECK([COBC_GEN_DUMP_COMMENTS=1 \ - $COMPILE -C -fdump=all -w prog.cob], [0], []) + $COMPILE -C -fdump -w prog.cob], [0], []) # TODO: only execute this piece when extended $GREP works AT_CHECK([($GREP -A 200 "P_dump:" prog.c | $GREP -B 200 "END OF DUMP") || exit 77], [0], [ P_dump: From a3e00bed1f21ce0f66315039be08c629574c9184 Mon Sep 17 00:00:00 2001 From: sf-mensch Date: Sun, 29 Sep 2024 19:12:59 +0000 Subject: [PATCH 48/51] fix bad line in [r5343] --- libcob/numeric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcob/numeric.c b/libcob/numeric.c index 36b868a3a..bd76526bc 100644 --- a/libcob/numeric.c +++ b/libcob/numeric.c @@ -1676,7 +1676,7 @@ cob_decimal_set_binary (cob_decimal *d, cob_field *f) } #endif -#ifndef COB_32_BIT_LONG +#elif !defined (COB_32_BIT_LONG) if (COB_FIELD_HAVE_SIGN (f)) { mpz_set_si (d->value, cob_binary_get_sint64 (f)); } else { From 49da19a3dfc05fa7beaed1ac9c1d08a16ee7dd61 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Mon, 30 Sep 2024 07:38:18 +0000 Subject: [PATCH 49/51] Add dependencies options and -fcopybook-deps cobc: * pplex.l (cb_text_list): prevent duplicates * cobc.c, help.c, pplex.l: add new flags to output dependencies following gcc: -M to output deps only, -MD to output deps while compiling (in .d files), -MP to output phony targets, -MG to keep missing copybooks, -MQ to Makefile-quote target ; add -fcopybook-deps to output only copybook names instead of file paths. -fcopybook-deps also forces -E, -foneline-deps, -MT=copybooks, disables errors on missing copybooks and removes output on stdout doc: * gnucobol.texi: document new dependencies options --- NEWS | 3 + cobc/ChangeLog | 14 ++ cobc/cobc.c | 273 ++++++++++++++++++++++----- cobc/cobc.h | 3 + cobc/flag.def | 2 + cobc/help.c | 8 +- cobc/pplex.l | 47 ++++- doc/ChangeLog | 4 + doc/gnucobol.texi | 39 ++++ tests/testsuite.src/used_binaries.at | 228 +++++++++++++++++++--- 10 files changed, 538 insertions(+), 83 deletions(-) diff --git a/NEWS b/NEWS index 090f6a4ca..c87619496 100644 --- a/NEWS +++ b/NEWS @@ -65,6 +65,9 @@ NEWS - user visible changes -*- outline -*- ** New option -fdefault-file-colseq to specify the default file collating sequence +** New options -M, -MP, -MG, -MD and -MQ to output COPY dependencies + to a file (see "Dependencies options" in the GnuCOBOL manual) + * More notable changes ** execution times were significantly reduced for the following: diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 758de798d..05399a1d6 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -24,6 +24,10 @@ * typeck.c (cb_emit_accept): always check position * cobc.c, flag.def: make scope optional for -fdump +2024-09-23 David Declerck + + * pplex.l (cb_text_list): prevent duplicates + 2024-08-28 David Declerck * tree.c (char_to_precedence_idx, get_char_type_description, valid_char_order): @@ -139,6 +143,16 @@ * codegen.c: handle profiling code generation under the cb_flag_prof guard +2024-03-15 Fabrice Le Fessant + + * cobc.c, help.c, pplex.l: add new flags to output dependencies following + gcc: -M to output deps only, -MD to output deps while compiling (in + .d files), -MP to output phony targets, -MG to keep missing copybooks, + -MQ to Makefile-quote target ; add -fcopybook-deps to + output only copybook names instead of file paths. -fcopybook-deps + also forces -E, -foneline-deps, -MT=copybooks, disables errors on + missing copybooks and removes output on stdout + 2024-02-19 Boris Eng * parser.y (screen_value_clause): replaced basic literals by literals diff --git a/cobc/cobc.c b/cobc/cobc.c index 1ab3214bc..915353ed4 100644 --- a/cobc/cobc.c +++ b/cobc/cobc.c @@ -109,7 +109,13 @@ enum compile_level { #define CB_FLAG_GETOPT_MEMORY_CHECK 17 #define CB_FLAG_GETOPT_COPY_FILE 18 #define CB_FLAG_GETOPT_INCLUDE_FILE 19 - +#define CB_FLAG_GETOPT_DEPEND_OUTPUT 20 +#define CB_FLAG_GETOPT_DEPEND_TARGET 21 +#define CB_FLAG_GETOPT_DEPEND_ESCAPE_TARGET 22 +#define CB_FLAG_GETOPT_DEPEND_OUTPUT_FILE 23 +#define CB_FLAG_GETOPT_DEPEND_ADD_PHONY 24 +#define CB_FLAG_GETOPT_DEPEND_KEEP_MISSING 25 +#define CB_FLAG_GETOPT_DEPEND_ON_THE_SIDE 26 /* Info display limits */ #define CB_IMSG_SIZE 24 @@ -249,6 +255,12 @@ FILE *cb_storage_file = NULL; FILE *cb_listing_file = NULL; FILE *cb_depend_file = NULL; const char *cb_ebcdic_table = NULL; +int cb_depend_output = 0; +int cb_depend_output_only = 0; +int cb_depend_add_phony = 0; +int cb_depend_keep_missing = 0; +int cb_depend_target_auto = 0; +int cb_flag_copybook_deps = 0; /* set by option -fttitle= */ char *cb_listing_with_title = NULL; @@ -386,7 +398,9 @@ static char *cobc_libs; /* -l... */ static char *cobc_lib_paths; /* -L... */ static char *cobc_include; /* -I... */ static char *cobc_ldflags; /* -Q / COB_LDFLAGS */ + static char *cb_depend_target; /* -MT <target>... */ +static const char *cb_depend_filename; /* -MF <file> */ static size_t cobc_cflags_size; static size_t cobc_libs_size; @@ -612,8 +626,14 @@ static const struct option long_options[] = { {"j", CB_OP_ARG, NULL, 'j'}, {"Q", CB_RQ_ARG, NULL, 'Q'}, {"A", CB_RQ_ARG, NULL, 'A'}, - {"MT", CB_RQ_ARG, NULL, '!'}, - {"MF", CB_RQ_ARG, NULL, '@'}, + {"M", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_OUTPUT }, + {"MT", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_DEPEND_TARGET}, + {"MQ", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_DEPEND_ESCAPE_TARGET}, + {"MF", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_DEPEND_OUTPUT_FILE}, + {"MP", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_ADD_PHONY}, + {"MG", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_KEEP_MISSING}, + {"MD", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_ON_THE_SIDE}, + {"fcopybook-deps", CB_NO_ARG, &cb_flag_copybook_deps, 1}, {"coverage", CB_NO_ARG, &cb_coverage_enabled, 1}, {"P", CB_OP_ARG, NULL, 'P'}, {"Xref", CB_NO_ARG, NULL, 'X'}, @@ -3001,6 +3021,82 @@ remove_trailing_slash (char *data) } } +static COB_INLINE COB_A_INLINE int +string_is_dash (const char *s) +{ + return (strcmp (s, COB_DASH) == 0); +} + +static void +add_depend_target (const char *s) +{ + if (!cb_depend_target) { + cb_depend_target = cobc_strdup (s); + } else { + /* multiple invocations add to the list */ + const size_t orig_len = strlen (cb_depend_target); + const size_t new_len = strlen (s); + const size_t buff_len = orig_len + 1 + new_len + 1; + cb_depend_target = cobc_realloc (cb_depend_target, buff_len); + *(cb_depend_target + orig_len) = ' '; + memcpy (cb_depend_target + orig_len + 1, s, new_len); + *(cb_depend_target + orig_len + 1 + new_len) = '\0'; + } +} + +static void +add_depend_escape_target (const char *s) +{ + int i, nchars = 0; + const int len = strlen (s); + for (i=0; i<len; i++) { + const char c = s[i]; + if (c == '$' || c == '#' || c == '*') { + nchars++; + } + } + if (nchars) { + char *new_s = cobc_malloc (len+nchars+1); + char *cur_s = new_s ; + for (i=0; i<len; i++) { + const char c = s[i]; + if (c == '$') { + *cur_s++ = '$'; + } else if (c == '#' || c == '*'){ + *cur_s++ = '\\'; + } + *cur_s++ = c; + } + *cur_s = 0; + add_depend_target (new_s); + cobc_free (new_s); + } else { + add_depend_target (s); + } +} + +static const char * +file_replace_extension (const char *file, const char *ext) +{ + int i; + const int len = strlen (file); + const int extlen = strlen (ext); + for (i=len; i>0; i--) { + const char c = file[i]; + if (c == '.') { + const int newlen = i+extlen+1; + char *new_file = cobc_malloc(newlen); + memcpy (new_file, file, i); + memcpy (new_file+i, ext, extlen+1); + return new_file; + } + if (c == '/') { + break; + } + } + return cobc_main_stradd_dup (file, ext); +} + /* process command line options */ static int process_command_line (const int argc, char **argv) @@ -3642,28 +3738,29 @@ process_command_line (const int argc, char **argv) cb_define_list = p; break; - case '!': - /* -MT <target> */ - if (!cb_depend_target) { - cb_depend_target = cobc_strdup (cob_optarg); - } else { - /* multiple invocations add to the list */ - const size_t orig_len = strlen (cb_depend_target); - const size_t new_len = strlen (cob_optarg); - const size_t buff_len = orig_len + 1 + new_len + 1; - cb_depend_target = cobc_realloc (cb_depend_target, buff_len); - memset (cb_depend_target + orig_len, ' ', 1); - memcpy (cb_depend_target + orig_len + 1, cob_optarg, new_len); - memset (cb_depend_target + orig_len + 1 + new_len, 0, 1); - } + case CB_FLAG_GETOPT_DEPEND_OUTPUT: /* -M */ + cb_depend_output = 1; + cb_depend_output_only = 1; + cb_compile_level = CB_LEVEL_PREPROCESS; break; - - case '@': - /* -MF <file> */ - cb_depend_file = fopen (cob_optarg, "w"); - if (!cb_depend_file) { - cb_perror (0, "cobc: %s: %s", cob_optarg, cb_get_strerror ()); - } + case CB_FLAG_GETOPT_DEPEND_ON_THE_SIDE: /* -MD */ + cb_depend_output = 1; + cb_depend_target_auto = 1; + break; + case CB_FLAG_GETOPT_DEPEND_ADD_PHONY: /* -MP */ + cb_depend_add_phony = 1; + break; + case CB_FLAG_GETOPT_DEPEND_KEEP_MISSING: /* -MG */ + cb_depend_keep_missing = 1; + break; + case CB_FLAG_GETOPT_DEPEND_TARGET: /* -MT <target> */ + add_depend_target (cob_optarg); + break; + case CB_FLAG_GETOPT_DEPEND_ESCAPE_TARGET: /* -MQ <target> */ + add_depend_escape_target (cob_optarg); + break; + case CB_FLAG_GETOPT_DEPEND_OUTPUT_FILE: /* -MF <file> */ + cb_depend_filename = cobc_strdup(cob_optarg); break; case 'I': @@ -4057,6 +4154,23 @@ process_command_line (const int argc, char **argv) } } + if (cb_flag_copybook_deps) { + /* same as -M, but only COPYBOOK names */ + cb_depend_output = 1; + cb_depend_output_only = 1; + cb_depend_keep_missing = 1; + cb_depend_add_phony = 0; + cb_compile_level = CB_LEVEL_PREPROCESS; + } + if (!cb_depend_output && + (cb_depend_filename || cb_depend_add_phony || cb_depend_target + || cb_depend_keep_missing)) { + cobc_err_exit ("dependency options require -M or -MD"); + } + if (cb_depend_output_only && cb_compile_level != CB_LEVEL_PREPROCESS) { + cobc_err_exit ("-M is compatible only with -E. Use -MD instead."); + } + /* Load reserved words from fixed word-list if specified */ if (cb_reserved_words != NULL) { cb_load_words(); @@ -4111,7 +4225,29 @@ process_command_line (const int argc, char **argv) } #endif - if (output_name && strcmp (output_name, COB_DASH) == 0) { + if (cb_depend_target_auto) { + if (!cb_depend_filename) { + if (output_name) { + cb_depend_filename = + file_replace_extension (output_name, ".d"); + } + } + } + if (cb_depend_output_only) { + if (cb_depend_filename) { + if (output_name) { + cb_depend_output_only = 0; + } + } else { + if (output_name) { + cb_depend_filename = output_name; + output_name = NULL; + } else + cb_depend_filename = cobc_strdup(COB_DASH); + } + } + + if (output_name && string_is_dash (output_name)) { cb_src_list_file = stdout; if (cb_compile_level != CB_LEVEL_PREPROCESS) { cobc_err_exit (_("output to stdout only valid for preprocess")); @@ -4119,18 +4255,16 @@ process_command_line (const int argc, char **argv) cobc_main_free (output_name); cobc_main_free (output_name_buff); } - -#if 0 /* TODO: */ - if (cb_compile_level == CB_LEVEL_PREPROCESS - && output_name && strcmp (output_name, COB_DASH) != 0)) { - cb_depend_file = output_file; - } -#endif - /* TODO: add -M and -MD (breaking change "per GCC" already announced) */ - if (cb_depend_file && !cb_depend_target) { - fclose (cb_depend_file); - cb_depend_file = NULL; - cobc_err_exit (_("-MT must be given to specify target file")); + + if (cb_depend_filename) { + if (string_is_dash(cb_depend_filename)) { + cb_depend_file = stdout; + } else { + cb_depend_file = fopen (cb_depend_filename, "w"); + if (!cb_depend_file) { + cb_perror (0, "cobc: %s: %s", cb_depend_filename, cb_get_strerror ()); + } + } } /* debug: Turn on all exception conditions @@ -4355,7 +4489,7 @@ process_filename (const char *filename) char *full_path; #endif - if (strcmp (filename, COB_DASH) == 0) { + if (string_is_dash (filename)) { if (cobc_seen_stdin == 0) { cobc_seen_stdin = 1; file_is_stdin = 1; @@ -5196,7 +5330,8 @@ preprocess (struct filename *fn) #endif if (output_name - || cb_compile_level > CB_LEVEL_PREPROCESS) { + || cb_compile_level > CB_LEVEL_PREPROCESS + || cb_depend_output_only) { if (cb_unix_lf) { ppout = fopen(fn->preprocess, "wb"); } else { @@ -5300,7 +5435,7 @@ preprocess (struct filename *fn) fflush (stderr); } if (cb_listing_outputfile && verbose_output >= 0) { - if (strcmp (cb_listing_outputfile, COB_DASH) == 0) { + if (string_is_dash (cb_listing_outputfile)) { cb_src_list_file = stdout; } else { if (cb_unix_lf) { @@ -9156,6 +9291,50 @@ process_file (struct filename *fn, int status) cobc_set_listing_header_code (); } + if (cb_depend_output) { + struct cb_text_list *l; + const char *sep = " \\\n"; + FILE *file = NULL; + + if (cb_flag_copybook_deps) { + sep = ""; + } + if (cb_depend_file) { + file = cb_depend_file; + } else { + const char *basename = file_basename (fn->source, NULL); + const char *d_name = file_replace_extension (basename, ".d"); + file = fopen (d_name, "w"); + } + + if (cb_depend_target) { + fprintf (file, "%s:%s", cb_depend_target, sep); + } else { + const char *basename = file_basename (fn->source, NULL); + basename = file_replace_extension (basename, "." COB_OBJECT_EXT); + fprintf (file, "%s:%s", basename, sep); + } + + for (l = cb_depend_list; l; l = l->next) { + fprintf (file, " %s%s", l->text, l->next ? sep : "\n\n"); + } + /* These lines should only be added with -MP */ + if (cb_depend_add_phony) { + for (l = cb_depend_list; l; l = l->next) { + fprintf (file, "%s:\n", l->text); + } + } + if (!cb_depend_file) { + fclose (file); + } + + /* For now, we don't need to free this space as it is + allocated by cobc_plex_malloc() for which no + cobc_plex_free() exists. Everything is freed at the + end. */ + cb_depend_list = NULL; + } + if (cobc_list_file) { putc ('\n', cb_listing_file); } @@ -9319,7 +9498,7 @@ main (int argc, char **argv) memset (cb_listing_header, 0, sizeof (cb_listing_header)); /* If -P=file specified, all lists go to this file */ if (cobc_list_file) { - if (strcmp (cobc_list_file, COB_DASH) == 0) { + if (string_is_dash (cobc_list_file)) { cb_listing_file = stdout; } else if (cb_unix_lf) { @@ -9334,7 +9513,7 @@ main (int argc, char **argv) /* internal complete source listing file */ if (cb_listing_outputfile) { - if (strcmp (cb_listing_outputfile, COB_DASH) == 0) { + if (string_is_dash (cb_listing_outputfile)) { cb_src_list_file = stdout; } else { if (cb_unix_lf) { @@ -9427,15 +9606,7 @@ main (int argc, char **argv) } /* Output dependency list */ - if (cb_depend_file) { - struct cb_text_list *l; - fprintf (cb_depend_file, "%s: \\\n", cb_depend_target); - for (l = cb_depend_list; l; l = l->next) { - fprintf (cb_depend_file, " %s%s\n", l->text, l->next ? " \\" : "\n"); - } - for (l = cb_depend_list; l; l = l->next) { - fprintf (cb_depend_file, "%s:\n", l->text); - } + if (cb_depend_file && cb_depend_file != stdout) { fclose (cb_depend_file); } diff --git a/cobc/cobc.h b/cobc/cobc.h index 822f7381e..2c1bcf2ca 100644 --- a/cobc/cobc.h +++ b/cobc/cobc.h @@ -473,6 +473,9 @@ extern int cb_saveargc; extern FILE *cb_listing_file; extern FILE *cb_src_list_file; extern FILE *cb_depend_file; +extern int cb_depend_output; +extern int cb_depend_keep_missing; +extern int cb_flag_copybook_deps; extern struct cb_text_list *cb_depend_list; extern struct cb_text_list *cb_copy_list; extern struct cb_text_list *cb_include_file_list; diff --git a/cobc/flag.def b/cobc/flag.def index 96c8765ab..d487f3ab4 100644 --- a/cobc/flag.def +++ b/cobc/flag.def @@ -150,6 +150,8 @@ CB_FLAG (cb_flag_stack_extended, 1, "stack-extended", CB_FLAG_ON (cb_flag_fast_compare, 0, "fast-compare", _(" -fno-fast-compare disables inline comparisions")) +/* Normal flags */ + CB_FLAG_ON (cb_flag_remove_unreachable, 1, "remove-unreachable", _(" -fno-remove-unreachable\tdisable remove of unreachable code\n" " * turned off by -g")) diff --git a/cobc/help.c b/cobc/help.c index 3e95a2e19..53077416f 100644 --- a/cobc/help.c +++ b/cobc/help.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2023 Free Software Foundation, Inc. + Copyright (C) 2001-2024 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Brian Tiffin, Edward Hart, Dave Pitts @@ -135,9 +135,15 @@ cobc_print_usage_common_options (void) puts (_(" --list-system display system routines")); puts (_(" --save-temps[=<dir>] save intermediate files\n" " * default: current directory")); + puts (_(" -M output dependency list in Makefile format")); puts (_(" -MT <target> set/add target file used in dependency list")); + puts (_(" -MQ <target> same as -MT but with Makefile-quoting of the target")); puts (_(" -MF <file> place dependency list into <file>")); + puts (_(" -MP create phony targets for all dependencies")); + puts (_(" -MG output missing dependencies without complaining")); + puts (_(" -MD output dependencies in .d files while compiling")); puts (_(" -ext <extension> add file extension for resolving COPY")); + puts (_(" -fcopybook-deps output copybook names as dependencies")); putchar ('\n'); } diff --git a/cobc/pplex.l b/cobc/pplex.l index ff73ff912..c3bbafbc9 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -1,5 +1,5 @@ /* - Copyright (C) 2001-2012, 2014-2023 Free Software Foundation, Inc. + Copyright (C) 2001-2012, 2014-2024 Free Software Foundation, Inc. Written by Keisuke Nishida, Roger While, Simon Sobisch, Dave Pitts This file is part of GnuCOBOL. @@ -1284,7 +1284,7 @@ ppopen_get_file (const char *name) loc.source_file = name; loc.source_line = -1; cb_error_x (&loc, _("recursive inclusion")); - return 0; + return 0; } } @@ -1458,7 +1458,7 @@ ppopen (const char *name, struct cb_replace_list *replacing_list) } /* add opened file to dependency list */ - if (cb_depend_file) { + if (cb_depend_output && !cb_flag_copybook_deps) { cb_depend_list = pp_text_list_add (cb_depend_list, name, strlen (name)); } @@ -1651,6 +1651,20 @@ ppcopy (const char *name, const char *lib, struct cb_replace_list *replace_list) plexbuff1 = cobc_malloc ((size_t)COB_SMALL_BUFF); } + if (cb_depend_output && cb_flag_copybook_deps) { + + if (lib) { + snprintf (plexbuff1, (size_t)COB_SMALL_MAX, "%s%c%s", + lib, SLASH_CHAR, name); + plexbuff1[COB_SMALL_MAX] = 0; + } else { + strcpy (plexbuff1, name); + } + cb_depend_list = + pp_text_list_add (cb_depend_list, plexbuff1, + strlen (plexbuff1)); + } + /* TODO: open with path relative to the current file's path, if any (applies both to with and without "lib") */ @@ -1721,10 +1735,23 @@ ppcopy (const char *name, const char *lib, struct cb_replace_list *replace_list) } /* otherwise fall-trough to error handling */ } else { - /* ensure to have errno from name as specified, not from another file */ - (void)access (plexbuff1, R_OK); - /* pass file error as we have no more places to check */ - cb_error ("%s: %s", plexbuff1, cb_get_strerror ()); + /* do not output error if looking only for copybook deps */ + if (!cb_flag_copybook_deps){ + + /* add opened file to dependency list */ + if (cb_depend_output && cb_depend_keep_missing) { + const char *depname = cobc_plex_stradd (plexbuff1, cb_extension_list->text); + + cb_depend_list = pp_text_list_add (cb_depend_list, depname, strlen (depname)); + } else { + + /* ensure to have errno from name as specified, not from another file */ + (void)access (plexbuff1, R_OK); + /* pass file error as we have no more places to check */ + cb_error ("%s: %s", + plexbuff1, cb_get_strerror ()); + } + } } /* On COPY, open error restore old file */ @@ -2790,6 +2817,12 @@ pp_text_list_add (struct cb_text_list *list, const char *text, struct cb_text_list *p; void *tp; + for (p = list; p; p = p->next) { + if (!strcmp(text, p->text)) { + return list; + } + } + p = cobc_plex_malloc (sizeof (struct cb_text_list)); tp = cobc_plex_malloc (size + 1); memcpy (tp, text, size); diff --git a/doc/ChangeLog b/doc/ChangeLog index 6934379cf..1f25414cd 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,8 @@ +2024-03-15 Fabrice Le Fessant <fabrice.le_fessant@ocamlpro.com> + + * gnucobol.texi: document new dependencies options + 2023-09-07 Emilien Lemaire <emilien.lemaire@ocamlpro.com> * gnucobol.texi: document the profiling feature diff --git a/doc/gnucobol.texi b/doc/gnucobol.texi index e1048c7b1..29fa893f4 100644 --- a/doc/gnucobol.texi +++ b/doc/gnucobol.texi @@ -121,6 +121,7 @@ Compiler options * Configuration options:: Configuration options * Listing options:: Listing options * Debug switches:: Debug switches +* Dependencies options:: Dependencies options * Miscellaneous:: Miscellaneous Multiple sources @@ -291,6 +292,7 @@ A complete list of options can be displayed by using the option @option{--help}. * Configuration options:: Configuration options * Listing options:: Listing options * Debug switches:: Debug switches +* Dependencies options:: Dependencies options * Miscellaneous:: Miscellaneous @end menu @@ -981,6 +983,43 @@ Do not truncate binary fields according to PICTURE. @end table +@node Dependencies options +@subsection Dependencies options + +Dependencies are files containing the content included by @code{COPY} +statements. These options are usually used by build systems to extract +dependencies from COBOL files. The dependencies can then be used to +decide when a file should be recompiled or not. + +@table @code + +@item -M +Output dependency list in Makefile format on stdout. Stop after +preprocessing the file and do not generate any other files. + +@item -MT <target> +Set/add target file used in dependency list + +@item -MQ <target> +Same as -MT but with Makefile-quoting of the target + +@item -MF <file> +Specify a filename <file> where to output dependencies + +@item -MP +Create phony targets for all dependencies + +@item -MG +Output missing dependencies without complaining + +@item -MD +Output dependencies in .d files while compiling + +@item -fcopybook-deps +Output dependencies as copybook names instead of file names + +@end table + @node Miscellaneous @subsection Miscellaneous @table @code diff --git a/tests/testsuite.src/used_binaries.at b/tests/testsuite.src/used_binaries.at index 50d8a1867..5a4ddf77f 100644 --- a/tests/testsuite.src/used_binaries.at +++ b/tests/testsuite.src/used_binaries.at @@ -279,30 +279,6 @@ AT_CHECK([$GREP 'PARAGRAPH_00_l_4:' prog.c], [0], ignore, []) AT_CHECK([$GREP 'PARAGRAPH_EX_l_7:' prog.c], [0], ignore, []) AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [bluBb END], []) -AT_CAPTURE_FILE([prog.d]) -AT_CHECK([$COBC -I sub/copy prog.cob -ext=cpy -o prog.i -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only], [0], [], []) -AT_CHECK([$GREP 'prog.c prog.h ' prog.d], [0], ignore, []) -AT_CHECK([$GREP ' prog.i:' prog.d], [0], ignore, []) -AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], ignore, [], [ - # Previous test "failed" --> no entry with slash available, check backslash for this and following tests - AT_CHECK([$GREP ' sub\\copy\\PROC.cpy \\' prog.d], [0], ignore, []) - AT_CHECK([$GREP ' sub\\PROCE.cpy' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub\\copy\\PROC.cpy:' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub\\PROCE.cpy:' prog.d], [0], ignore, []) -], [ - AT_CHECK([$GREP ' sub/copy/PROC.cpy \\' prog.d], [0], ignore, []) - AT_CHECK([$GREP ' sub/PROCE.cpy' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub/copy/PROC.cpy:' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub/PROCE.cpy:' prog.d], [0], ignore, []) -]) - -# test again with trailing slash which should not result in different files -AT_CHECK([$COBC -I sub/copy/ prog.cob -ext=cpy -o prog.i -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only], [0], [], []) -AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], ignore, [], [ - # Previous test "failed" --> no entry with slash available, check backslash for this test - AT_CHECK([$GREP 'sub\\copy\\PROC.cpy' prog.d], [0], ignore, []) -]) - AT_CLEANUP @@ -1172,3 +1148,207 @@ AT_CHECK([$COMPILE_MODULE -Wno-unfinished --copy "f.copy" -fstatic-call prog2.co ) AT_CLEANUP + + +AT_SETUP([output dependencies]) +# AT_KEYWORDS([]) + +AT_CAPTURE_FILE([compiler.output]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + COPY COPY1. + PROCEDURE DIVISION. + MAIN-PROC SECTION. + 00. + COPY COPY3. + COPY COPY3.CPY. + END-PROC SECTION. + COPY COPY4 in "sub". + EX. + STOP RUN. +]) + +AT_DATA([prog2.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + PROCEDURE DIVISION. + COPY COPY3. + STOP RUN. +]) + + +AT_CHECK([mkdir -p sub]) +AT_DATA([COPY1.CPY], [ COPY COPY2. +]) +AT_DATA([COPY2.CPY], []) +AT_DATA([COPY3.CPY], [ DISPLAY "Hello". +]) +AT_DATA([sub/COPY4.CPY], []) + +AT_CHECK([$COMPILE prog.cob]) + +AT_CHECK([$COMPILE -M prog.cob prog2.cob > compiler.output], [0]) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT:/.COB_OBJECT_EXT:/g;s/sub\\\\/sub\//g" compiler.output], [0], +[prog.COB_OBJECT_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +prog2.COB_OBJECT_EXT: \ + prog2.cob \ + COPY3.CPY + +]) + +AT_CHECK([$COMPILE -M -MF prog.dep prog.cob]) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT/.COB_OBJECT_EXT/g;s/sub\\\\/sub\//g" prog.dep], [0], +[prog.COB_OBJECT_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +]) + +AT_CHECK([$COMPILE -M -fcopybook-deps prog.cob > compiler.output], [0]) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT/.COB_OBJECT_EXT/g;s/sub\\\\/sub\//g" compiler.output], [0], +[prog.COB_OBJECT_EXT: COPY1 COPY2 COPY3 COPY3.CPY sub/COPY4 + +]) + +AT_CHECK([$COMPILE -g -M -MT prog.$COB_MODULE_EXT prog.cob > compiler.output], [0]) +AT_CHECK([$SED "s/\.$COB_MODULE_EXT/.COB_MODULE_EXT/g;s/sub\\\\/sub\//g" compiler.output], [0], +[prog.COB_MODULE_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +]) + +AT_CHECK([test -f prog.c], [1]) +AT_CHECK([test -f prog.o], [1]) + +AT_CHECK([$COMPILE -M -MQ '$(target)#toto' prog.cob > compiler.output], [0]) +AT_CHECK([$SED "s/sub\\\\/sub\//g" compiler.output], [0], +[$$(target)\#toto: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +]) + +AT_CHECK([rm -f prog.d]) +AT_CAPTURE_FILE([prog.d]) + +AT_CHECK([$COMPILE -MD prog.cob]) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT/.COB_OBJECT_EXT/g;s/sub\\\\/sub\//g" prog.d], [0], +[prog.COB_OBJECT_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +]) + +AT_CHECK([$COMPILE -MD -o sub/prog.exe prog.cob]) +AT_CHECK([test -f sub/prog.exe]) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT/.COB_OBJECT_EXT/g;s/sub\\\\/sub\//g" sub/prog.d], [0], +[prog.COB_OBJECT_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +]) + +AT_CHECK([rm sub/COPY4.CPY]) + +AT_CHECK([$COMPILE -M prog.cob > compiler.output 2> compiler.error], [1], [], []) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT/.COB_OBJECT_EXT/g" compiler.output], [0], +[prog.COB_OBJECT_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY + +]) + +AT_CHECK([$SED "s/sub\\\\/sub\//g" compiler.error], [0], +[prog.cob:13: error: sub/COPY4: No such file or directory +]) + +AT_CHECK([$COMPILE_ONLY -M -MG prog.cob > compiler.output], [0]) +AT_CHECK([$SED "s/\.$COB_OBJECT_EXT/.COB_OBJECT_EXT/g;s/sub\\\\/sub\//g" compiler.output], [0], +[prog.COB_OBJECT_EXT: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + COPY3.CPY \ + sub/COPY4.CPY + +]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 BLA PIC X(5) VALUE 'bluBb'. + PROCEDURE DIVISION. + MAIN-PROC SECTION. + 00. + COPY PROC. + END-PROC SECTION. + COPY PROCE in "sub". + EX. + STOP RUN. +]) + +AT_CHECK([mkdir -p sub/copy]) +AT_DATA([sub/copy/PROC.cpy], [ + DISPLAY BLA NO ADVANCING. +]) +AT_DATA([sub/PROCE.cpy], [ + DISPLAY ' END' NO ADVANCING. +]) + +AT_CAPTURE_FILE([prog.d]) +AT_CHECK([$COBC -I sub/copy prog.cob -ext=cpy -o prog.i -M -MP -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only]) +AT_CHECK([$GREP 'prog.c prog.h ' prog.d], [0], [ignore]) +AT_CHECK([$GREP ' prog.i:' prog.d], [0], [ignore]) +AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], [ignore], [], [ + # Previous test "failed" --> no entry with slash available, check backslash for this and following tests + AT_CHECK([$GREP ' sub\\copy\\PROC.cpy \\' prog.d], [0], [ignore]) + AT_CHECK([$GREP ' sub\\PROCE.cpy' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub\\copy\\PROC.cpy:' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub\\PROCE.cpy:' prog.d], [0], [ignore]) +], [ + AT_CHECK([$GREP ' sub/copy/PROC.cpy \\' prog.d], [0], [ignore]) + AT_CHECK([$GREP ' sub/PROCE.cpy' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub/copy/PROC.cpy:' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub/PROCE.cpy:' prog.d], [0], [ignore]) +]) + +# test again with trailing slash which should not result in different files +AT_CHECK([$COBC -I sub/copy/ prog.cob -ext=cpy -o prog.i -M -MP -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only]) +AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], [ignore], [], [ + # Previous test "failed" --> no entry with slash available, check backslash for this test + AT_CHECK([$GREP 'sub\\copy\\PROC.cpy' prog.d], [0], [ignore]) +]) + +AT_CLEANUP + + From 9b0259d78f87e479887f617206a002636c8e57cb Mon Sep 17 00:00:00 2001 From: nberth <nberth@ed166372-6744-4ac0-a67f-bb1ae9efa102> Date: Tue, 1 Oct 2024 09:00:58 +0000 Subject: [PATCH 50/51] Support collating sequence for indexed file keys of alphanumeric class cobc: * tree.c (validate_indexed_key_field): warn about ignored collating sequence for non-alphanumeric keys (considers only primary keys and file collating sequence for now) * codegen.c (output_indexed_file_key_colseq): assign collating sequence for any key of alphanumeric class, and preliminary handing of NATIONAL collations * parser.y: adjust position of messages about unfinished KEY or FILE COLLATING SEQUENCE --- cobc/ChangeLog | 13 ++- cobc/codegen.c | 12 +-- cobc/parser.y | 4 +- cobc/tree.c | 21 +++++ tests/testsuite.src/run_file.at | 159 ++++++++++++++++++++++++++++++-- tests/testsuite.src/syn_file.at | 57 +++++++++++- 6 files changed, 247 insertions(+), 19 deletions(-) diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 05399a1d6..3d38e0246 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,15 @@ +2024-10-01 Nicolas Berthier <nicolas.berthier@ocamlpro.com> + + * tree.c (validate_indexed_key_field): warn about ignored collating + sequence for non-alphanumeric keys (considers only primary keys and file + collating sequence for now) + * codegen.c (output_indexed_file_key_colseq): assign collating sequence + for any key of alphanumeric class, and preliminary handing of NATIONAL + collations + * parser.y: adjust position of messages about unfinished KEY or FILE + COLLATING SEQUENCE + 2024-09-29 Simon Sobisch <simonsobisch@gnu.org> * cobc.c (cobc_print_info): drop COB_LI_IS_LL @@ -6,7 +17,7 @@ 2024-09-27 Simon Sobisch <simonsobisch@gnu.org> - * plex.l, scanner.l: use noyywrap option instead of manually + * plex.l, scanner.l: use noyywrap option instead of manually defining related code parts * typeck.c (cb_tree_list_has_numeric_ref_or_field): cleanup diff --git a/cobc/codegen.c b/cobc/codegen.c index 298917312..d3bcc2fc7 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -9341,16 +9341,14 @@ output_indexed_file_key_colseq (const struct cb_file *f, const struct cb_alt_key { const cb_tree key = ak ? ak->key : f->key; const cb_tree key_col = ak ? ak->collating_sequence_key : f->collating_sequence_key; - const int type = cb_tree_type (key, cb_code_field (key)); cb_tree col = NULL; - /* We only apply a collating sequence if the key is alphanumeric / display */ - if ((type & COB_TYPE_ALNUM) || (type == COB_TYPE_NUMERIC_DISPLAY)) { + /* We only apply a collating sequence if the key is of class alphanumeric; + Warned in `validate_indexed_key_field`. */ + if (CB_TREE_CLASS (key) == CB_CLASS_ALPHANUMERIC) { col = key_col ? key_col : f->collating_sequence; -#if 0 /* TODO: this should be done for national, when available */ - } else if (type & COB_TYPE_NATIONAL) { - col = key_col_n ? key_col_n : f->collating_sequence_n; -#endif + } else if (CB_TREE_CLASS (key) == CB_CLASS_NATIONAL) { + col = f->collating_sequence_n; } output_prefix (); diff --git a/cobc/parser.y b/cobc/parser.y index 5f4eebe45..6293848c0 100644 --- a/cobc/parser.y +++ b/cobc/parser.y @@ -5784,7 +5784,7 @@ 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_UNFINISHED ("FILE COLLATING SEQUENCE"); /* only implemented for BDB */ + CB_UNFINISHED_X (alphanumeric_collation, "FILE COLLATING SEQUENCE"); /* only implemented for BDB */ } ; @@ -5836,7 +5836,7 @@ collating_sequence_clause_key: and also attached to the correct key later, so just store in a list here: */ current_file->collating_sequence_keys = cb_list_add(current_file->collating_sequence_keys, CB_BUILD_PAIR ($6, $4)); - CB_UNFINISHED ("KEY COLLATING SEQUENCE"); /* only implemented for BDB */ + CB_UNFINISHED_X ($6, "KEY COLLATING SEQUENCE"); /* only implemented for BDB */ } ; diff --git a/cobc/tree.c b/cobc/tree.c index cb49c88c8..0e2f9bb18 100644 --- a/cobc/tree.c +++ b/cobc/tree.c @@ -4781,6 +4781,27 @@ validate_indexed_key_field (struct cb_file *f, struct cb_field *records, } } } + + /* check collating sequence is not ignored */ + if (get_warn_opt_value (cb_warn_filler) != COBC_WARN_DISABLED + && CB_TREE_CLASS (k) != CB_CLASS_ALPHANUMERIC) { + const char *source = "KEY"; + cb_tree colseq = (cbak == NULL) + ? f->collating_sequence_key + : cbak->collating_sequence_key; + cb_tree pos = colseq; + if (colseq == NULL) { + source = "FILE"; + colseq = f->collating_sequence; + pos = key_ref; + } + if (colseq != NULL) { + cb_warning_x (COBC_WARN_FILLER, CB_TREE (pos), + _("%s COLLATING SEQUENCE '%s' is ignored " + "for non-alphanumeric key '%s'"), + source, CB_NAME (colseq), k->name); + } + } } void diff --git a/tests/testsuite.src/run_file.at b/tests/testsuite.src/run_file.at index 11a491571..2aed60f08 100644 --- a/tests/testsuite.src/run_file.at +++ b/tests/testsuite.src/run_file.at @@ -12444,7 +12444,7 @@ AT_CLEANUP # This is, so far, only supported by the BDB backend -AT_SETUP([INDEXED files under ASCII/EBCDIC collation]) +AT_SETUP([INDEXED file under ASCII/EBCDIC collation]) AT_KEYWORDS([runfile WRITE DELETE READ EBCDIC]) AT_SKIP_IF([test "$COB_HAS_ISAM" != "db"]) @@ -12685,13 +12685,15 @@ CCC 888 +0000000043 1 DONE ]) +# Note: `-Wno-others` is for ignored COLLATIONS for non-alphanumeric keys + # Testing ASCII file collating sequence using clause AT_DATA([prog1.cob], [ COPY "prog.cpy" REPLACING ==FILE-COLSEQ== BY ==COLLATING SEQUENCE IS ASCII== ==KEY-COLSEQ== BY ====. ]) -AT_CHECK([$COMPILE -Wno-unfinished prog1.cob], [0], [], []) +AT_CHECK([$COMPILE -Wno-unfinished -Wno-others prog1.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog1 1>prog1.out], [0], [], []) AT_CHECK([diff reference_ascii prog1.out], [0], [], []) @@ -12712,7 +12714,7 @@ AT_DATA([prog3.cob], [ ==FILE-COLSEQ== BY ==COLLATING SEQUENCE IS ASCII== ==KEY-COLSEQ== BY ==COLLATING SEQUENCE OF MY-AKEY1 IS EBCDIC==. ]) -AT_CHECK([$COMPILE -Wno-unfinished prog3.cob], [0], [], []) +AT_CHECK([$COMPILE -Wno-unfinished -Wno-others prog3.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog3 1>prog3.out], [0], [], []) AT_CHECK([diff reference_ascii_ebcdic prog3.out], [0], [], []) @@ -12732,7 +12734,7 @@ AT_DATA([prog5.cob], [ ==FILE-COLSEQ== BY ==COLLATING SEQUENCE IS EBCDIC== ==KEY-COLSEQ== BY ==COLLATING SEQUENCE OF MY-AKEY1 IS EBCDIC==. ]) -AT_CHECK([$COMPILE -Wno-unfinished prog5.cob], [0], [], []) +AT_CHECK([$COMPILE -Wno-unfinished -Wno-others prog5.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog5 1>prog5.out], [0], [], []) AT_CHECK([diff reference_ebcdic prog5.out], [0], [], []) @@ -12742,7 +12744,7 @@ AT_DATA([prog6.cob], [ ==FILE-COLSEQ== BY ==== ==KEY-COLSEQ== BY ====. ]) -AT_CHECK([$COMPILE -Wno-unfinished -fdefault-file-colseq=EBCDIC prog6.cob], [0], [], []) +AT_CHECK([$COMPILE -Wno-unfinished -Wno-others -fdefault-file-colseq=EBCDIC prog6.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog6 1>prog6.out], [0], [], []) AT_CHECK([diff reference_ebcdic prog6.out], [0], [], []) @@ -12752,7 +12754,7 @@ AT_DATA([prog7.cob], [ ==FILE-COLSEQ== BY ==COLLATING SEQUENCE IS EBCDIC== ==KEY-COLSEQ== BY ==COLLATING SEQUENCE OF MY-AKEY1 IS ASCII==. ]) -AT_CHECK([$COMPILE -Wno-unfinished prog7.cob], [0], [], []) +AT_CHECK([$COMPILE -Wno-unfinished -Wno-others prog7.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog7 1>prog7.out], [0], [], []) AT_CHECK([diff reference_ebcdic_ascii prog7.out], [0], [], []) @@ -12762,13 +12764,156 @@ AT_DATA([prog8.cob], [ ==FILE-COLSEQ== BY ==== ==KEY-COLSEQ== BY ==COLLATING SEQUENCE OF MY-AKEY1 IS ASCII==. ]) -AT_CHECK([$COMPILE -Wno-unfinished -fdefault-file-colseq=EBCDIC prog8.cob], [0], [], []) +AT_CHECK([$COMPILE -Wno-unfinished -Wno-others -fdefault-file-colseq=EBCDIC prog8.cob], [0], [], []) AT_CHECK([$COBCRUN_DIRECT ./prog8 1>prog8.out], [0], [], []) AT_CHECK([diff reference_ebcdic_ascii prog8.out], [0], [], []) AT_CLEANUP +AT_SETUP([INDEXED file with collation on group key]) +AT_KEYWORDS([runfile WRITE READ EBCDIC]) + +AT_SKIP_IF([test "$COB_HAS_ISAM" = "no"]) + +# This is, so far, only supported by the BDB backend +AT_XFAIL_IF([test "$COB_HAS_ISAM" != "db"]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT MY-FILE ASSIGN TO "testfile" + ORGANIZATION IS INDEXED + ACCESS IS DYNAMIC + RECORD KEY IS MY-KEY. + DATA DIVISION. + FILE SECTION. + FD MY-FILE. + 01 MY-REC. + 05 MY-KEY. + 10 MY-KEY-1 PIC X. + 10 MY-KEY-2 PIC X. + 05 MY-DATA PIC 9. + PROCEDURE DIVISION. + + OPEN OUTPUT MY-FILE + MOVE "111" TO MY-REC WRITE MY-REC + MOVE "AA2" TO MY-REC WRITE MY-REC + MOVE "223" TO MY-REC WRITE MY-REC + MOVE "BB4" TO MY-REC WRITE MY-REC + MOVE "335" TO MY-REC WRITE MY-REC + MOVE "CC6" TO MY-REC WRITE MY-REC + MOVE "447" TO MY-REC WRITE MY-REC + MOVE "DD8" TO MY-REC WRITE MY-REC + CLOSE MY-FILE + + OPEN INPUT MY-FILE + MOVE LOW-VALUES TO MY-KEY + START MY-FILE KEY >= MY-KEY + INVALID KEY + DISPLAY "INVALID KEY" + NOT INVALID KEY + PERFORM UNTIL EXIT + READ MY-FILE NEXT + AT END + EXIT PERFORM + NOT AT END + DISPLAY MY-REC + END-READ + END-PERFORM + END-START. + CLOSE MY-FILE + + STOP RUN. +]) + +AT_DATA([expout], +[ASCII: +111 +223 +335 +447 +AA2 +BB4 +CC6 +DD8 +EBCDIC: +AA2 +BB4 +CC6 +DD8 +111 +223 +335 +447 +]) + +# Note: ignore any unfinished warning as the test is about the runtime behavior: +AT_CHECK([$COMPILE -Wno-unfinished -fdefault-file-colseq=ASCII prog.cob -o ascii], [0]) +AT_CHECK([$COMPILE -Wno-unfinished -fdefault-file-colseq=EBCDIC prog.cob -o ebcdic], [0]) + +AT_CHECK([ + echo "ASCII:" && $COBCRUN_DIRECT ./ascii && \ + echo "EBCDIC:" && $COBCRUN_DIRECT ./ebcdic +], [0], [expout]) # <- compare stdout with existing `expout` + +AT_CLEANUP + + +# Note: codegen only for now +AT_SETUP([INDEXED file with NATIONAL collation]) +AT_KEYWORDS([runfile]) + +AT_SKIP_IF([test "$COB_HAS_ISAM" = "no"]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT MY-FILE ASSIGN TO "testfile" + ORGANIZATION IS INDEXED + ACCESS IS DYNAMIC + RECORD KEY IS MY-KEY + COLLATING SEQUENCE FOR NATIONAL IS ASCII. + DATA DIVISION. + FILE SECTION. + FD MY-FILE. + 01 MY-REC. + 05 MY-KEY PIC N. + 05 MY-DATA PIC 9. + PROCEDURE DIVISION. + + OPEN OUTPUT MY-FILE + MOVE "11" TO MY-REC WRITE MY-REC + MOVE "A2" TO MY-REC WRITE MY-REC + MOVE "23" TO MY-REC WRITE MY-REC + MOVE "B4" TO MY-REC WRITE MY-REC + MOVE "35" TO MY-REC WRITE MY-REC + MOVE "C6" TO MY-REC WRITE MY-REC + MOVE "47" TO MY-REC WRITE MY-REC + MOVE "D8" TO MY-REC WRITE MY-REC + CLOSE MY-FILE + + STOP RUN. +]) + +AT_DATA([expout], []) + +# Note: ignore any unfinished warning as the test is about the runtime behavior: +AT_CHECK([$COMPILE -Wno-unfinished prog.cob], [0], [], +[prog.cob:11: warning: NATIONAL COLLATING SEQUENCE is not implemented +]) + +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [expout]) + +AT_CLEANUP + + AT_SETUP([INDEXED file numeric keys ordering]) AT_KEYWORDS([runfile]) diff --git a/tests/testsuite.src/syn_file.at b/tests/testsuite.src/syn_file.at index 24c1f835f..1f43f9025 100644 --- a/tests/testsuite.src/syn_file.at +++ b/tests/testsuite.src/syn_file.at @@ -631,7 +631,7 @@ AT_CLEANUP AT_SETUP([INDEXED file invalid key items]) -AT_KEYWORDS([record ALTERNATE split]) +AT_KEYWORDS([record ALTERNATE split collation]) AT_DATA([prog.cob], [ IDENTIFICATION DIVISION. @@ -658,6 +658,32 @@ AT_DATA([prog.cob], [ RECORD KEY IS NOT-HERE-KEY SOURCE IS NOT-IN-FILE1 NOT-IN-FILE2. + SELECT TEST-CSQ1 ASSIGN TO 'FILE-TEST-COSQ1' + ORGANIZATION IS INDEXED + ACCESS MODE IS DYNAMIC + RECORD KEY IS TEST-P5 + ALTERNATE KEY IS TEST-P6 + ALTERNATE KEY IS TEST-P7 + COLLATING SEQUENCE IS EBCDIC + COLLATING SEQUENCE OF TEST-P7 IS EBCDIC. + SELECT TEST-CSQ2 ASSIGN TO 'FILE-TEST-COSQ2' + ORGANIZATION IS INDEXED + ACCESS MODE IS DYNAMIC + RECORD KEY IS TEST-P8 + COLLATING SEQUENCE IS EBCDIC *> unused + COLLATING SEQUENCE OF TEST-P8 IS EBCDIC. + SELECT TEST-CSQ3 ASSIGN TO 'FILE-TEST-COSQ3' + ORGANIZATION IS INDEXED + ACCESS MODE IS DYNAMIC + RECORD KEY IS SPLIT-KEY1 = TEST-P9 TEST-P10 + ALTERNATE KEY IS SPLIT-KEY2 = TEST-P9 TEST-P11 + COLLATING SEQUENCE IS EBCDIC *> should not warn + COLLATING SEQUENCE OF SPLIT-KEY2 IS EBCDIC.*> should not warn + SELECT TEST-CSQ4 ASSIGN TO 'FILE-TEST-COSQ4' + ORGANIZATION IS INDEXED + ACCESS MODE IS DYNAMIC + RECORD KEY IS SPLIT-KEY3 = TEST-P12 + COLLATING SEQUENCE OF SPLIT-KEY1 IS EBCDIC. DATA DIVISION. FILE SECTION. FD TEST-SOME. @@ -670,6 +696,23 @@ AT_DATA([prog.cob], [ FD TEST-MORE. 01 MORE-REC. 05 MORE-DATA PIC X(4). + FD TEST-CSQ1. + 01 CSQ1-REC. + 05 TEST-P5 PIC 9(2) BINARY. + 05 TEST-P6 PIC 9(2) BINARY. + 05 TEST-P7 PIC X(2). + FD TEST-CSQ2. + 01 CSQ2-REC. + 05 TEST-P8 PIC 9(2) BINARY. + 05 TEST-P8X PIC X(2). + FD TEST-CSQ3. + 01 CSQ3-REC. + 05 TEST-P9 PIC 9(2) BINARY. + 05 TEST-P10 PIC 9(2) BINARY. + 05 TEST-P11 PIC X(2). + FD TEST-CSQ4. + 01 CSQ4-REC. + 05 TEST-P12 PIC 9(2) BINARY. WORKING-STORAGE SECTION. 77 TEST-P2 PIC S9(4) COMP. 77 TEST-P3 PIC S9(5) COMP-3. @@ -681,13 +724,23 @@ AT_DATA([prog.cob], [ # FIXME: "is not defined" should be changed in "is not defined in file ..." AT_CHECK([$COMPILE_ONLY prog.cob], [1], [], -[prog.cob:10: error: 'TEST-P2' is not defined +[prog.cob:32: warning: handling of FILE COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:33: warning: handling of KEY COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:38: warning: handling of FILE COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:39: warning: handling of KEY COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:45: warning: handling of FILE COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:46: warning: handling of KEY COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:51: warning: handling of KEY COLLATING SEQUENCE is unfinished; implementation is likely to be changed +prog.cob:10: error: 'TEST-P2' is not defined prog.cob:11: error: 'TEST-P1' is not defined prog.cob:12: error: 'TEST-P3' is not defined prog.cob:18: error: 'NOT-THERE' is not defined prog.cob:13: error: invalid KEY item 'SOME-REC', not in file 'TEST-FILE' prog.cob:24: error: 'NOT-IN-FILE1' is not defined prog.cob:20: error: invalid KEY item 'NOT-HERE-KEY', not in file 'TEST-MORE' +prog.cob:66: warning: FILE COLLATING SEQUENCE 'EBCDIC' is ignored for non-alphanumeric key 'TEST-P5' +prog.cob:67: warning: FILE COLLATING SEQUENCE 'EBCDIC' is ignored for non-alphanumeric key 'TEST-P6' +prog.cob:39: warning: KEY COLLATING SEQUENCE 'EBCDIC' is ignored for non-alphanumeric key 'TEST-P8' prog.cob:25: error: 'NOT-IN-FILE2' is not defined ]) From 7d4a2fd772a6dc6e8de09bf3aeed02d1081c550d Mon Sep 17 00:00:00 2001 From: Simon Sobisch <simonsobisch@web.de> Date: Mon, 7 Oct 2024 09:55:44 +0000 Subject: [PATCH 51/51] ci adjustments * ubuntu: * only run jobs for "coverage" and "additional warnings" if the main ci build works and use its generated tarball in both cases * add two new artifacts: test binaries and windows source * ubuntu+msys1+msys2+macos: * upload config.log after the build - because we may need it to debug build issues * always upload the testsuite.log (additional build documentation) * ubuntu+msys1+msys2: * use --with-pkgversion to mark CI binaries * msys2+macos: * uploading NIST test results * msys1: * GMP url changes, building it again for performance reasons * building BDB with all relevant patches from MSYS2 * drop GC install log step and therefore extra prefix * using msys-build instead of building Bison (only necessary for GC4) * drop extra CFLAGS previously necessary for local cJSON (fixed in 3.x) * enable NIST85 (+ comment-code in case we ever need to skip something there and/or ignoring failing NIST) --> as after last upstream update everything works * ci cache adjustment: * remove split per matrix * split per software, enabling smaller updates * use CI tarball like for the minimal build, drop flex+bison * drop workflow specific expected failures that now work fine * move env to MSYS job * resolve env vars by build API instead of runner * integrate msys1.yml into ubuntu.yml, renaming to build_nightly.yml * msys2: * split NIST + internal testsuite and run the later with less jobs to prevent hanging * split between "prepare" and "build" job, with the former generating a full distribution inclusive documentation, and the later having less packages installed, allowing to enable i386 again * disable BDB for 32bit build as MSYS2 doesn't provide that any more * switch cjson to json-c (more commonly used, MSYS2 still providing 32bit build) * explicit list of dependencies for configure * msvc: * testsuite skip adjustments from the generated testsuite * enable building binary package and artifact * export dependencies and artifact --- .github/workflows/build_nightly.yml | 701 ++++++++++++++++++++++++++++ .github/workflows/macos.yml | 32 +- .github/workflows/ubuntu.yml | 310 ------------ .github/workflows/windows-msvc.yml | 117 ++--- .github/workflows/windows-msys1.yml | 245 ---------- .github/workflows/windows-msys2.yml | 188 +++++--- 6 files changed, 921 insertions(+), 672 deletions(-) create mode 100644 .github/workflows/build_nightly.yml delete mode 100644 .github/workflows/ubuntu.yml delete mode 100644 .github/workflows/windows-msys1.yml diff --git a/.github/workflows/build_nightly.yml b/.github/workflows/build_nightly.yml new file mode 100644 index 000000000..0d3b44d51 --- /dev/null +++ b/.github/workflows/build_nightly.yml @@ -0,0 +1,701 @@ +name: Build, Test and provide Nightly (Ubuntu + MSYS1) + +on: + + pull_request: + branches: [ gcos4gnucobol-3.x ] + push: + # manual run in actions tab - for all branches + workflow_dispatch: + + +jobs: + + build: + name: Build, test and provide nightly + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + + steps: + - name: Install packages + run: | + sudo apt -y update + sudo apt -y install automake libtool libdb5.3-dev libxml2-dev libcjson-dev \ + bison flex help2man gettext texlive + + - name: Set git user + run: | + git config --global user.name github-actions + git config --global user.email github-actions-bot@users.noreply.github.com + + - name: Checkout code + uses: actions/checkout@v4 + + - name: Bootstrap + run: | + ./build_aux/bootstrap + + # FIXME: With TERM="dumb" `make check` fails with: + # ... + # 571: ACCEPT OMITTED (SCREEN) FAILED (run_accept.at:307) + # ... + # 693: ON EXCEPTION clause of DISPLAY FAILED (run_misc.at:6335) + # 695: LINE/COLUMN 0 exceptions FAILED (run_misc.at:6414) + # 694: EC-SCREEN-LINE-NUMBER and -STARTING-COLUMN FAILED (run_misc.at:6376) + # ... + # Failure cases read: "Error opening terminal: unknown." on + # stderr, and exit with code 1. + # + # Another alternative is passing `--with-curses=no` to the + # configure script, yet distcheck does call configure too... + # + - name: Build environment setup + run: | + mkdir _build + export TERM="vt100" + echo "TERM=$TERM" >> $GITHUB_ENV + + - name: Configure + run: | + cd _build + ../configure --enable-cobc-internal-checks \ + --enable-hardening \ + --prefix /opt/gnucobol3 \ + --with-pkgversion="GnuCOBOL CI" + echo "VERSION=PACKAGE_VERSION" | cpp -P -imacros config.h | tr -d \" \ + >> $GITHUB_ENV + + - name: Build + run: | + make -C _build --jobs=$(($(nproc)+1)) + + - name: Upload config.log + uses: actions/upload-artifact@v4 + if: failure() + with: + name: config-${{ matrix.os }}-${{ github.job }}.log + path: _build/config.log + + # note: distcheck also creates the dist tarball + - name: Build distribution archive & run tests + run: | + make -C _build distcheck \ + TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" \ + --jobs=$(($(nproc)+1)) || \ + make -C _build/gnucobol-$VERSION/_build/sub/tests check \ + TESTSUITEFLAGS="--recheck --verbose" + make -C _build --jobs=$(($(nproc)+1)) dist DIST_TARGETS="dist-gzip distwin-zip" + make -C _build --jobs=$(($(nproc)+1)) distbin DISTBIN_TARGETS="distbin-xz" + + - name: Upload testsuite.log + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + # Assume there's only one directory matching `build/gnucobol-*`: + name: testsuite-${{ matrix.os }}-${{ github.job }}.log + path: _build/gnucobol-${{ env.VERSION }}/_build/sub/tests/testsuite.log + + - name: Upload dist tarball + uses: actions/upload-artifact@v4 + with: + name: gnucobol-ci source distribution + path: _build/gnucobol*.tar.gz + if-no-files-found: error + retention-days: 0 + + - name: Upload dist tarball + uses: actions/upload-artifact@v4 + with: + name: gnucobol-ci windows source distribution + path: _build/gnucobol*.zip + if-no-files-found: error + retention-days: 0 + + - name: Upload test binaries + uses: actions/upload-artifact@v4 + with: + name: gnucobol-ci binary distribution + path: _build/gnucobol*.tar.xz + if-no-files-found: error + retention-days: 0 + + - name: Cache newcob.val + uses: actions/cache@v4 + with: + path: _build/tests/cobol85/newcob.val + key: newcob-val + save-always: true + enableCrossOsArchive: true + + - name: NIST85 Test Suite + run: | + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) + + - name: Upload NIST85 Test Suite results + uses: actions/upload-artifact@v4 + with: + name: NIST85 results on ${{ matrix.os }}-${{ github.job }} + path: | + _build/tests/cobol85/summary.* + _build/tests/cobol85/**/*.log + _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt + + minmal_build: + name: Build and test with minimal dependencies + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest] + needs: build + runs-on: ${{ matrix.os }} + + steps: + + - name: Install packages + run: | + sudo apt -y update + sudo apt -y install build-essential libgmp-dev + sudo apt -y remove bison flex + + - name: Get CI dist tarball + uses: actions/download-artifact@v4 + with: + name: gnucobol-ci source distribution + + - name: Build environment setup + run: | + tar -xvf gnucobol*.tar.* --strip-components=1 + mkdir _build + + - name: Configure + run: | + cd _build + ../configure --disable-dependency-tracking \ + --without-db --without-curses \ + --without-xml2 --without-json \ + --without-iconv --disable-nls + + - name: Build + run: | + make -C _build --jobs=$(($(nproc)+1)) + + - name: Upload config.log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: config-${{ matrix.os }}-${{ github.job }}.log + path: _build/config.log + + - name: run internal tests + run: | + make -C _build check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || \ + make -C _build check TESTSUITEFLAGS="--recheck --verbose" + + - name: Upload testsuite.log + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: testsuite-${{ matrix.os }}-${{ github.job }}.log + path: _build/tests/testsuite.log + + - name: Cache newcob.val + uses: actions/cache@v4 + with: + path: _build/tests/cobol85/newcob.val + key: newcob-val + save-always: true + enableCrossOsArchive: true + + - name: NIST85 Test Suite + run: | + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) + + - name: Upload NIST85 Test Suite results + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: NIST85 results on ${{ matrix.os }}-${{ github.job }} + path: | + _build/tests/cobol85/summary.* + _build/tests/cobol85/**/*.log + _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt + + + coverage: + name: Coverage and Warnings + needs: build + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt -y install libdb5.3-dev libxml2-dev libcjson-dev lcov + + - name: Get CI dist tarball + uses: actions/download-artifact@v4 + with: + name: gnucobol-ci source distribution + + - name: Build environment setup + run: | + tar -xvf gnucobol*.tar.* --strip-components=1 + mkdir _build + export TERM="vt100" + echo "TERM=$TERM" >> $GITHUB_ENV + + # note: add additional C compiler syntax checks here to not need + # _another_ CI run + # + # TODO: try and pass -pedantic via CPPFLAGS + - name: Configure + run: | + cd _build + ../configure --enable-code-coverage \ + --with-db --with-xml2 --with-json=cjson --with-curses=ncursesw \ + CPPFLAGS="-Werror=declaration-after-statement" \ + CC="gcc -std=c89" + + - name: Build + run: | + make -C _build --jobs=$(($(nproc)+1)) + + - name: Upload config.log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: config-${{ github.job }}.log + path: _build/config.log + + - name: Coverage + run: | + # make -C _build check-code-coverage # <- (ignores errors) + make -C _build check \ + TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" + make -C _build code-coverage-capture \ + CODE_COVERAGE_DIRECTORY="$(realpath .)/_build" + + - name: Upload testsuite.log + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: testsuite-${{ github.job }}.log + path: _build/tests/testsuite.log + + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: coverage + path: _build/GnuCOBOL-**-coverage + + - name: Cache newcob.val + uses: actions/cache@v4 + with: + path: _build/tests/cobol85/newcob.val + key: newcob-val + save-always: true + enableCrossOsArchive: true + + - name: Extended coverage + run: | + make -C _build/tests/cobol85 EXEC85 test \ + --jobs=$(($(nproc)+1)) \ + --keep-going + make -C _build code-coverage-capture \ + CODE_COVERAGE_OUTPUT_DIRECTORY=extended-coverage \ + CODE_COVERAGE_OUTPUT_FILE=extended-coverage.info \ + CODE_COVERAGE_DIRECTORY="$(realpath .)/_build" + + - name: Upload extended coverage report + uses: actions/upload-artifact@v4 + with: + name: extended-coverage + path: _build/extended-coverage + + - name: Upload coverage to codecov + uses: codecov/codecov-action@v3 + with: + # token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos + directory: _build + # Shall fail until we have a working account on codecov.io + fail_ci_if_error: false # optional (default = false) + verbose: true # optional (default = false) + + + msys_build_test_createdist: + + needs: build + runs-on: windows-latest + timeout-minutes: 30 + + env: + MSYS_ROOT: C:\MinGW + MSYS_BIN: C:\MinGW\msys\1.0\bin + #BISON_PKGDATADIR: C:\MinGW\share\bison + # M4: m4 + MSYSTEM: MINGW32 + MSYSPKGS: msys-m4 msys-coreutils msys-patch + #MSYSPKGS: msys-m4 msys-flex msys-coreutils msys-help2man msys-bison msys-patch GC3 from VCS + #MINGW_AUTOCONF_VERS: 2.7.0 # only needed to build from VCS, not from dist tarball + #MINGW_BISON_VERS: bison-3.6 # minimal for GC 4.x+ + MINGW_GMP_VERS: gmp-6.3.0 # always update for performance reasons + MINGW_BDB_VERS: db-6.0.19.NC + MINGW_PDCM_VERS: 4.4.0 + MINGW_CJSON_VERS: 1.7.18 + MINGW_XML2_VERS: 2.8.0 + + strategy: + fail-fast: false + matrix: + target: + - debug + - release + + steps: + + - name: Get CI dist tarball + uses: actions/download-artifact@v4 + with: + name: gnucobol-ci source distribution + + - name: Build environment setup + run: | + bash -lc "tar -xvf gnucobol*.tar.* --strip-components=1" + mkdir _build + + - name: Setup environment + run: | + echo GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV + echo HOME=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV + echo PATH="$env:MSYS_BIN;$env:PATH" >> $env:GITHUB_ENV + If ("${{ matrix.target }}" -eq "release") { + echo DISTDIR=GnuCOBOL_mingw >> $env:GITHUB_ENV + echo CFGOPT="--with-pkgversion=GnuCOBOL-CI-MSYS" >> $env:GITHUB_ENV + } else { + echo DISTDIR=GnuCOBOL_mingw_dbg >> $env:GITHUB_ENV + echo CFGOPT="--with-pkgversion=GnuCOBOL-CI-MSYS-Debug --enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV + } + + - name: Restore MSYS1 cache + id: restore-msys + uses: actions/cache/restore@v4 + with: + key: cache-msys + path: ${{ env.MSYS_ROOT }} + + - name: Install MSYS1 + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + curl -O https://www.arnoldtrembley.com/MinGW-bkup02.7z + 7z x -y MinGW-bkup02.7z -o${{ env.MSYS_ROOT }}\ + + - name: Install MSYS1 packages + if: steps.restore-msys.outputs.cache-hit != 'true' + run: | + ${{ env.MSYS_ROOT }}\bin\mingw-get install ${{ env.MSYSPKGS }} + + - name: Cleanup MSYS1 env + if: steps.restore-msys.outputs.cache-hit != 'true' + shell: cmd + run: | + rmdir /Q /S ${{ env.MSYS_ROOT }}\docs + rmdir /Q /S ${{ env.MSYS_ROOT }}\var + del /Q ${{ env.MSYS_ROOT }}\bin\gdb* + + - name: Save MSYS1 cache + if: steps.restore-msys.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-msys + path: ${{ env.MSYS_ROOT }} + + + # - name: Restore Bison cache + # id: restore-bison + # uses: actions/cache/restore@v4 + # with: + # key: cache-msys-bison + # path: ${{ env.MINGW_BISON_VERS }} + + # - name: Install Bison + # if: steps.restore-bison.outputs.cache-hit != 'true' + # run: | + # curl -L https://ftp.gnu.org/gnu/bison/%MINGW_BISON_VERS%.tar.gz -o %MINGW_BISON_VERS%.tar.gz + # tar -xvf %MINGW_BISON_VERS%.tar.gz + # bash -lc "cd %MINGW_BISON_VERS% && ./configure --prefix=/mingw && make" + + # - name: Install Bison + # run: | + # bash -lc "make -C %MINGW_BISON_VERS% install" + + # - name: Save Bison cache + # if: steps.restore-bison.outputs.cache-hit != 'true' + # uses: actions/cache/save@v4 + # with: + # key: cache-msys-bison + # path: ${{ env.MINGW_BISON_VERS }} + + + # - name: Restore Autoconf cache + # id: restore-autoconf + # uses: actions/cache/restore@v4 + # with: + # key: cache-msys-autoconf + # path: ${{ env.MINGW_BISON_VERS }} + + # - name: Install Autoconf 2.70 + # if: steps.restore-autoconf.outputs.cache-hit != 'true' + # run: | + # curl -L https://ftpmirror.gnu.org/autoconf/%MINGW_AUTOCONF_VERS%.tar.gz -o %MINGW_AUTOCONF_VERS%.tar.gz + # tar -xvzf %MINGW_AUTOCONF_VERS%.tar.gz + # bash -lc "cd %MINGW_AUTOCONF_VERS% && ./configure" + # bash -lc "cd %MINGW_AUTOCONF_VERS% && make" + + # - name: Install Autoconf + # run: | + # bash -lc "cd %MINGW_AUTOCONF_VERS% && make install" + + # - name: Save Autoconf cache + # if: steps.restore-autoconf.outputs.cache-hit != 'true' + # uses: actions/cache/save@v4 + # with: + # key: cache-msys-autoconf + # path: ${{ env.MINGW_BISON_VERS }} + + + - name: Restore GMP cache + id: restore-gmp + uses: actions/cache/restore@v4 + with: + key: cache-msys-gmp + path: ${{ env.MINGW_GMP_VERS }} + + - name: Build GMP + if: steps.restore-gmp.outputs.cache-hit != 'true' + shell: cmd + run: | + rem note: MSYS1 cannot connect to https://gmplib.org, so using GNU mirror side instead + curl -L https://ftp.gnu.org/gnu/gmp/${{ env.MINGW_GMP_VERS }}.tar.xz -o ${{ env.MINGW_GMP_VERS }}.tar.xz + tar -xvf ${{ env.MINGW_GMP_VERS }}.tar.xz + bash -lc "cd ${{ env.MINGW_GMP_VERS }} && ./configure --prefix=/mingw --enable-fat --enable-shared --disable-static CFLAGS=\"-Wno-attributes -Wno-ignored-attributes\" ABI=32 && make --jobs=$(($(nproc)+1))" + + - name: Install GMP + run: | + bash -lc "make -C ${{ env.MINGW_GMP_VERS }} install" + + - name: Save GMP cache + if: steps.restore-gmp.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-msys-gmp + path: ${{ env.MINGW_GMP_VERS }} + + + - name: Restore BDB cache + id: restore-bdb + uses: actions/cache/restore@v4 + with: + key: cache-msys-bdb + path: ${{ env.MINGW_BDB_VERS }} + + - name: Build BDB + if: steps.restore-bdb.outputs.cache-hit != 'true' + run: | + curl -L https://download.oracle.com/berkeley-db/${{ env.MINGW_BDB_VERS }}.tar.gz -o ${{ env.MINGW_BDB_VERS }}.tar.gz + curl -L https://raw.githubusercontent.com/msys2/MINGW-packages/refs/heads/master/mingw-w64-db/0001-db-tls-m4-fix-pthread.patch -o db-tls-m4-fix-pthread.patch + curl -L https://raw.githubusercontent.com/msys2/MINGW-packages/refs/heads/master/mingw-w64-db/mingw.patch -o mingw.patch + curl -L https://raw.githubusercontent.com/msys2/MINGW-packages/refs/heads/master/mingw-w64-db/cclang_cxx_11.patch -o cx11.patch + tar -xvf ${{ env.MINGW_BDB_VERS }}.tar.gz + sed -i 's/_tcsclen/_mbslen/' ${{ env.MINGW_BDB_VERS }}\src\os_windows\os_stat.c + bash -lc "cd ${{ env.MINGW_BDB_VERS }} && /bin/patch -p1 -i ../db-tls-m4-fix-pthread.patch" + bash -lc "cd ${{ env.MINGW_BDB_VERS }} && /bin/patch -p1 -i ../mingw.patch" + bash -lc "cd ${{ env.MINGW_BDB_VERS }} && /bin/patch -p1 -i ../cx11.patch" + bash -lc "cd ${{ env.MINGW_BDB_VERS }}/build_unix && ../dist/configure --prefix=/mingw --enable-mingw --enable-debug --disable-static --disable-replication --disable-tcl --without-cryptography LIBCSO_LIBS=-lwsock32 && make --jobs=$(($(nproc)+1))" + + - name: Install BDB + run: | + bash -lc "make -C ${{ env.MINGW_BDB_VERS }}/build_unix install" + + - name: Save BDB cache + if: steps.restore-bdb.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-msys-bdb + path: ${{ env.MINGW_BDB_VERS }} + + + - name: Restore LibXML2 cache + id: restore-xml2 + uses: actions/cache/restore@v4 + with: + key: cache-msys-xml2 + path: libxml2-${{ env.MINGW_XML2_VERS }} + + - name: Build LibXML2 + if: steps.restore-xml2.outputs.cache-hit != 'true' + run: | + curl -L https://github.com/GNOME/libxml2/archive/refs/tags/v${{ env.MINGW_XML2_VERS }}.tar.gz -o libxml2-${{ env.MINGW_XML2_VERS }}.tar.xz + tar -xvf libxml2-${{ env.MINGW_XML2_VERS }}.tar.xz + bash -lc "cd libxml2-${{ env.MINGW_XML2_VERS }} && ./autogen.sh" + bash -lc "cd libxml2-${{ env.MINGW_XML2_VERS }} && ./configure --prefix=/mingw --enable-debug && make --jobs=$(($(nproc)+1))" + + - name: Install LibXML2 + run: | + bash -lc "make -C libxml2-${{ env.MINGW_XML2_VERS }} install" + + - name: Save LibXML2 cache + if: steps.restore-xml2.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-msys-xml2 + path: libxml2-${{ env.MINGW_XML2_VERS }} + + + - name: Restore PDCursesMod cache + id: restore-pdcm + uses: actions/cache/restore@v4 + with: + key: cache-msys-pdcm + path: PDCursesMod-${{ env.MINGW_PDCM_VERS }} + + - name: Build PDCursesMod + if: steps.restore-pdcm.outputs.cache-hit != 'true' + shell: cmd + run: | + curl -L https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v${{ env.MINGW_PDCM_VERS }}.tar.gz -o "PDCursesMod-${{ env.MINGW_PDCM_VERS }}.tar.xz" + tar -xvf PDCursesMod-${{ env.MINGW_PDCM_VERS }}.tar.xz + rem: consider inclusion of https://github.com/Bill-Gray/PDCursesMod/commit/45949000c3ac1375f5f821d72f46e4726a3a6a2f.patch + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && make -C wincon --jobs=$(($(nproc)+1)) INFOEX=N CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && make -C wingui --jobs=$(($(nproc)+1)) CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && make -C vt --jobs=$(($(nproc)+1)) CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll CFLAGS=\"-Wall -Wextra -pedantic -g -DPDCDEBUG -fPIC -DPDC_DLLbuild\"" + rem: only works this way on cmd + echo #define CHTYPE_64 > PDCursesMod-${{ env.MINGW_PDCM_VERS }}\pdcurses.h + echo #define PDC_DLLbuild >> PDCursesMod-${{ env.MINGW_PDCM_VERS }}\pdcurses.h + echo #include "pdcurses/curses.h" >> PDCursesMod-${{ env.MINGW_PDCM_VERS }}\pdcurses.h + + - name: Install PDCursesMod + run: | + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install wincon/libpdcurses.dll.a /mingw/lib/" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install wincon/libpdcurses.dll /mingw/bin/" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install wincon/libpdcurses.dll /mingw/bin/libpdcurses-wincon.dll" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install wingui/libpdcurses.dll /mingw/bin/libpdcurses-wingui.dll" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install vt/libpdcurses.dll /mingw/bin/libpdcurses-vt.dll" + bash -lc "install -d /mingw/include/pdcurses" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install -m 0644 curses.h panel.h term.h /mingw/include/pdcurses/" + bash -lc "cd PDCursesMod-${{ env.MINGW_PDCM_VERS }} && install -m 0644 pdcurses.h /mingw/include/" + + - name: Save PDCursesMod cache + if: steps.restore-pdcm.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + key: cache-msys-pdcm + path: PDCursesMod-${{ env.MINGW_PDCM_VERS }} + + + - name: get cJSON + run: | + curl -L https://raw.githubusercontent.com/DaveGamble/cJSON/v${{ env.MINGW_CJSON_VERS }}/cJSON.c -o .\libcob\cJSON.c + curl -L https://raw.githubusercontent.com/DaveGamble/cJSON/v${{ env.MINGW_CJSON_VERS }}/cJSON.h -o .\libcob\cJSON.h + + + # - name: Bootstrap GnuCOBOL + # run: | + # sed -i 's/AM_PROG_AR/m4_ifdef\(\[AM_PROG_AR\], \[AM_PROG_AR\]\)/g' .\configure.ac + # sed -i 's/po extras doc tests/po extras tests/g' .\Makefile.am + # bash -lc "./autogen.sh" + + + - name: Configure GnuCOBOL + shell: cmd + run: | + bash -lc "cd _build && ../configure %CFGOPT% --with-db --with-xml2 --with-json=local --with-curses=pdcurses --prefix=/mingw" + rem Note: GC4 may need CPPFLAGS="-I../libcob" for local cJSON + + - name: Build GnuCOBOL + shell: cmd + run: | + bash -lc "CPATH=$(pwd) make -C _build --jobs=$(($(nproc)+1))" + rem Note: the extra CPATH above is only required in debug builds (otherwise gcc invoked from cobc does not find libcob.h [pre-inst-env]), for some reason... + + - name: Upload config-${{ matrix.target }}.log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: config-${{ matrix.target }}.log + path: _build/config.log + + - name: Cache newcob.val + uses: actions/cache@v4 + with: + path: _build/tests/cobol85/newcob.val + key: newcob-val + save-always: true + enableCrossOsArchive: true + + - name: Run NIST85 testsuite + # if we ever need to disable something in the tests: skip like here IF106A + # and later expect a failure + # perl -pi -e 's/^# OBNC1M/\$skip{IF106A} = 1; # OBNC1M/' tests/cobol85/report.pl + # bash -lc "CPATH=$(pwd) make -C _build/tests test --jobs=$(($(nproc)+1)) || echo \"WARNING: NIST85 did not pass!\"" + shell: cmd + run: | + bash -lc "CPATH=$(pwd) make -C _build/tests test --jobs=$(($(nproc)+1))" + rem Note: the extra CPATH above is only required in debug builds (otherwise gcc invoked from cobc does not find libcob.h [atlocal]), for some reason... + + - name: Upload NIST85 Test Suite results + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: NIST85 results on ${{ matrix.target }} + path: | + _build/tests/cobol85/summary.* + _build/tests/cobol85/**/*.log + _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt + + - name: Run testsuite + shell: cmd + run: | + rem skip test as it sometimes works and sometimes not... + rem instead of + rem sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/used_binaries.at + rem use + bash -lc "sed -i '/used_binaries/{N;/temporary path invalid/{N;N;N;N;s/traceon/traceon; echo \"workflow:1\">\"$at_check_line_file\"; at_fn_check_skip 77/;}}' tests/testsuite" + + rem change to expected fail if there's an error specific to the CI that we don't want to change + rem in the testsuite for expected result (should normally only be a temporary thing) + rem instead of + rem sed -i '/AT_SETUP(\[Compare FLOAT-LONG with floating-point literal\])/a AT_XFAIL_IF(\[true\])' tests/testsuite.src/run_fundamental.at + rem use + rem sed -i '/run_fundamental/{N;/Compare FLOAT-LONG with floating-point literal/{N;s/at_xfail=no/at_xfail=yes/;}}' tests/testsuite + + rem to work around regular hangs we run NIST first, then the internal + rem and the later only with 2 jobs + bash -lc "CPATH=$(pwd) make -C _build/tests check TESTSUITEFLAGS=\"--jobs=2\"" + rem Note: the extra CPATH above is only required in debug builds (otherwise gcc invoked from cobc does not find libcob.h [atlocal]), for some reason... + + - name: Upload testsuite-${{ matrix.target }}.log + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: testsuite-${{ matrix.target }}.log + path: _build/tests/testsuite.log + + - name: Package GnuCOBOL MinGW nightly + run: | + bash -lc "make -C _build distmingw" + + - name: Upload GnuCOBOL_mingw-${{ matrix.target }} + uses: actions/upload-artifact@v4 + with: + name: GnuCOBOL_mingw-${{ matrix.target }} + path: _build/${{ env.DISTDIR }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7115b1f94..28ccbce6b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -22,7 +22,6 @@ jobs: - name: Configure git run: git config --global core.symlinks false - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Checkout code uses: actions/checkout@v4 @@ -57,6 +56,10 @@ jobs: --enable-hardening \ --prefix /opt/cobol/gnucobol-gcos \ + - name: make + run: | + make -C _build --jobs=$((${NPROC}+1)) + - name: Upload config.log uses: actions/upload-artifact@v4 with: @@ -64,10 +67,6 @@ jobs: path: _build/config.log if: failure() - - name: make - run: | - make -C _build --jobs=$((${NPROC}+1)) - # make install must be done before make check, otherwise # execution of generated COBOL files fail for a missing # /usr/local/lib/libcob.dylib @@ -89,7 +88,7 @@ jobs: - name: Upload testsuite.log uses: actions/upload-artifact@v4 - if: failure() + if: ${{ ! cancelled() }} #-> always upload as build result documentation with: name: testsuite-${{ matrix.os }}.log path: _build/tests/testsuite.log @@ -102,7 +101,22 @@ jobs: save-always: true enableCrossOsArchive: true - - name: NIST85 Test Suite +# - name: NIST85 Test Suite +# run: | +# make -C _build/tests/cobol85 EXEC85 test \ +# --jobs=$((${NPROC}+1)) + + - name: Run NIST85 testsuite run: | - make -C _build/tests/cobol85 EXEC85 test \ - --jobs=$((${NPROC}+1)) + make -C _build/tests test --jobs=$((${NPROC}+1)) + + - name: Upload NIST85 Test Suite results + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: NIST85 results on ${{ matrix.os }} + path: | + _build/tests/cobol85/summary.* + _build/tests/cobol85/**/*.log + _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml deleted file mode 100644 index 1a3df6462..000000000 --- a/.github/workflows/ubuntu.yml +++ /dev/null @@ -1,310 +0,0 @@ -name: Ubuntu Workflow - -on: - - pull_request: - branches: [ gcos4gnucobol-3.x ] - push: - # manual run in actions tab - for all branches - workflow_dispatch: - - -jobs: - - build: - name: Build, test and provide nightly - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest] - runs-on: ${{ matrix.os }} - - steps: - - name: Install packages - run: | - sudo apt-get update - sudo apt-get install automake libtool libdb5.3-dev libxml2-dev libcjson-dev \ - bison flex help2man gettext texlive - - - name: Set git user - run: | - git config --global user.name github-actions - git config --global user.email github-actions-bot@users.noreply.github.com - - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - name: Checkout code - uses: actions/checkout@v4 - - - name: Bootstrap - run: | - ./build_aux/bootstrap - - # FIXME: With TERM="dumb" `make check` fails with: - # ... - # 571: ACCEPT OMITTED (SCREEN) FAILED (run_accept.at:307) - # ... - # 693: ON EXCEPTION clause of DISPLAY FAILED (run_misc.at:6335) - # 695: LINE/COLUMN 0 exceptions FAILED (run_misc.at:6414) - # 694: EC-SCREEN-LINE-NUMBER and -STARTING-COLUMN FAILED (run_misc.at:6376) - # ... - # Failure cases read: "Error opening terminal: unknown." on - # stderr, and exit with code 1. - # - # Another alternative is passing `--with-curses=no` to the - # configure script, yet distcheck does call configure too... - # - - name: Build environment setup - run: | - mkdir _build - export TERM="vt100" - echo "TERM=$TERM" >> $GITHUB_ENV - echo "INSTALL_PATH=$(pwd)/_install" >> $GITHUB_ENV - - - name: Configure - run: | - cd _build - ../configure --enable-cobc-internal-checks \ - --enable-hardening \ - --prefix ${INSTALL_PATH} - echo "VERSION=PACKAGE_VERSION" | cpp -P -imacros config.h | tr -d \" \ - >> $GITHUB_ENV - - - name: Upload config.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: config-${{ matrix.os }}-${{ github.job }}.log - path: _build/config.log - - - name: Build - run: | - make -C _build --jobs=$(($(nproc)+1)) - - # note: distcheck also creates the dist tarball - - name: Build distribution archive & run tests - run: | - make -C _build distcheck \ - TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" \ - --jobs=$(($(nproc)+1)) || \ - make -C _build/gnucobol-$VERSION/_build/sub/tests check \ - TESTSUITEFLAGS="--recheck --verbose" - - - name: Upload testsuite.log - uses: actions/upload-artifact@v4 - if: failure() - with: - # Assume there's only one directory matching `_build/gnucobol-*`: - name: testsuite-${{ matrix.os }}-${{ github.job }}.log - path: _build/gnucobol-${{ env.VERSION }}/_build/sub/tests/testsuite.log - - - name: Upload dist tarball - uses: actions/upload-artifact@v4 - with: - name: gnucobol-ci source distribution - path: _build/gnucobol*.tar* - if-no-files-found: error - retention-days: 0 - - - name: Cache newcob.val - uses: actions/cache@v4 - with: - path: _build/tests/cobol85/newcob.val - key: newcob-val - save-always: true - enableCrossOsArchive: true - - - name: NIST85 Test Suite - run: | - make -C _build/tests/cobol85 EXEC85 test \ - --jobs=$(($(nproc)+1)) - - - name: Upload NIST85 Test Suite results - uses: actions/upload-artifact@v4 - with: - name: NIST85 results on ${{ matrix.os }}-${{ github.job }} - path: | - _build/tests/cobol85/summary.* - _build/tests/cobol85/**/*.log - _build/tests/cobol85/**/*.out - _build/tests/cobol85/**/duration.txt - - minmal_build: - name: Build and test with minimal dependencies - strategy: - fail-fast: true - matrix: - os: [ubuntu-latest] - needs: build - runs-on: ${{ matrix.os }} - - steps: - - - name: Install packages - run: | - sudo apt-get update - sudo apt-get install build-essential libgmp-dev - - - name: Get CI dist tarball - uses: actions/download-artifact@v4 - with: - name: gnucobol-ci source distribution - - - name: Build environment setup - run: | - tar -xvf gnucobol*.tar.* --strip-components=1 - mkdir _build - - - name: Configure - run: | - cd _build - ../configure --disable-dependency-tracking \ - --without-db --without-curses \ - --without-xml2 --without-json \ - --without-iconv --disable-nls - - - name: Upload config.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: config-${{ matrix.os }}-${{ github.job }}.log - path: _build/config.log - - - name: Build - run: | - make -C _build --jobs=$(($(nproc)+1)) - - - name: run internal tests - run: | - make -C _build check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || \ - make -C _build check TESTSUITEFLAGS="--recheck --verbose" - - - name: Upload testsuite.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: testsuite-${{ matrix.os }}-${{ github.job }}.log - path: _build/tests/testsuite.log - - - name: Cache newcob.val - uses: actions/cache@v4 - with: - path: _build/tests/cobol85/newcob.val - key: newcob-val - save-always: true - enableCrossOsArchive: true - - - name: NIST85 Test Suite - run: | - make -C _build/tests/cobol85 EXEC85 test \ - --jobs=$(($(nproc)+1)) - - - name: Upload NIST85 Test Suite results - uses: actions/upload-artifact@v4 - with: - name: NIST85 results on ${{ matrix.os }}-${{ github.job }} - path: | - _build/tests/cobol85/summary.* - _build/tests/cobol85/**/*.log - _build/tests/cobol85/**/*.out - _build/tests/cobol85/**/duration.txt - - - coverage: - name: Coverage and Warnings - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - # note: less dependencies as we don't generate a dist tarball, one additional for lcov - - name: Install dependencies - run: | - sudo apt-get install automake libtool libdb5.3-dev libxml2-dev \ - libcjson-dev bison flex help2man gettext lcov - - - name: Bootstrap - run: | - ./build_aux/bootstrap - - - name: Build environment setup - run: | - mkdir _build - export TERM="vt100" - echo "TERM=$TERM" >> $GITHUB_ENV - - # note: add additional C compiler syntax checks here to not need - # _another_ CI run - # - # TODO: try and pass -pedantic via CPPFLAGS - - name: Configure - run: | - cd _build - ../configure --enable-code-coverage \ - CPPFLAGS="-Werror=declaration-after-statement" \ - CC="gcc -std=c89" - - - name: Upload config.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: config-${{ matrix.os }}-${{ github.job }}.log - path: _build/config.log - - - name: Build - run: | - make -C _build --jobs=$(($(nproc)+1)) - - - name: Coverage - run: | - # make -C _build check-code-coverage # <- (ignores errors) - make -C _build check \ - TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" - make -C _build code-coverage-capture \ - CODE_COVERAGE_DIRECTORY="$(realpath .)/_build" - - - name: Upload testsuite.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: testsuite-${{ matrix.os }}-${{ github.job }}.log - path: _build/tests/testsuite.log - - - name: Upload coverage report - uses: actions/upload-artifact@v4 - with: - name: coverage - path: _build/GnuCOBOL-**-coverage - - - name: Cache newcob.val - uses: actions/cache@v4 - with: - path: _build/tests/cobol85/newcob.val - key: newcob-val - save-always: true - enableCrossOsArchive: true - - - name: Extended coverage - run: | - make -C _build/tests/cobol85 EXEC85 test \ - --jobs=$(($(nproc)+1)) \ - --keep-going - make -C _build code-coverage-capture \ - CODE_COVERAGE_OUTPUT_DIRECTORY=extended-coverage \ - CODE_COVERAGE_OUTPUT_FILE=extended-coverage.info \ - CODE_COVERAGE_DIRECTORY="$(realpath .)/_build" - - - name: Upload extended coverage report - uses: actions/upload-artifact@v4 - with: - name: extended-coverage - path: _build/extended-coverage - - - name: Upload coverage to codecov - uses: codecov/codecov-action@v2 - with: - # token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos - directory: _build - # Shall fail until we have a working account on codecov.io - fail_ci_if_error: false # optional (default = false) - verbose: true # optional (default = false) diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml index b748e62d6..03211301c 100644 --- a/.github/workflows/windows-msvc.yml +++ b/.github/workflows/windows-msvc.yml @@ -33,15 +33,13 @@ jobs: strategy: fail-fast: false matrix: - os: - - windows-latest arch: - x86 - x64 target: - Debug - Release - runs-on: ${{ matrix.os }} + runs-on: windows-latest timeout-minutes: 45 steps: @@ -57,12 +55,12 @@ jobs: - name: Setup environment shell: pwsh run: | - echo GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV + echo GITHUB_WORKSPACE=${{ env.GITHUB_WORKSPACE }} >> $env:GITHUB_ENV If ("${{ matrix.arch }}" -eq "x86") { echo VCVARS=$env:VCVARS32 >> $env:GITHUB_ENV echo VCPKGS=$env:VCPKGS32 >> $env:GITHUB_ENV echo ARCHDIR=Win32 >> $env:GITHUB_ENV - } Else { + } else { echo VCVARS=$env:VCVARS64 >> $env:GITHUB_ENV echo VCPKGS=$env:VCPKGS64 >> $env:GITHUB_ENV echo ARCHDIR=x64 >> $env:GITHUB_ENV @@ -78,24 +76,24 @@ jobs: ${{ env.VCPKG_ROOT }}/packages - name: Bootstrap VCPKG - if: steps.restore-vcpkg.outputs.cache-hit != 'true' run: | - cd /d %VCPKG_ROOT% - vcpkg update + cd /d ${{ env.VCPKG_ROOT }} git pull cmd /C .\bootstrap-vcpkg.bat -disableMetrics + vcpkg update - name: Integrate VCPKG run: | + cd /d ${{ env.VCPKG_ROOT }} vcpkg integrate install - name: Install VCPKG packages if: steps.restore-vcpkg.outputs.cache-hit != 'true' run: | + cd /d ${{ env.VCPKG_ROOT }} vcpkg install %VCPKGS% - name: Save VCPKG cache - if: steps.restore-vcpkg.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: key: cache-vcpkg-${{ matrix.arch }}-${{ matrix.target }} @@ -108,7 +106,7 @@ jobs: id: restore-flexbison with: key: cache-flexbison-${{ matrix.arch }}-${{ matrix.target }} - path: ${{ env.GITHUB_WORKSPACE }}/flexbison + path: flexbison - name: Install WinFlexBison if: steps.restore-flexbison.outputs.cache-hit != 'true' @@ -122,30 +120,30 @@ jobs: uses: actions/cache/save@v4 with: key: cache-flexbison-${{ matrix.arch }}-${{ matrix.target }} - path: ${{ env.GITHUB_WORKSPACE }}/flexbison + path: flexbison - name: Configure GnuCOBOL shell: pwsh run: | cd build_windows - Get-Content -Path 'config.h.in' | ForEach-Object { $_ ` + (('#define COB_MAIN_DIR "' + $env:GITHUB_WORKSPACE + '"') -replace '\\', '\\') + "`r`n" + ` + ((Get-Content -Path 'config.h.in' | ForEach-Object { $_ ` -replace '(#define\s+CONFIGURED_ISAM)\s.+$', '$1 BDB' ` -replace '(#define\s+CONFIGURED_CURSES)\s.+$', '$1 PDCURSES' ` -replace '(#define\s+CONFIGURED_XML)\s.+$', '$1 XML2' ` -replace '(#define\s+CONFIGURED_JSON)\s.+$', '$1 CJSON_CJSON' ` - } | Set-Content -Path 'config.h' + -replace '"\(" PACKAGE_NAME "\) "', '"(GnuCOBOL-CI ${{ matrix.target }}) "' ` + }) -join "`r`n" ) | Set-Content -Path 'config.h' & .\maketarstamp.ps1 > tarstamp.h - name: Generate parser run: | - cd build_windows set PATH=%GITHUB_WORKSPACE%\flexbison;%PATH% - cmd /C .\makebisonflex.cmd <NUL + cmd /C build_windows\makebisonflex.cmd <NUL - name: Build GnuCOBOL run: | cd build_windows - set CL=/DCOB_MAIN_DIR=\"%GITHUB_WORKSPACE:\=\\%\" "%MSBUILD%" .\vs2019\GnuCOBOL.sln /m /p:Platform=${{ matrix.arch }} /p:Configuration=${{ matrix.target }} - name: Install MSYS2 packages @@ -153,26 +151,6 @@ jobs: run: | pacman --needed --noconfirm -S $MSYSPKGS - - name: Adjust testsuite - shell: C:\shells\msys2bash.cmd {0} - run: | - cd tests - sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_misc.at - - # Skip two tests that behave differently (fail or hand) 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: | - cd tests - sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' testsuite.src/run_extensions.at - sed -i '/AT_SETUP(\[PROGRAM COLLATING SEQUENCE\])/a AT_SKIP_IF(\[true\])' testsuite.src/syn_definition.at - - name: Build testsuite shell: C:\shells\msys2bash.cmd {0} run: | @@ -194,30 +172,63 @@ jobs: sed 's/x64\/Debug/${{ env.ARCHDIR }}\/${{ matrix.target }}/g' atlocal_win > atlocal autom4te --lang=autotest -I ./testsuite.src ./testsuite.at -o ./testsuite + - name: Adjust testsuite + shell: C:\shells\msys2bash.cmd {0} + run: | + # 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 + # - 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: | - cd tests - set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" + set CL=/I "${{ env.VCPKG_ROOT }}\installed\${{ matrix.arch }}-windows\include" call "%VCVARS%" set MSYS2_PATH_TYPE=inherit + cd tests C:\shells\msys2bash.cmd -c "./testsuite || ./testsuite --recheck --verbose" - name: Upload testsuite-${{ matrix.arch }}-${{ matrix.target }}.log uses: actions/upload-artifact@v4 - if: failure() + if: ${{ ! cancelled() }} #-> always upload as build result documentation with: name: testsuite-${{ matrix.arch }}-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/tests/testsuite.log - - # - name: Package GnuCOBOL - # run: | - # cd build_windows - # set CL=/I "%VCPKG_ROOT%\installed\${{ matrix.arch }}-windows\include" - # call "%VCVARS%" - # cmd /C .\makedist.cmd <NUL - - # - name: Upload distribution - # uses: actions/upload-artifact@v4 - # with: - # name: GnuCOBOL_3.3-dev_${{ matrix.arch }}-${{ matrix.target }}.7z - # path: ${{ env.GITHUB_WORKSPACE }}/GnuCOBOL_3.3-dev_vs_bin.7z + path: tests/testsuite.log + + - name: Package GnuCOBOL and dependencies + run: | + echo exporting dependencies + vcpkg.exe export %VCPKGS% --raw + pushd C:\vcpkg\vcpkg-export-* + set VCPKG_EXPORT_DIR=%CD% + popd + + echo wrap up dependencies for separate download + 7z.exe a -r -mx=9 dependencies-${{ matrix.arch }}.7z "%VCPKG_EXPORT_DIR%" + + echo wrap up GnuCBOBOL binary package + rem set CL= + cmd /C build_windows\makedist.cmd ${{ matrix.target }} <NUL + + - name: Upload dependencies + uses: actions/upload-artifact@v4 + with: + name: VCPKG ${{ matrix.arch }}-${{ matrix.target }} dependencies + path: dependencies-${{ matrix.arch }}.7z + + - name: Upload distribution + uses: actions/upload-artifact@v4 + with: + name: GnuCOBOL bin ${{ matrix.arch }}-${{ matrix.target }} + path: build_windows/GnuCOBOL_*.7z diff --git a/.github/workflows/windows-msys1.yml b/.github/workflows/windows-msys1.yml deleted file mode 100644 index 67f3801c6..000000000 --- a/.github/workflows/windows-msys1.yml +++ /dev/null @@ -1,245 +0,0 @@ -name: Windows MSYS1 Workflow - -on: - pull_request: - branches: [ gcos4gnucobol-3.x ] - push: - # manual run in actions tab - for all branches - workflow_dispatch: - -env: - MSYS_ROOT: C:\MinGW - MSYS_BIN: C:\MinGW\msys\1.0\bin - BISON_PKGDATADIR: C:\MinGW\share\bison - - M4: m4 - - MSYSTEM: MINGW32 - MSYSPKGS: msys-m4 msys-flex msys-coreutils msys-help2man - - MINGW_BISON_VERS: bison-3.0.1 - MINGW_GMP_VERS: gmp-6.3.0 - MINGW_BDB_VERS: db-6.0.19.NC - MINGW_PDCM_VERS: 4.4.0 - MINGW_CJSON_VERS: 1.7.18 - MINGW_XML2_VERS: 2.8.0 - -defaults: - run: - shell: cmd - -jobs: - build: - strategy: - fail-fast: false - matrix: - os: - - windows-latest - arch: - - x86 - target: - - debug - - release - runs-on: ${{ matrix.os }} - timeout-minutes: 45 - - steps: - - - name: Set git user - run: | - git config --global user.name github-actions - git config --global user.email github-actions-bot@users.noreply.github.com - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup environment - shell: pwsh - run: | - echo GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV - echo HOME=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV - echo PATH="$env:MSYS_BIN;$env:PATH" >> $env:GITHUB_ENV - If ("${{ matrix.target }}" -eq "release") { - echo DISTDIR=GnuCOBOL_mingw >> $env:GITHUB_ENV - echo CFGOPT= >> $env:GITHUB_ENV - } Else { - echo DISTDIR=GnuCOBOL_mingw_dbg >> $env:GITHUB_ENV - echo CFGOPT="--enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV - } - - - name: Restore MSYS1 cache - id: restore-msys - uses: actions/cache/restore@v4 - with: - key: cache-msys-${{ matrix.target }} - path: ${{ env.MSYS_ROOT }} - - - name: Install MSYS1 - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - curl -O https://www.arnoldtrembley.com/MinGW-bkup02.7z - 7z x MinGW-bkup02.7z -o%MSYS_ROOT%\ - - - name: Install MSYS1 packages - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - bash -lc "mingw-get install %MSYSPKGS%" - - - name: Install Bison 3.0 - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - curl -L https://mirror.ibcp.fr/pub/gnu/bison/%MINGW_BISON_VERS%.tar.xz -o %MINGW_BISON_VERS%.tar.xz - tar -xvf %MINGW_BISON_VERS%.tar.xz - bash -lc "cd %MINGW_BISON_VERS% && ./configure --prefix=/mingw && make" - bash -lc "cd %MINGW_BISON_VERS% && make install" - - # Note: actually unavailable, so skip (works with the GMP alredy provided) - # - name: Install GMP - # if: steps.restore-msys.outputs.cache-hit != 'true' - # run: | - # curl -L https://gmplib.org/download/gmp/%MINGW_GMP_VERS%.tar.xz -o %MINGW_GMP_VERS%.tar.xz - # tar -xvf %MINGW_GMP_VERS%.tar.xz - # bash -lc "cd %MINGW_GMP_VERS% && ./configure --prefix=/mingw --enable-fat --enable-shared --disable-static CFLAGS=\"-Wno-attributes -Wno-ignored-attributes\" ABI=32 && make" - # bash -lc "cd %MINGW_GMP_VERS% && make install" - - - name: Install BDB - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - curl -L https://download.oracle.com/berkeley-db/%MINGW_BDB_VERS%.tar.gz -o %MINGW_BDB_VERS%.tar.gz - tar -xvf %MINGW_BDB_VERS%.tar.gz - sed -i 's/_tcsclen/strlen/' %MINGW_BDB_VERS%\src\os_windows\os_stat.c - bash -lc "cd %MINGW_BDB_VERS%/build_unix && ../dist/configure --prefix=/mingw --enable-mingw --enable-debug --disable-static --disable-replication --disable-tcl LIBCSO_LIBS=-lwsock32 && make || make" - bash -lc "cd %MINGW_BDB_VERS%/build_unix && make install" - - - name: Install PDCurses - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - curl -L https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v%MINGW_PDCM_VERS%.tar.gz -o "PDCursesMod-%MINGW_PDCM_VERS%.tar.xz" - tar -xvf PDCursesMod-%MINGW_PDCM_VERS%.tar.xz - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS%\wincon && make INFOEX=N CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS%\wingui && make CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS%\vt && make CHTYPE_64=Y DEBUG=Y DLL=Y DLLNAME=libpdcurses LIBNAME=libpdcurses.dll CFLAGS=\"-Wall -Wextra -pedantic -g -DPDCDEBUG -fPIC -DPDC_DLL_BUILD\"" - echo #define CHTYPE_64 > PDCursesMod-%MINGW_PDCM_VERS%\pdcurses.h - echo #define PDC_DLL_BUILD >> PDCursesMod-%MINGW_PDCM_VERS%\pdcurses.h - echo #include "pdcurses/curses.h" >> PDCursesMod-%MINGW_PDCM_VERS%\pdcurses.h - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wincon/libpdcurses.dll.a /mingw/lib/" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wincon/libpdcurses.dll /mingw/bin/" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wincon/libpdcurses.dll /mingw/bin/libpdcurses-wincon.dll" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install wingui/libpdcurses.dll /mingw/bin/libpdcurses-wingui.dll" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install vt/libpdcurses.dll /mingw/bin/libpdcurses-vt.dll" - bash -lc "install -d /mingw/include/pdcurses" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install -m 0644 curses.h panel.h term.h /mingw/include/pdcurses/" - bash -lc "cd PDCursesMod-%MINGW_PDCM_VERS% && install -m 0644 pdcurses.h /mingw/include/" - - - name: Install LibXML2 - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - curl -L https://github.com/GNOME/libxml2/archive/refs/tags/v%MINGW_XML2_VERS%.tar.gz -o libxml2-%MINGW_XML2_VERS%.tar.xz - tar -xvf libxml2-%MINGW_XML2_VERS%.tar.xz - bash -lc "cd libxml2-%MINGW_XML2_VERS% && ./autogen.sh" - bash -lc "cd libxml2-%MINGW_XML2_VERS% && ./configure --prefix=/mingw && make" - bash -lc "cd libxml2-%MINGW_XML2_VERS% && make install" - - - name: Cleanup MSYS1 env - if: steps.restore-msys.outputs.cache-hit != 'true' - run: | - rmdir /Q /S %MSYS_ROOT%\docs - rmdir /Q /S %MSYS_ROOT%\var - del /Q %MSYS_ROOT%\bin\gdb.exe - - - name: Save MSYS1 cache - if: steps.restore-msys.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: cache-msys-${{ matrix.target }} - path: ${{ env.MSYS_ROOT }} - - - name: Download CJSON sources - run: | - curl -L https://github.com/DaveGamble/cJSON/archive/refs/tags/v%MINGW_CJSON_VERS%.tar.gz -o cjson-%MINGW_CJSON_VERS%.tar.xz - tar -xvf cjson-%MINGW_CJSON_VERS%.tar.xz - copy cjson-%MINGW_CJSON_VERS%\cJSON.* .\libcob - - - name: Bootstrap GnuCOBOL - run: | - sed -i 's/AM_PROG_AR/m4_ifdef\(\[AM_PROG_AR\], \[AM_PROG_AR\]\)/g' .\configure.ac - sed -i 's/po extras doc tests/po extras tests/g' .\Makefile.am - bash -lc "./autogen.sh" - - - name: Configure GnuCOBOL - run: | - mkdir _build - sed -i 'N;s/else/else :;/g' .\configure - sed -i 's/\} else \:;/} else/g' .\configure - sed -i 's/#else \:;/#else/g' .\configure - bash -lc "cd _build && CFLAGS=\"-I ../libcob\" ../configure %CFGOPT% --with-db --prefix=/opt/cobol/gnucobol" - - - name: Upload config-${{ matrix.target }}.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: config-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/config.log - - - name: Build GnuCOBOL - run: | - bash -lc "cd _build && CPATH=$(pwd)/.. make --jobs=$(($(nproc)+1))" - -# Note: the extra CPATH above is only required in debug builds, for some reason... - - - name: Install GnuCOBOL - run: | - bash -lc "cd _build && make install" - bash -lc "cd _build && find /opt/cobol > install.log" - - - name: Upload install-${{ matrix.target }}.log - uses: actions/upload-artifact@v4 - with: - name: install-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/install.log - - - name: Run testsuite - run: | - sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/used_binaries.at - - sed -i '/AT_SETUP(\[Compare FLOAT-LONG with floating-point literal\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[Numeric operations (3) PACKED-DECIMAL\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[Numeric operations (7)\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[integer arithmetic on floating-point var\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_fundamental.at - sed -i '/AT_SETUP(\[FLOAT-DECIMAL w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[FLOAT-SHORT \/ FLOAT-LONG w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[FLOAT-LONG with SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_misc.at - sed -i '/AT_SETUP(\[FUNCTION ANNUITY\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[FUNCTION INTEGER\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[FUNCTION MOD (valid)\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[FUNCTION SECONDS-FROM-FORMATTED-TIME\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_functions.at - sed -i '/AT_SETUP(\[GCOS floating-point usages\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/run_extensions.at - sed -i '/AT_SETUP(\[BINARY: 64bit unsigned arithmetic notrunc\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_binary.at - sed -i '/AT_SETUP(\[DISPLAY: ADD and SUBTRACT w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_display.at - sed -i '/AT_SETUP(\[DISPLAY: ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_display.at - sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT w\/o SIZE ERROR\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_packed.at - sed -i '/AT_SETUP(\[BCD ADD and SUBTRACT, all ROUNDED MODEs\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/data_packed.at - - bash -lc "cd _build/tests && CPATH=/opt/cobol/gnucobol/include make check TESTSUITEFLAGS=\"--jobs=$(($(nproc)+1))\"" - -# Note: the extra CPATH above is only required in debug builds, for some reason... - -# The NIST testsuite hangs forever in IF -# bash -lc "CPATH=/opt/cobol/gnucobol/include make test" - - - name: Upload testsuite-${{ matrix.target }}.log - uses: actions/upload-artifact@v4 - if: failure() - with: - name: testsuite-${{ matrix.target }}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log - - - name: Package GnuCOBOL - run: | - bash -lc "cd _build && make distmingw" - - - name: Upload GnuCOBOL_mingw-${{ matrix.target }} - uses: actions/upload-artifact@v4 - with: - name: GnuCOBOL_mingw-${{ matrix.target }} - path: ${{ env.GITHUB_WORKSPACE }}/_build/${{ env.DISTDIR }} diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index 59ba117b5..689a489b1 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -8,18 +8,9 @@ on: workflow_dispatch: jobs: - build: - strategy: - fail-fast: false - matrix: - include: - - { os: windows-latest, target: release, sys: mingw64, env: x86_64 } - - { os: windows-latest, target: debug, sys: mingw64, env: x86_64 } - - { os: windows-latest, target: debug, sys: ucrt64, env: ucrt-x86_64 } - - { os: windows-latest, target: debug, sys: clang64, env: clang-x86_64 } - # - { target: debug, sys: mingw32, env: i686 } - runs-on: ${{matrix.os}} - timeout-minutes: 45 + prepare: + runs-on: windows-latest + timeout-minutes: 30 steps: @@ -31,54 +22,127 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Setup environment + - name: Install packages + uses: msys2/setup-msys2@v2 + with: + update: true + msystem: mingw64 + install: autoconf automake libtool make flex bison help2man texinfo texinfo-tex + mingw-w64-x86_64-cc + mingw-w64-x86_64-gmp mingw-w64-x86_64-texlive-core + mingw-w64-x86_64-gettext-runtime gettext-devel + + - name: Bootstrap GnuCOBOL + shell: msys2 {0} run: | - echo GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE >> $env:GITHUB_ENV - If ("${{ matrix.target }}" -eq "release") { + ./build_aux/bootstrap install + + - name: Configure GnuCOBOL + shell: msys2 {0} + run: | + mkdir _build + cd _build + ../configure --without-db --without-curses --without-xml2 --without-json + + - name: Build GnuCOBOL Source Distribution + shell: msys2 {0} + run: | + make -C _build --jobs=$(($(nproc)+1)) + make -C _build --jobs=$(($(nproc)+1)) dist + + - name: Upload config-dist.log + uses: actions/upload-artifact@v4 + if: ${{ ! cancelled() }} #-> always upload as build result documentation + with: + name: config-dist.log + path: _build/config.log + + - name: Upload dist tarball + uses: actions/upload-artifact@v4 + with: + name: gnucobol-ci source distribution msys2 + path: _build/gnucobol*.tar.gz + if-no-files-found: error + retention-days: 1 + + build: + strategy: + fail-fast: false + matrix: + include: + - { target: release, sys: mingw64, env: x86_64 } + - { target: debug, sys: mingw64, env: x86_64 } + - { target: release, sys: ucrt64, env: ucrt-x86_64 } + - { target: release, sys: clang64, env: clang-x86_64 } + - { target: release, sys: mingw32, env: i686 } + runs-on: windows-latest + needs: prepare + timeout-minutes: 45 + + steps: + + - name: Build environment setup + run: | + if ("${{ matrix.target }}" -eq "release") { echo DISTDIR=GnuCOBOL_mingw >> $env:GITHUB_ENV - echo CFGOPT= >> $env:GITHUB_ENV - } Else { + echo CFGOPT="--with-pkgversion=GnuCOBOL-CI-MSYS2" >> $env:GITHUB_ENV + } else { echo DISTDIR=GnuCOBOL_mingw_dbg >> $env:GITHUB_ENV - echo CFGOPT="--enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV + echo CFGOPT="--with-pkgversion=GnuCOBOL-CI-MSYS2-debug --enable-debug --enable-cobc-internal-checks --enable-hardening" >> $env:GITHUB_ENV + } + # Common options (dependencies) + echo CFGOPT="$env:CFGOPT --with-math=gmp --with-curses=ncursesw --with-xml2 --with-json=json-c" >> $env:GITHUB_ENV + # Conditional inclusion of --with-db (MSYS2 does not provide 32bit builds for BDB any more) + if ("${{ matrix.sys }}" -ne "mingw32") { + echo CFGOPT="$env:CFGOPT --with-db" >> $env:GITHUB_ENV + } else { + echo CFGOPT="$env:CFGOPT --without-db" >> $env:GITHUB_ENV } - - name: Install packages + - name: Update and install packages uses: msys2/setup-msys2@v2 with: update: true msystem: ${{matrix.sys}} - install: autoconf automake libtool make flex bison help2man texinfo + install: make diffutils mingw-w64-${{matrix.env}}-cc - mingw-w64-${{matrix.env}}-gmp gmp-devel - mingw-w64-${{matrix.env}}-gettext-runtime gettext-devel + mingw-w64-${{matrix.env}}-gmp + mingw-w64-${{matrix.env}}-gettext-runtime mingw-w64-${{matrix.env}}-ncurses mingw-w64-${{matrix.env}}-libxml2 - mingw-w64-${{matrix.env}}-cjson - mingw-w64-${{matrix.env}}-db libdb-devel + mingw-w64-${{matrix.env}}-json-c - - name: Bootstrap GnuCOBOL - shell: msys2 {0} - run: | - ./build_aux/bootstrap install + - name: BDB package + uses: msys2/setup-msys2@v2 + if: matrix.sys != 'mingw32' # MSYS2 does not provide 32bit builds for it any more + with: + msystem: ${{matrix.sys}} + install: mingw-w64-${{matrix.env}}-db + + - name: Get CI dist tarball + uses: actions/download-artifact@v4 + with: + name: gnucobol-ci source distribution msys2 - name: Configure GnuCOBOL shell: msys2 {0} run: | + tar -xvf gnucobol*.tar.* --strip-components=1 mkdir _build cd _build - ../configure $CFGOPT --with-db --prefix=/opt/cobol/gnucobol + ../configure $CFGOPT + + - name: Build GnuCOBOL + shell: msys2 {0} + run: | + make -C _build --jobs=$(($(nproc)+1)) - name: Upload config-${{matrix.sys}}-${{matrix.target}}.log uses: actions/upload-artifact@v4 if: failure() with: name: config-${{matrix.sys}}-${{matrix.target}}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/config.log - - - name: Build GnuCOBOL - shell: msys2 {0} - run: | - make -C _build --jobs=$(($(nproc)+1)) + path: _build/config.log - name: Cache newcob.val uses: actions/cache@v4 @@ -88,39 +152,53 @@ jobs: save-always: true enableCrossOsArchive: true + - name: Run NIST85 testsuite + shell: msys2 {0} + run: | + make -C _build/tests test --jobs=$(($(nproc)+1)) + + - name: Upload NIST85 Test Suite results + if: ${{ ! cancelled() }} #-> always upload as build result documentation + uses: actions/upload-artifact@v4 + with: + name: NIST85 results on ${{matrix.sys}}-${{ matrix.target }} + path: | + _build/tests/cobol85/summary.* + _build/tests/cobol85/**/*.log + _build/tests/cobol85/**/*.out + _build/tests/cobol85/**/duration.txt + - name: Run testuite shell: msys2 {0} run: | - sed '/AT_SETUP(\[temporary path invalid\])/a \ - AT_SKIP_IF(\[true\])' \ - -i tests/testsuite.src/used_binaries.at - make -C _build/tests checkall \ - --jobs=$(($(nproc)+1)) \ - TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || \ - make -C _build/tests check \ - TESTSUITEFLAGS="--recheck --verbose" + # skip test as it sometimes works and sometimes not... + # instead of + # sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' tests/testsuite.src/used_binaries.at + # use + sed -i '/used_binaries/{N;/temporary path invalid/{N;N;N;N;s/traceon/traceon; echo "workflow:1">"$at_check_line_file"; at_fn_check_skip 77/;}}' tests/testsuite + + # to work around regular hangs we run NIST first, then the internal + # and the later only with 2 jobs + # make -C _build/tests checkall TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || \ + make -C _build/tests check TESTSUITEFLAGS="--jobs=2" || \ + make -C _build/tests check TESTSUITEFLAGS="--recheck --verbose" - name: Upload testsuite-${{matrix.sys}}-${{matrix.target}}.log uses: actions/upload-artifact@v4 - if: failure() + if: ${{ ! cancelled() }} #-> always upload as build result documentation with: name: testsuite-${{matrix.sys}}-${{matrix.target}}.log - path: ${{ env.GITHUB_WORKSPACE }}/_build/tests/testsuite.log + path: _build/tests/testsuite.log - - name: Package GnuCOBOL + - name: Package GnuCOBOL MinGW nightly shell: msys2 {0} run: | make -C _build distmingw - - - name: Tar GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}} - shell: msys2 {0} - run: | - cd _build - tar -cvf ../GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar \ - "${{ env.DISTDIR }}" + tar -cvf GnuCOBOL_msys2-${{matrix.sys}}-${{matrix.target}}.tar \ + _build/"${{ env.DISTDIR }}" - name: Upload GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar uses: actions/upload-artifact@v4 with: - name: GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar - path: GnuCOBOL_mingw-${{matrix.sys}}-${{matrix.target}}.tar + name: GnuCOBOL_msys2-${{matrix.sys}}-${{matrix.target}}.tar + path: GnuCOBOL_msys2-${{matrix.sys}}-${{matrix.target}}.tar