diff --git a/.github/workflows/build_nightly.yml b/.github/workflows/build_nightly.yml
index cd48c7435..9ee69c078 100644
--- a/.github/workflows/build_nightly.yml
+++ b/.github/workflows/build_nightly.yml
@@ -872,22 +872,10 @@ jobs:
run: |
cd tests\testsuite.src
- rem Skip test as it sometimes works and sometimes not...
- rem sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' used_binaries.at
-
- rem The following 13 fail (identical to MSYS2)
+ rem The following 4 fail (identical to MSYS2)
sed -i '/AT_SETUP(\[Test dump feature (4)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[OUTPUT on INDEXED file to missing directory\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED undeclared keys\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[PIPE I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[STDOUT STDERR I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[LINE SEQUENTIAL one Record\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[SEQUENTIAL\/RELATIVE COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[LINE SEQUENTIAL COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[OPEN OUTPUT COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[MF io status (indexed)\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[Test MF Status (sequential)\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[LINE SEQUENTIAL\])/a AT_SKIP_IF(\[true\])' run_file.at
- name: Run testsuite
diff --git a/.github/workflows/ibm.yml b/.github/workflows/ibm.yml
index 1c26ef818..d606258c6 100644
--- a/.github/workflows/ibm.yml
+++ b/.github/workflows/ibm.yml
@@ -10,7 +10,7 @@ on:
jobs:
build:
runs-on: ${{ matrix.os }}
- timeout-minutes: 15 # usually around 6-10 minutes
+ timeout-minutes: 20 # usually around 6-10 minutes
strategy:
fail-fast: false
matrix:
diff --git a/.github/workflows/windows-msvc.yml b/.github/workflows/windows-msvc.yml
index 8e8f54cdf..dbca566cf 100644
--- a/.github/workflows/windows-msvc.yml
+++ b/.github/workflows/windows-msvc.yml
@@ -165,34 +165,13 @@ jobs:
# Depends on target-specific memory layout
sed -i '/AT_SETUP(\[runtime check: write to internal storage (1)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- # The following 22 fail in Release Mode
- sed -i '/AT_SETUP(\[Large BINARY, COMP-X\])/a AT_SKIP_IF(\[true\])' run_misc.at
+ # The following 4 fail in Release Mode
sed -i '/AT_SETUP(\[Test dump feature (4)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[C-API (3)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[C API Test JUST\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[Test COBOL-C interface\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[Test COBOL-C interface (2)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[OUTPUT on INDEXED file to missing directory\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED file SUPPRESS WHEN ALL + KEYCHECK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED undeclared keys\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[EXTFH: using ISAM callback\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[trace feature\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[trace feature with indexed EXTFH\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[trace feature with subroutine\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[PIPE I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[STDOUT STDERR I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[SEQUENTIAL\/RELATIVE COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[LINE SEQUENTIAL COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[OPEN OUTPUT COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[MF io status (indexed)\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[Test MF Status (sequential)\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[LINE SEQUENTIAL\])/a AT_SKIP_IF(\[true\])' run_file.at
- # The following 4 fail in Debug Mode
- sed -i '/AT_SETUP(\[C-API (field based)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[SEQUENTIAL basic I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[LINE SEQUENTIAL one Record\])/a AT_SKIP_IF(\[true\])' run_file.at
+ # The following 1 fail in Debug Mode
sed -i '/AT_SETUP(\[System routine CBL_GC_HOSTED\])/a AT_SKIP_IF(\[true\])' run_extensions.at
- name: Build testsuite
diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml
index 11a403c42..d48b29b66 100644
--- a/.github/workflows/windows-msys2.yml
+++ b/.github/workflows/windows-msys2.yml
@@ -150,7 +150,7 @@ jobs:
# command it provides, to workaround a diff bug under the MSYS2 CI ;
# this no longer seems necessary today
# PATH="$PATH:/c/Program Files/Git/usr/bin"
- ../configure $CFGOPT CFLAGS=-std=c17
+ ../configure $CFGOPT CFLAGS=-std=gnu17
- name: Upload config.log
if: ${{ !cancelled() }}
@@ -190,23 +190,10 @@ jobs:
run: |
cd tests/testsuite.src
- # Skip test as it sometimes works and sometimes not...
- # sed -i '/AT_SETUP(\[temporary path invalid\])/a AT_SKIP_IF(\[true\])' used_binaries.at
-
- # The following 13 fail (identical to MSYS1)
- # Note LINE SEQUENTIAL one Record works with the clang64 environment
+ # The following 4 fail (identical to MSYS1)
sed -i '/AT_SETUP(\[Test dump feature (4)\])/a AT_SKIP_IF(\[true\])' run_misc.at
- sed -i '/AT_SETUP(\[OUTPUT on INDEXED file to missing directory\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED undeclared keys\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[PIPE I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[STDOUT STDERR I\/O\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[LINE SEQUENTIAL one Record\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[INDEXED COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[SEQUENTIAL\/RELATIVE COMMIT\/ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[LINE SEQUENTIAL COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[OPEN OUTPUT COMMIT \/ ROLLBACK\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[MF io status (indexed)\])/a AT_SKIP_IF(\[true\])' run_file.at
- sed -i '/AT_SETUP(\[Test MF Status (sequential)\])/a AT_SKIP_IF(\[true\])' run_file.at
sed -i '/AT_SETUP(\[LINE SEQUENTIAL\])/a AT_SKIP_IF(\[true\])' run_file.at
- name: Run testsuite
diff --git a/TODO b/TODO
index dbdf1a446..7d2d6b9ae 100644
--- a/TODO
+++ b/TODO
@@ -234,6 +234,8 @@ https://sourceforge.net/p/gnucobol/code/HEAD/tree/external-doc/guide/
- Check the TODO about cb_default_byte in codegen.c:output_initialize
+- Check the TODO about having a single dialect option to change io stats (also for other dialects) in run_file.at:Test MF Status (sequential)
+
- Make status an enum instead of an int in fileio.c:cob_file_save_status as per TODO
- Move the IO status codes from common.h to fileio.h as per TODO
diff --git a/build_windows/vs2010/cobc.vcxproj b/build_windows/vs2010/cobc.vcxproj
index 3cbbb6e4c..848f80a0a 100644
--- a/build_windows/vs2010/cobc.vcxproj
+++ b/build_windows/vs2010/cobc.vcxproj
@@ -30,23 +30,27 @@
true
+ false
Application
+ true
Application
true
+ false
Windows7.1SDK
Application
+ true
Windows7.1SDK
diff --git a/build_windows/vs2010/cobcrun.vcxproj b/build_windows/vs2010/cobcrun.vcxproj
index 8e3852a65..6c01f236d 100644
--- a/build_windows/vs2010/cobcrun.vcxproj
+++ b/build_windows/vs2010/cobcrun.vcxproj
@@ -30,23 +30,27 @@
true
+ false
Application
+ true
Application
true
+ false
Windows7.1SDK
Application
+ true
Windows7.1SDK
@@ -211,4 +215,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2010/libcob.vcxproj b/build_windows/vs2010/libcob.vcxproj
index bf659c744..4740935f2 100644
--- a/build_windows/vs2010/libcob.vcxproj
+++ b/build_windows/vs2010/libcob.vcxproj
@@ -28,17 +28,21 @@
DynamicLibrary
true
+ false
DynamicLibrary
+ true
DynamicLibrary
true
+ false
Windows7.1SDK
DynamicLibrary
+ true
Windows7.1SDK
diff --git a/build_windows/vs2010/libsupport.vcxproj b/build_windows/vs2010/libsupport.vcxproj
index 88d1f7fd8..5cb2a53e1 100644
--- a/build_windows/vs2010/libsupport.vcxproj
+++ b/build_windows/vs2010/libsupport.vcxproj
@@ -30,23 +30,27 @@
true
+ false
StaticLibrary
+ true
StaticLibrary
true
+ false
Windows7.1SDK
StaticLibrary
+ true
Windows7.1SDK
@@ -197,4 +201,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2012/cobc.vcxproj b/build_windows/vs2012/cobc.vcxproj
index c81fa2163..a7024d4bf 100644
--- a/build_windows/vs2012/cobc.vcxproj
+++ b/build_windows/vs2012/cobc.vcxproj
@@ -27,6 +27,7 @@
Application
+ false
$(DefaultPlatformToolset)
@@ -34,12 +35,14 @@
Application
+ true
$(DefaultPlatformToolset)
Application
+ false
$(DefaultPlatformToolset)
@@ -47,6 +50,7 @@
Application
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2012/cobcrun.vcxproj b/build_windows/vs2012/cobcrun.vcxproj
index 159e54490..bad6154ea 100644
--- a/build_windows/vs2012/cobcrun.vcxproj
+++ b/build_windows/vs2012/cobcrun.vcxproj
@@ -27,6 +27,7 @@
Application
+ false
$(DefaultPlatformToolset)
@@ -34,12 +35,14 @@
Application
+ true
$(DefaultPlatformToolset)
Application
+ false
$(DefaultPlatformToolset)
@@ -47,6 +50,7 @@
Application
+ true
$(DefaultPlatformToolset)
@@ -215,4 +219,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2012/libcob.vcxproj b/build_windows/vs2012/libcob.vcxproj
index 9acdcc07f..b7093b6a6 100644
--- a/build_windows/vs2012/libcob.vcxproj
+++ b/build_windows/vs2012/libcob.vcxproj
@@ -27,20 +27,24 @@
DynamicLibrary
+ false
$(DefaultPlatformToolset)
true
DynamicLibrary
+ true
$(DefaultPlatformToolset)
DynamicLibrary
+ false
$(DefaultPlatformToolset)
true
DynamicLibrary
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2012/libsupport.vcxproj b/build_windows/vs2012/libsupport.vcxproj
index e152acba0..3c2ec55bb 100644
--- a/build_windows/vs2012/libsupport.vcxproj
+++ b/build_windows/vs2012/libsupport.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -199,4 +203,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2013/cobc.vcxproj b/build_windows/vs2013/cobc.vcxproj
index d3dc279e7..92bdaf0e0 100644
--- a/build_windows/vs2013/cobc.vcxproj
+++ b/build_windows/vs2013/cobc.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2013/cobcrun.vcxproj b/build_windows/vs2013/cobcrun.vcxproj
index dc77a4253..2a73e0233 100644
--- a/build_windows/vs2013/cobcrun.vcxproj
+++ b/build_windows/vs2013/cobcrun.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -218,4 +222,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2013/libcob.vcxproj b/build_windows/vs2013/libcob.vcxproj
index 50557d1f9..b964d2c13 100644
--- a/build_windows/vs2013/libcob.vcxproj
+++ b/build_windows/vs2013/libcob.vcxproj
@@ -28,19 +28,23 @@
DynamicLibrary
true
+ false
$(DefaultPlatformToolset)
DynamicLibrary
+ true
$(DefaultPlatformToolset)
DynamicLibrary
true
+ false
$(DefaultPlatformToolset)
DynamicLibrary
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2013/libsupport.vcxproj b/build_windows/vs2013/libsupport.vcxproj
index 87a28db68..e8376cf5e 100644
--- a/build_windows/vs2013/libsupport.vcxproj
+++ b/build_windows/vs2013/libsupport.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -203,4 +207,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2015/cobc.vcxproj b/build_windows/vs2015/cobc.vcxproj
index 6925f9fb3..053a2709f 100644
--- a/build_windows/vs2015/cobc.vcxproj
+++ b/build_windows/vs2015/cobc.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2015/cobcrun.vcxproj b/build_windows/vs2015/cobcrun.vcxproj
index dde7b36a8..c4533c287 100644
--- a/build_windows/vs2015/cobcrun.vcxproj
+++ b/build_windows/vs2015/cobcrun.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -216,4 +220,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2015/libsupport.vcxproj b/build_windows/vs2015/libsupport.vcxproj
index f729813d1..78a8d4992 100644
--- a/build_windows/vs2015/libsupport.vcxproj
+++ b/build_windows/vs2015/libsupport.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -201,4 +205,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2017/cobc.vcxproj b/build_windows/vs2017/cobc.vcxproj
index af3131a60..4947999db 100644
--- a/build_windows/vs2017/cobc.vcxproj
+++ b/build_windows/vs2017/cobc.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2017/cobcrun.vcxproj b/build_windows/vs2017/cobcrun.vcxproj
index 9b7dad5e0..e64af341e 100644
--- a/build_windows/vs2017/cobcrun.vcxproj
+++ b/build_windows/vs2017/cobcrun.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -218,4 +222,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2017/libsupport.vcxproj b/build_windows/vs2017/libsupport.vcxproj
index c3f8188dd..0b7ee8994 100644
--- a/build_windows/vs2017/libsupport.vcxproj
+++ b/build_windows/vs2017/libsupport.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -205,4 +209,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2019/cobc.vcxproj b/build_windows/vs2019/cobc.vcxproj
index 6eb1ab255..e1248842b 100644
--- a/build_windows/vs2019/cobc.vcxproj
+++ b/build_windows/vs2019/cobc.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
diff --git a/build_windows/vs2019/cobcrun.vcxproj b/build_windows/vs2019/cobcrun.vcxproj
index 9b7dad5e0..e64af341e 100644
--- a/build_windows/vs2019/cobcrun.vcxproj
+++ b/build_windows/vs2019/cobcrun.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
Application
+ true
$(DefaultPlatformToolset)
@@ -218,4 +222,4 @@
-
\ No newline at end of file
+
diff --git a/build_windows/vs2019/libsupport.vcxproj b/build_windows/vs2019/libsupport.vcxproj
index c47f9e74c..01830ca2a 100644
--- a/build_windows/vs2019/libsupport.vcxproj
+++ b/build_windows/vs2019/libsupport.vcxproj
@@ -30,12 +30,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -43,12 +45,14 @@
true
+ false
$(DefaultPlatformToolset)
StaticLibrary
+ true
$(DefaultPlatformToolset)
@@ -205,4 +209,4 @@
-
\ No newline at end of file
+
diff --git a/libcob/ChangeLog b/libcob/ChangeLog
index aed29a146..4f8d06c6b 100644
--- a/libcob/ChangeLog
+++ b/libcob/ChangeLog
@@ -1,4 +1,18 @@
+2026-08-14 David Declerck
+
+ * fileio.c (isdirvalid): implement Windows counterpart
+ * fileio.c (cob_open_qbl): fix flags and permission for Windows
+ * fileio.c (cob_file_sync, cob_file_unlock): call fdcobsync
+ only if file is open in mode other than COB_OPEN_INPUT
+ and fflush only is last operation was a write
+ * fileio.c (pathcmp) [_WIN32]: new function to compare paths
+ while ignoring slash differences
+ * fileio.c (cob_get_filename_print) [_WIN32]: use pathcmp
+ instead of strcmp to compare paths
+ * fbdb.c (ix_bdb_open): call ix_bdb_close to cleanup on
+ * cobcapi.c (cob_get_buff): protect call to cob_free
+
2025-07-28 Simon Sobisch
* common.h, fileio.c: new externalized typedef EXTFH_FUNC used in
diff --git a/libcob/Makefile.am b/libcob/Makefile.am
index b0fb053b9..0e6bb8e8b 100644
--- a/libcob/Makefile.am
+++ b/libcob/Makefile.am
@@ -50,7 +50,7 @@ INDEXED_LD_FLAGS = -version-info 1:0:0
if COB_MAKE_CISAM_LIB
lib_ci = libcobci.la
libcobci_la_SOURCES = libcobci.c fsqlxfd.c # includes fisam.c
-libcobci_la_LIBADD = libcob.la $(CISAM_LIBS)
+libcobci_la_LIBADD = libcob.la $(CISAM_LIBS) $(LIBCOB_LIBS)
libcobci_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcobci_la_CFLAGS = $(AM_CFLAGS) $(CISAM_CFLAGS)
else
@@ -60,7 +60,7 @@ endif
if COB_MAKE_DISAM_LIB
lib_di = libcobdi.la
libcobdi_la_SOURCES = libcobdi.c fsqlxfd.c # includes fisam.c
-libcobdi_la_LIBADD = libcob.la $(DISAM_LIBS)
+libcobdi_la_LIBADD = libcob.la $(DISAM_LIBS) $(LIBCOB_LIBS)
libcobdi_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcobdi_la_CFLAGS = $(AM_CFLAGS) $(DISAM_CFLAGS)
else
@@ -70,7 +70,7 @@ endif
if COB_MAKE_VBISAM_LIB
lib_vb = libcobvb.la
libcobvb_la_SOURCES = libcobvb.c fsqlxfd.c # includes fisam.c
-libcobvb_la_LIBADD = libcob.la $(VBISAM_LIBS)
+libcobvb_la_LIBADD = libcob.la $(VBISAM_LIBS) $(LIBCOB_LIBS)
libcobvb_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcobvb_la_CFLAGS = $(AM_CFLAGS) $(VBISAM_CFLAGS)
else
@@ -80,7 +80,7 @@ endif
if COB_MAKE_VISAM_LIB
lib_vc = libcobvc.la
libcobvc_la_SOURCES = libcobvc.c fsqlxfd.c # includes fisam.c
-libcobvc_la_LIBADD = libcob.la $(VISAM_LIBS)
+libcobvc_la_LIBADD = libcob.la $(VISAM_LIBS) $(LIBCOB_LIBS)
libcobvc_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcobvc_la_CFLAGS = $(AM_CFLAGS) $(VISAM_CFLAGS)
else
@@ -89,7 +89,7 @@ endif
if COB_MAKE_ODBC_LIB
lib_od = libcobod.la
-libcobod_la_LIBADD = libcob.la $(ODBC_LIBS)
+libcobod_la_LIBADD = libcob.la $(ODBC_LIBS) $(LIBCOB_LIBS)
libcobod_la_SOURCES = fodbc.c fsqlxfd.c
libcobod_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcobod_la_CFLAGS = $(AM_CFLAGS) $(ODBC_CFLAGS)
@@ -99,7 +99,7 @@ endif
if COB_MAKE_OCI_LIB
lib_oc = libcoboc.la
-libcoboc_la_LIBADD = libcob.la $(OCI_LIBS)
+libcoboc_la_LIBADD = libcob.la $(OCI_LIBS) $(LIBCOB_LIBS)
libcoboc_la_SOURCES = foci.c fsqlxfd.c
libcoboc_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcoboc_la_CFLAGS = $(AM_CFLAGS) $(OCI_CFLAGS)
@@ -109,7 +109,7 @@ endif
if COB_MAKE_BDB_LIB
lib_db = libcobdb.la
-libcobdb_la_LIBADD = libcob.la $(BDB_LIBS)
+libcobdb_la_LIBADD = libcob.la $(BDB_LIBS) $(LIBCOB_LIBS)
libcobdb_la_SOURCES = fbdb.c fsqlxfd.c
libcobdb_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcobdb_la_CFLAGS = $(AM_CFLAGS) $(BDB_CFLAGS)
@@ -119,7 +119,7 @@ endif
if COB_MAKE_LMDB_LIB
lib_lm = libcoblm.la
-libcoblm_la_LIBADD = libcob.la $(LMDB_LIBS)
+libcoblm_la_LIBADD = libcob.la $(LMDB_LIBS) $(LIBCOB_LIBS)
libcoblm_la_SOURCES = flmdb.c fsqlxfd.c
libcoblm_la_LDFLAGS = $(AM_LDFLAGS) $(INDEXED_LD_FLAGS)
libcoblm_la_CFLAGS = $(AM_CFLAGS) $(LMDB_CFLAGS)
diff --git a/libcob/cobcapi.c b/libcob/cobcapi.c
index 56181f8aa..372ee6ff2 100644
--- a/libcob/cobcapi.c
+++ b/libcob/cobcapi.c
@@ -73,7 +73,9 @@ cob_get_buff (const size_t buffsize)
{
if (buffsize > capi_lastsize) {
capi_lastsize = buffsize;
- cob_free (capi_buffer);
+ if (capi_buffer) {
+ cob_free (capi_buffer);
+ }
capi_buffer = cob_fast_malloc (buffsize);
}
return capi_buffer;
diff --git a/libcob/fbdb.c b/libcob/fbdb.c
index bbb2b4c85..c38d2570c 100644
--- a/libcob/fbdb.c
+++ b/libcob/fbdb.c
@@ -1527,6 +1527,7 @@ ix_bdb_open (cob_file_api *a, cob_file *f, char *filename, const enum cob_open_m
if (p->data.data != NULL
&& p->data.size > 0
&& p->data.size > f->record_max) {
+ ix_bdb_close (a, f, 0);
return COB_STATUS_39_CONFLICT_ATTRIBUTE;
}
} else {
diff --git a/libcob/fileio.c b/libcob/fileio.c
index 870f6398b..8a9d3cec9 100644
--- a/libcob/fileio.c
+++ b/libcob/fileio.c
@@ -399,12 +399,20 @@ void cob_seqra_init_fileio (cob_file_api *);
/* Local functions */
+static COB_INLINE COB_A_INLINE int
+isslash (char c)
+{
+ return
+#ifdef _WIN32
+ c == '\\' ||
+#endif
+ c == '/';
+}
+
static int
isdirvalid (char *filename)
{
-#ifndef _WIN32
struct stat st;
-#endif
char tmp[COB_NORMAL_BUFF];
int ln = strlen (filename);
@@ -419,12 +427,19 @@ isdirvalid (char *filename)
strcpy (tmp, filename);
while (--ln > 0) {
-#ifndef _WIN32
- /* TODO: This code needs to be tested on Windows and adjusted as needed */
- /* For now it is effectively disabled on Windows */
- if (tmp[ln] == SLASH_CHAR) {
+ if (isslash(tmp[ln])) {
+ while (ln > 1 && isslash(tmp[ln-1])) { --ln; }
tmp[ln] = 0;
errno = 0;
+#ifdef _WIN32
+ /* Under Windows, a slash is required after a drive letter, else stat fails */
+ if (ln == 2 && tmp[1] == ':'
+ && ((tmp[0] >= 'A' && tmp[0] <= 'Z')
+ || (tmp[0] >= 'a' && tmp[0] <= 'z'))) {
+ tmp[ln] = '\\';
+ tmp[ln + 1] = 0;
+ }
+#endif
if (stat(tmp, &st) == -1) {
errno = ENOENT;
return 0;
@@ -434,7 +449,6 @@ isdirvalid (char *filename)
return 0;
}
}
-#endif
}
errno = 0;
return 1;
@@ -1095,12 +1109,12 @@ cob_open_qbl (char *filename, int makeit, int append)
{
int fd, mode;
errno = 0;
- mode = O_RDWR;
+ mode = O_RDWR | O_BINARY;
if (append)
mode |= O_APPEND;
if (makeit)
mode |= O_CREAT;
- fd = open (filename, mode, 0666);
+ fd = open (filename, mode, COB_FILE_MODE);
if (errno) {
cob_runtime_warning (_("Error opening %s; %s"),
filename, strerror(errno));
@@ -1912,8 +1926,13 @@ cob_file_sync (cob_file *f)
fileio_funcs[get_io_ptr (f)]->iosync (&file_api, f);
return;
}
- if (f->organization != COB_ORG_SORT) {
- if (f->file) {
+ if (f->organization != COB_ORG_SORT && f->open_mode != COB_OPEN_INPUT) {
+ if (f->file
+ && (f->last_operation == COB_LAST_WRITE
+ || f->last_operation == COB_LAST_REWRITE
+ || f->last_operation == COB_LAST_DELETE
+ || f->last_operation == COB_LAST_COMMIT
+ || f->last_operation == COB_LAST_ROLLBACK)) {
fflush ((FILE *)f->file);
}
if (f->fd >= 0) {
@@ -6485,7 +6504,7 @@ cob_file_unlock (cob_file *f)
return;
}
if (f->organization != COB_ORG_INDEXED) {
- if (f->fd >= 0) {
+ if (f->fd >= 0 && f->open_mode != COB_OPEN_INPUT) {
fdcobsync (f->fd);
}
#ifdef HAVE_FCNTL
@@ -9821,6 +9840,53 @@ cob_file_return (cob_file *f)
}
}
+#ifdef _WIN32
+
+static int
+get_drive_letter(const char **s)
+{
+ const char *p = *s;
+ if (p[0] == '/'
+ && ((p[1] >= 'A' && p[1] <= 'Z')
+ || (p[1] >= 'a' && p[1] <= 'z'))
+ && p[2] == '/') {
+ *s += 3;
+ return p[1];
+ } else
+ if (((p[0] >= 'A' && p[0] <= 'Z')
+ || (p[0] >= 'a' && p[0] <= 'z'))
+ && p[1] == ':'
+ && (p[2] == '\\' || p[2] == '/')) {
+ *s += 3;
+ return p[0];
+ }
+ return 0;
+}
+
+static int
+pathcmp (const char *s1, const char *s2)
+{
+ int c1, c2;
+ c1 = get_drive_letter(&s1);
+ c2 = get_drive_letter(&s2);
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ do {
+ c1 = (unsigned char)*s1++;
+ c2 = (unsigned char)*s2++;
+ if (c1 == '\\') c1 = '/';
+ if (c2 == '\\') c2 = '/';
+ } while (c1 && c1 == c2);
+ return c1 - c2;
+}
+
+#else
+
+#define pathcmp strcmp
+
+#endif
+
char *
cob_get_filename_print (cob_file* file, const int show_resolved_name)
{
@@ -9846,7 +9912,7 @@ cob_get_filename_print (cob_file* file, const int show_resolved_name)
offset += len;
if (show_resolved_name
- && strcmp (file_open_env, file_open_name)) {
+ && pathcmp (file_open_env, file_open_name)) {
/* environment name is set; format: "%s ('%s' => %s)" */
len = 5;
memcpy (runtime_buffer + offset, "' => ", len);
diff --git a/tests/testsuite.src/run_file.at b/tests/testsuite.src/run_file.at
index 1a0114c78..c1977b6b5 100644
--- a/tests/testsuite.src/run_file.at
+++ b/tests/testsuite.src/run_file.at
@@ -18477,8 +18477,8 @@ AT_DATA([cmod.c], [[
#include
#include
-#include
#include
+#include
#ifndef TRUE
#define TRUE 1
@@ -26634,7 +26634,8 @@ AT_DATA([prog.cob], [
MOVE "./junky/chkdatax" TO DATAFILE.
MOVE "invalid directory" TO LIST-TEST
PERFORM LISTFILE.
- MOVE "/tmp" TO DATAFILE.
+ ACCEPT DATAFILE FROM ENVIRONMENT "TMP".
+ IF DATAFILE = SPACES MOVE "/tmp" TO DATAFILE.
MOVE "tmp directory" TO LIST-TEST
PERFORM LISTFILE.
STOP RUN RETURNING 0.
@@ -26708,7 +26709,7 @@ AT_DATA([prog.cob], [
DATA-CUST-NUM (SUB).
])
-# TODO: have a single dialect option to change io stats (also for ohter dialects)
+# TODO: have a single dialect option to change io stats (also for other dialects)
AT_CHECK([$COMPILE -std=mf prog.cob], [0], [], [])
AT_CHECK([$COBCRUN_DIRECT ./prog], [0],
@@ -26880,7 +26881,8 @@ AT_DATA([prog.cob], [
MOVE "./junky/chkdatax" TO DATAFILE.
MOVE "invalid directory" TO LIST-TEST
PERFORM LISTFILE.
- MOVE "/tmp" TO DATAFILE.
+ ACCEPT DATAFILE FROM ENVIRONMENT "TMP".
+ IF DATAFILE = SPACES MOVE "/tmp" TO DATAFILE.
MOVE "tmp directory" TO LIST-TEST
PERFORM LISTFILE.
STOP RUN RETURNING 0.
@@ -29833,3 +29835,75 @@ AT_CHECK([$COMPILE -fdefault-file-colseq=EBCDIC prog.cob])
AT_CHECK([$COBCRUN_DIRECT ./prog])
AT_CLEANUP
+
+
+AT_SETUP([Check for potential COB_SYNC bugs])
+AT_KEYWORDS([runfile INPUT READ UNLOCK COB_SYNC])
+
+# Under Windows, fdcobsync is an alias of _commit, which calls the
+# FlushFileBuffers function, which can not be called on a file opened
+# exclusively for input. Therefore, we should ensure the READ and
+# UNLOCK operation do not call fdcobsync.
+
+AT_DATA([prog1.cob], [
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. prog1.
+ ENVIRONMENT DIVISION.
+ INPUT-OUTPUT SECTION.
+ FILE-CONTROL.
+ SELECT file1 ASSIGN DISK ORGANIZATION SEQUENTIAL.
+ DATA DIVISION.
+ FILE SECTION.
+ FD file1.
+ 01 file1-rec PIC X.
+ PROCEDURE DIVISION.
+ OPEN OUTPUT file1.
+ WRITE file1-rec.
+ CLOSE file1.
+ OPEN INPUT file1.
+ READ file1.
+ UNLOCK file1.
+ CLOSE file1.
+ GOBACK.
+])
+
+AT_CHECK([$COMPILE prog1.cob], [0], [], [])
+AT_CHECK([COB_SYNC=Y $COBCRUN_DIRECT ./prog1], [0], [], [])
+
+# Per C standard, calling fflush is UB on files opened for input or after a
+# read operation on a file opened for update/append. While harmless under
+# most C runtime implementations, this causes problems under MSVCRT (used
+# by older MSVC and by MSYS2's MINGW32/64 environments). Typically, a fflush
+# after read might mess up the EOF indicator, resulting in incomplete
+# file read. Therefore, we should not call fflush on files opened for
+# INPUT, or after a READ operation on files opened for I-O.
+
+AT_DATA([prog2.cob], [
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. prog2.
+ ENVIRONMENT DIVISION.
+ INPUT-OUTPUT SECTION.
+ FILE-CONTROL.
+ SELECT file2 ASSIGN DISK ORGANIZATION LINE SEQUENTIAL.
+ DATA DIVISION.
+ FILE SECTION.
+ FD file2.
+ 01 file2-rec PIC X.
+ PROCEDURE DIVISION.
+ OPEN OUTPUT file2.
+ MOVE "X" TO file2-rec.
+ WRITE file2-rec.
+ MOVE "Y" TO file2-rec.
+ WRITE file2-rec.
+ CLOSE file2.
+ OPEN I-O file2.
+ READ file2.
+ READ file2.
+ CLOSE file2.
+ GOBACK.
+])
+
+AT_CHECK([$COMPILE prog2.cob], [0], [], [])
+AT_CHECK([COB_SYNC=Y $COBCRUN_DIRECT ./prog2], [0], [], [])
+
+AT_CLEANUP
diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at
index ba481c31b..092d75705 100644
--- a/tests/testsuite.src/run_misc.at
+++ b/tests/testsuite.src/run_misc.at
@@ -3701,22 +3701,28 @@ AT_DATA([prog.cob], [
AT_DATA([cmod.c], [[
#include
-int dump (unsigned char *data)
+#include
+
+COB_EXT_EXPORT int
+dump (unsigned char *data)
{
int i;
for (i = 0; i < 4; i++)
printf ("%02X", data[i]);
puts (" ");
+ fflush(stdout);
return 0;
}
-int dumpln (unsigned char *data, int len)
+COB_EXT_EXPORT int
+dumpln (unsigned char *data, int len)
{
int i;
printf ("%2d: ",len);
for (i = 0; i < 32 && i < len; i++)
printf ("%02X", data[i]);
puts (":");
+ fflush(stdout);
return 0;
}
]])
@@ -11322,7 +11328,7 @@ AT_DATA([cmod.c], [[
#include
static int doWatch = 1;
-int
+COB_EXT_EXPORT int
CSYMDMP ()
{
int nargs,sts;
@@ -11392,6 +11398,7 @@ CSYMDMP ()
sts = cob_get_field_value (modname, fld, sizeof(buf), buf);
printf(" %30s is %s%s. Was changed\n",fld,sts?"Error: ":"",buf);
}
+ fflush(stdout);
return 0;
}
]])
@@ -11501,7 +11508,7 @@ getType(int type, int byvalue)
return wrk;
}
-int
+COB_EXT_EXPORT int
CAPI(void *p1, ...)
{
int k,nargs,type,digits,scale,size,sign,byvalue,isright;
@@ -14204,17 +14211,18 @@ AT_DATA([prog.cob], [
AT_DATA([cmod.c], [[
#include
-#include
+#include
extern int CSUB4();
extern int CSUB5();
extern int SUB6();
extern int CSUB7(float f);
extern int CSUB8(float *f);
-int
+COB_EXT_EXPORT int
COBCSUB(int y, unsigned char x[15])
{
float flt1;
printf("C routine passed: Y is %d; X is '%.15s'\n",y,x);
+ fflush(stdout);
CSUB4(y, x);
CSUB4(y+1, "A C-String is being passed");
CSUB5(y+2, "A much longer C-String is being passed");
@@ -14354,9 +14362,11 @@ int main()
return 0;
}
-void one_parameter(void *dummy)
+COB_EXT_EXPORT void
+one_parameter(void *dummy)
{
printf("Now in one_parameter\n");
+ fflush(stdout);
routine2((void *)(0x3),(void *)(0x4));
}
]])