From 3b59e536d3e8638000caa24cee8b4d19e51e32fb Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 11:10:36 +1000 Subject: [PATCH 01/35] chore: renamed **CHANGES.txt** to **CHANGES.md** (and updated) --- CHANGES.md | 133 +++++++++++ CHANGES.txt | 666 ---------------------------------------------------- 2 files changed, 133 insertions(+), 666 deletions(-) create mode 100644 CHANGES.md delete mode 100644 CHANGES.txt diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..e584ce8 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,133 @@ +# **cstring** Changes + + +## 4.0.12 - 2nd September 2025 + +* GitHub Actions; +* CTest; +* CMake helper scripts now define default make command as `"mingw32-make.exe"` if recognise MinGW; +* Documentation; +* `*.sh`: moved info-lines into **./.sis/script_info_lines.txt**; +* Added **libver** scratch test; +* **.gitattributes**; + + +## 4.0.11 - 23rd February 2025 + +* Boilerplate; +* Simplification of dependencies; + + +## 4.0.10 - 25th October 2024 + +* Substantial CMake improvements; +* MinGW compatibility; + + +## 4.0.9 - 28th January 2024 + +* Improved CMake support; +* CMake language standards now C-11 and C++14; +* Fixed typo defect in definition of `CSTRING_F_USE_WINDOWS_PROCESSHEAP_MEMORY`; +* Added project boilerplate files: **AUTHORS.md**, **CHANGES.txt**, **FAQ.md**, **HISTORY.md**, **NEWS.md**; + + +## 4.0.8 - 12th January 2024 + +* Added **cstring.vector** API; +* Added API function `cstring_write()`; +* Wide string support (indicated via `CSTRING_USE_WIDE_STRINGS`); +* Partial CMake support; +* Added result code `CSTRING_RC_REQUESTTOOLARGE`; +* Added component test **test.component.cstring_writeline**; +* Added scratch test **test.scratch.cstring_vector**; +* Added unit test **test.unit.cstring.cstring_vector**; + + +## 3.6.2 - 20th February 2012 + +* Added `CSTRING_RC_SYSTEMSPECIFICFAILURE`; +* All makefiles now build `cstring.3.core*.(lib|a)` rather than `cstring.3*.(lib|a)`: this was erroneously omitted from the 3.6.1 release; + + +## 3.6.1 - 24th January 2012 + +* Added `CSTRING_F_MEMORY_CAN_GROW_TO_HEAP` flag, which allows a borrowed buffer to grow (into the heap); +* Renamed output library to `cstring.core.*` (in preparation for coming 4.x expansions); +* Added string access shims for `CSTRING_RC`; +* Added `cstring_getStatusCodeStringLength()`; +* Renamed `cstring_error()` ⇒ `cstring_getStatusCodeString()`; +* Added VC10 solution and project files; +* Added VC9 solution and project files; +* Added **test.unit.cstring.auto_buffer**; +* Added **test.unit.cstring.cstring_getStatusCodeString**; +* Added **test.scratch.auto_buffer**; +* Full Win64 compatibility; +* Fixed up minor documentation mistakes; + + +## 3.5.4 - 22nd January 2012 + +* Win64-compatibility; +* Added **test.scratch.HGLOBAL_on_x64** project; +* VC++ 10 compatibility; + + +## 3.5.3 - 11th January 2010 + +* Trivial formatting changes; + + +## 3.5.2 - 11th July 2009 + +* Fixed implicit link defects; +* Completed Win64 compatibility; +* Minor adjustments to compiler warnings; + + +## 3.5.1 - 10th July 2009 + +* Added new API functions for cstring I/O, replacing and inserting substrings, and initialisation; +* Added compatibility with Borland C/C++ 5.8.2, 5.9 and 6.1, Intel C/C++ 9–11, and GCC 4.1–4.4; +* Added three unit/component test programs; + + +## 3.4.4 - 4th May 2008 + +* Additional error codes in API; +* Compatible with Win64; +* Compatible with Safe String library; + + +## 3.4.3 - 26th January 2007 + +* Distribution now roots under `cstring-X.Y`, e.g. `cstring-3.4.3`; + + +## 3.4.2 - 30th April 2006 + +* Only minor edits, and little fixes; + + +## 3.4.1 - 7th October 2005 + +* Makefiles now build libraries whose names include the major version number, e.g. `cstring.3.vc6.lib`, in addition to the unversioned form, e.g. `cstring.vc6.lib`; +* Type `cstring_flags_t` is defined to disambiguate flags params from size params (which use `size_t`); +* Added `CSTRING_RC_CANNOTYIELDFROMSO` return code, used when trying to yield a string from a dynamic library implementation that has been allocated using `realloc()`; +* `cstring_yield()` has been deprecated in favour of `cstring_yield2()`; define `CSTRING_OBSOLETE` for the old behaviour; + + +## 3.3.1 - 8th August 2005 + +* Changed the memory allocation algorithm such that each reallocation is at least twice the size of the extant block; +* Now dynamically loads the `CoTaskMemRealloc` function from **OLE32.DLL**, easing the linking burden when working with a variety of compilers; + + +## 3.2.1 - 29th July 2005 + +* Initial public release of this formerly proprietary library from Synesis Software; +* Plain-C library, platform/compiler independent; +* When compiled under Win32, provides facility to use Win32 Global, Process Heap and COM Task Allocator memory, rather than the default C library `realloc()`; + + + diff --git a/CHANGES.txt b/CHANGES.txt deleted file mode 100644 index 8de8dc5..0000000 --- a/CHANGES.txt +++ /dev/null @@ -1,666 +0,0 @@ -cstring - Changes -================= - -; Updated: 2nd September 2025 - - - ************************************ - * Change key: * - * * - * ~ means something has changed * - * + means a new addition * - * - means removal of something * - * * means a general bullet-point * - * * - ************************************ - - -Version 4.0.12 (2nd September 2025) -=================================== - - * GitHub Actions; - * CTest; - * CMake helper scripts now define default make command as "mingw32-make.exe" if recognise MinGW; - * Documentation; - * *.sh : ~ moved info-lines into ./.sis/script_info_lines.txt; - * added **libver** scratch test; - * .gitattributes; - - -Version 4.0.11 (23rd February 2025) -=================================== - - * Boilerplate; - * Simplication of dependencies; - - -Version 4.0.10 (25th October 2024) -================================== - - * Substantial CMake improvements; - * MinGW compatibility; - - -Version 4.0.9 (28th January 2024) -================================= - - ~ improved CMake support; - ~ CMake language standards now C-11 and C++14; - ~ fixed typo defect in definition of CSTRING_F_USE_WINDOWS_PROCESSHEAP_MEMORY; - + project boilerplate files: - + AUTHORS.md; - + CHANGES.txt; - + FAQ.md; - + HISTORY.md; - + NEWS.md; - - -Version 4.0.8 (12th January 2024) -================================= - - + added cstring.vector API; - + added API function cstring_write(); - + wide string support (indicated via CSTRING_USE_WIDE_STRINGS); - + partial CMake support; - + added result code CSTRING_RC_REQUESTTOOLARGE; - + added component test test.component.cstring_writeline; - + added scratch test test.scratch.cstring_vector; - + added unit test test.unit.cstring.cstring_vector; - - -Version 3.6.2 (20th February 2012) -================================== - -Summary: --------- - - * added CSTRING_RC_SYSTEMSPECIFICFAILURE - * all makefiles now build cstring.3.core*.(lib|a) rather than cstring.3*.(lib|a) : this was erroneously omitted from the 3.6.1 release - -Details: --------- - -General: - - ~ include/cstring/cstring.h: - + added CSTRING_RC_SYSTEMSPECIFICFAILURE - ~ makefiles now build cstring.3.core*.(lib|a) rather than cstring.3*.(lib|a) - - ~ src/cstring.core.c: - + added CSTRING_RC_SYSTEMSPECIFICFAILURE - -Distribution: - -Makefiles / Project-files: - - ~ build/ar/makefile: - ~ build/bc55/makefile: - ~ build/bc551/makefile: - ~ build/bc56/makefile: - ~ build/bc564/makefile: - ~ build/bc582/makefile: - ~ build/bc59x/makefile: - ~ build/bc61x/makefile: - ~ build/como433.unix/makefile: - ~ build/como433.win32/makefile: - ~ build/cw7.unix/makefile: - ~ build/cw7.win32/makefile: - ~ build/cw8.unix/makefile: - ~ build/cw8.win32/makefile: - ~ build/dm/makefile: - ~ build/gcc295.unix/makefile: - ~ build/gcc295.win32/makefile: - ~ build/gcc32.unix/makefile: - ~ build/gcc32.win32/makefile: - ~ build/gcc33.unix/makefile: - ~ build/gcc33.win32/makefile: - ~ build/gcc34.unix/makefile: - ~ build/gcc34.win32/makefile: - ~ build/gcc40.mac.x64/makefile: - ~ build/gcc40.mac/makefile: - ~ build/gcc40.unix/makefile: - ~ build/gcc41.unix/makefile: - ~ build/gcc42.unix/makefile: - ~ build/gcc43.unix/makefile: - ~ build/gcc44.unix/makefile: - ~ build/icl10.win32/makefile: - ~ build/icl11.win32/makefile: - ~ build/icl6.win32/makefile: - ~ build/icl7.win32/makefile: - ~ build/icl8.win32/makefile: - ~ build/icl9.win32/makefile: - ~ build/ow12.win32/makefile: - ~ build/ow13.win32/makefile: - ~ build/sunpro59x.unix/makefile: - ~ build/vc10.unixem/makefile: - ~ build/vc10.x64/makefile: - ~ build/vc10/makefile: - ~ build/vc42/makefile: - ~ build/vc5/makefile: - ~ build/vc6.unixem/makefile: - ~ build/vc6/makefile: - ~ build/vc7/makefile: - ~ build/vc71/makefile: - ~ build/vc8.unixem/makefile: - ~ build/vc8.x64/makefile: - ~ build/vc8/makefile: - ~ build/vc9.unixem/makefile: - ~ build/vc9.x64/makefile: - ~ build/vc9/makefile: - ~ makefiles now build cstring.3.core*.(lib|a) rather than cstring.3*.(lib|a) - -Examples: - -Test: - -Test.Unit: - -Test.Component: - -Test.Scratch: - -Depends on: - - STLSoft 1.9.111 (for test programs only) - xTests 0.16.2 (for test programs only) - shwild 0.9.20 (for test programs only) - - - -Version 3.6.1 (24th January 2012) -================================= - -Summary: --------- - - * added CSTRING_F_MEMORY_CAN_GROW_TO_HEAP flag, which allows a borrowed buffer to grow (into the heap) - * renamed output library to cstring.core.* (in preparation for coming 4.x expansions) - * added string access shims for CSTRING_RC - * added cstring_getStatusCodeStringLength() - * renamed cstring_error() => cstring_getStatusCodeString() - * added VC10 solution and project files - * added VC9 solution and project files - * added test.unit.cstring.auto_buffer - * added test.unit.cstring.cstring_getStatusCodeString - * added test.scratch.auto_buffer - * full Win64 compatibility - * fixed up minor documentation mistakes - -Details: --------- - -General: - - ~ include/cstring/cstring.h: - + added CSTRING_F_MEMORY_CAN_GROW_TO_HEAP, which allows a borrowed buffer to grow (into the heap) - ~ renamed cstring_error() => cstring_getStatusCodeString() - + added cstring_getStatusCodeStringLength() - + added string access shims for CSTRING_RC - ~ fixed up minor documentation mistakes - ~ trivial spacing changes - - ~ include/cstring/implicit_link.h: - + now supports VC++10 implicit-linking - ~ renamed output library to cstring.core.* - - ~ src/cstring.core.c: - ~ renamed src/cstring.c to src/cstring.core.c - + added CSTRING_F_MEMORY_CAN_GROW_TO_HEAP, which allows a borrowed buffer to grow (into the heap) - ~ renamed cstring_error() => cstring_getStatusCodeString() - + added cstring_getStatusCodeStringLength() - ~ tidying compiler pragmas - ~ compiler compatibility - ~ Win64 compatibility - ~ trivial formatting changes - ~ trivial spacing changes - - ~ src/cstring.def: - ~ renamed cstring_error() => cstring_getStatusCodeString() - + added cstring_getStatusCodeStringLength() - -Distribution: - -Makefiles / Project-files: - - ~ build/bc55/makefile: - ~ build/bc551/makefile: - ~ build/bc56/makefile: - ~ build/bc564/makefile: - ~ build/bc582/makefile: - ~ build/bc59x/makefile: - ~ build/bc61x/makefile: - ~ build/como433.unix/makefile: - ~ build/como433.win32/makefile: - ~ build/cw7.unix/makefile: - ~ build/cw7.win32/makefile: - ~ build/cw8.unix/makefile: - ~ build/cw8.win32/makefile: - ~ build/dm/makefile: - ~ build/gcc295.unix/makefile: - ~ build/gcc295.win32/makefile: - ~ build/gcc32.unix/makefile: - ~ build/gcc32.win32/makefile: - ~ build/gcc33.unix/makefile: - ~ build/gcc33.win32/makefile: - ~ build/gcc34.unix/makefile: - ~ build/gcc34.win32/makefile: - ~ build/gcc40.mac.x64/makefile: - ~ build/gcc40.mac/makefile: - ~ build/gcc40.unix/makefile: - ~ build/gcc41.unix/makefile: - ~ build/gcc42.unix/makefile: - ~ build/gcc43.unix/makefile: - ~ build/gcc44.unix/makefile: - ~ build/icl10.win32/makefile: - ~ build/icl11.win32/makefile: - ~ build/icl6.win32/makefile: - ~ build/icl7.win32/makefile: - ~ build/icl8.win32/makefile: - ~ build/icl9.win32/makefile: - ~ build/ow12.win32/makefile: - ~ build/ow13.win32/makefile: - ~ build/sunpro59x.unix/makefile: - ~ build/vc42/makefile: - ~ build/vc5/makefile: - ~ build/vc6.unixem/makefile: - ~ build/vc6/makefile: - ~ build/vc7/makefile: - ~ build/vc71/makefile: - ~ build/vc8.unixem/makefile: - ~ build/vc8.x64/makefile: - ~ build/vc8/makefile: - ~ build/vc9.unixem/makefile: - ~ build/vc9.x64/makefile: - ~ build/vc9/makefile: - + added test.scratch.auto_buffer - + added test.scratch.HGLOBAL_on_x64 - + added test.unit.cstring.auto_buffer - + added test.unit.cstring.cstring_getStatusCodeString - ~ corrections to all makefiles to ensure all targets and intermediates are cleaned - ~ minor correction to makefiles (to ensure compile.test.unit builds all unit test source) - - + build/vc10.unixem/makefile: - + build/vc10.x64/makefile: - + build/vc10/makefile: - + VC++ 10 compatibility - - + cstring.vc10.sln: - + added VC++10 solution file - - ~ cstring.vc6.dsw: - ~ renamed output library from cstring.V.* to cstring.V.core.* - ~ moved VC6 project file build/vc6 to projects/cstring.core/vc6, and renamed from cstring.dsp to cstring.core.dsp - + added test.unit.cstring.auto_buffer - ~ updated to correctly reflect all projects - - + cstring.vc9.sln: - ~ renamed output library from cstring.V.* to cstring.V.core.* - ~ moved VC9 project file build/vc9 to projects/cstring.core/vc9, and renamed from cstring.vcproj to cstring.core.vcproj - + added test.unit.cstring.auto_buffer - + added VC9 solution and project files - - ~ projects/cstring.core/vc6/cstring.core.dsp: - ~ renamed outputs to cstring.core.* - ~ moved VC6 project file build/vc6 to projects/cstring.core/vc6, and renamed from cstring.dsp to cstring.core.dsp - - + projects/cstring.core/vc9/cstring.core.vcproj: - + added x64 platform to configurations - ~ renamed outputs to cstring.core.* - ~ moved VC6 project file build/vc9 to projects/cstring.core/vc9, and renamed from cstring.vcproj to cstring.core.vcproj - + added VC9 solution and project files - - -Examples: - -Test: - -Test.Unit: - - + test/unit/test.unit.cstring.1/vc10/test.unit.cstring.1.vcxproj: - + added VC++10 project files - - + test/unit/test.unit.cstring.1/vc9/test.unit.cstring.1.vcproj: - + added VC9 solution and project files - - + test/unit/test.unit.cstring.2/vc10/test.unit.cstring.2.vcxproj: - + added VC++10 project files - - + test/unit/test.unit.cstring.2/vc9/test.unit.cstring.2.vcproj: - + added VC9 solution and project files - - + test/unit/test.unit.cstring.auto_buffer/implicit_link.cpp: - + test/unit/test.unit.cstring.auto_buffer/test.unit.cstring.auto_buffer.cpp: - + test/unit/test.unit.cstring.auto_buffer/vc10/test.unit.cstring.auto_buffer.vcxproj: - + test/unit/test.unit.cstring.auto_buffer/vc6/test.unit.cstring.auto_buffer.dsp: - + test/unit/test.unit.cstring.auto_buffer/vc9/test.unit.cstring.auto_buffer.vcproj: - + added test.unit.cstring.auto_buffer - - + test/unit/test.unit.cstring.cstring_getStatusCodeString/implicit_link.cpp: - + test/unit/test.unit.cstring.cstring_getStatusCodeString/test.unit.cstring.cstring_getStatusCodeString.cpp: - + test/unit/test.unit.cstring.cstring_getStatusCodeString/vc6/test.unit.cstring.cstring_getStatusCodeString.dsp: - + test/unit/test.unit.cstring.cstring_getStatusCodeString/vc9/test.unit.cstring.cstring_getStatusCodeString.vcproj: - + test/unit/test.unit.cstring.cstring_getStatusCodeString/vc10/test.unit.cstring.cstring_getStatusCodeString.vcxproj: - + added test.unit.cstring.cstring_getStatusCodeString - -Test.Component: - - + test/component/test.component.cstring_readline/vc9/test.component.cstring_readline.vcproj: - + added VC9 solution and project files - -Test.Scratch: - - ~ test/scratch/test.scratch.cstring/test.scratch.cstring.c: - ~ renamed cstring_error() => cstring_getStatusCodeString() - - + test/scratch/test.scratch.cstring/vc9/test.scratch.cstring.vcproj: - + added VC9 solution and project files - - + test/scratch/test.scratch.cstring/vc10/test.scratch.cstring.vcxproj: - + added VC10 solution and project files - - ~ test/scratch/test.scratch.cstring_create/test.scratch.cstring_create.c: - ~ renamed cstring_error() => cstring_getStatusCodeString() - - + test/scratch/test.scratch.cstring_create/vc9/test.scratch.cstring_create.vcproj: - + added VC9 solution and project files - - + test/scratch/test.scratch.cstring_create/vc10/test.scratch.cstring_create.vcxproj: - + added VC10 solution and project files - -Depends on: - - STLSoft 1.9.111 (for test programs only) - xTests 0.16.2 (for test programs only) - shwild 0.9.20 (for test programs only) - - - -Version 3.5.4 (22nd January 2012) -================================= - -Summary: --------- - - * Win64-compatibility - * added test.scratch.HGLOBAL_on_x64 project - * VC++ 10 compatibility - -Details: --------- - -General: - - ~ src/cstring.c: - ~ tidying compiler pragmas - ~ compiler compatibility - ~ Win64 compatibility - -Distribution: - -Makefiles / Project-files: - - ~ build/icl9.win32/makefile: - + VC++ 10 compatibility - - ~ cstring.vc6.dsw: - ~ updated to correctly reflect all projects - -Examples: - -Test: - -Test.Unit: - -Test.Component: - -Test.Scratch: - - + test/scratch/cstring.test.scratch.vc9.sln: - + test/scratch/test.scratch.HGLOBAL_on_x64/implicit_link.cpp: - + test/scratch/test.scratch.HGLOBAL_on_x64/test.scratch.HGLOBAL_on_x64.cpp: - + test/scratch/test.scratch.HGLOBAL_on_x64/vc9/test.scratch.HGLOBAL_on_x64.vcproj: - + added test/scratch/test.scratch.HGLOBAL_on_x64 - -Depends on: - - STLSoft 1.9.111 (for test programs only) - xTests 0.16.2 (for test programs only) - shwild 0.9.20 (for test programs only) - - - -Version 3.5.3 (11th January 2010) -================================= - -Summary: --------- - - * trivial formatting changes - -Details: --------- - -General: - - ~ include/cstring/cstring.h: - ~ trivial spacing changes - - ~ src/cstring/cstring.c: - ~ trivial spacing changes - -Distribution: - -Makefiles / Project-files: - -Examples: - -Test: - -Test.Unit: - -Test.Component: - -Test.Scratch: - -Depends on: - - STLSoft 1.9.87 (for test programs only) - xTests 0.13 (for test programs only) - shwild 0.9 (for test programs only) - - - -Version 3.5.2 (11th July 2009) -============================== - -Summary: --------- - - * fixed implicit link defects - * completed Win64 compatibility - * minor adjustments to compiler warnings - -Details: --------- - -General: - - ~ include/cstring/cstring.h: - ~ Win64 constants - ~ suppresses VC++ C4514 warning - - ~ include/cstring/implicit_link.h: - ~ fixed implicit link defects - -Distribution: - -Makefiles / Project-files: - -Examples: - -Test: - -Test.Unit: - -Test.Component: - -Test.Scratch: - -Depends on: - - STLSoft 1.9.85 (for test programs only) - xTests 0.13 (for test programs only) - shwild 0.9 (for test programs only) - - - -Version 3.5.1 (10th July 2009) -============================== - -Summary: --------- - - * added new API functions for cstring I/O, replacing and inserting substrings, and initialisation - * added compatibility with Borland C/C++ 5.8.2, 5.9 and 6.1, Intel C/C++ 9-11, and GCC 4.1-4.4 - * added three unit/component test programs - -Details: --------- - -General: - - + added cstring_readline() and cstring_writeline() functions, for FILE* I/O - + added cstring_createN() function, which creates a string with N repetitions of a given character - + added cstring_insert() and cstring_insertLen() functions, which insert into a string - + added cstring_replace(), cstring_replaceLen(), cstring_replaceAll() (sub-)string replacement functions - + added STLSoft string access shims (though still no dependency on STLSoft for library) - + CSTRING_RC_INVALIDSTREAM, CSTRING_RC_EOF, CSTRING_RC_INVALIDSECTION, CSTRING_RC_IOERROR return codes - + compatibility with Borland C/C++ 5.8.2, 5.9 and 6.1, Intel C/C++ 9, 10 and 11, GCC 4.1-4.4 - + added test.unit.cstring.1 - + added test.unit.cstring.2 - + added test.component.cstring_readline - -Distribution: - -Makefiles / Project-files: - - ~ wholesale changes, incorporating all changes to source & test programs - -Examples: - -Test: - -Test.Unit: - - + added test.unit.cstring.1 - + added test.unit.cstring.2 - -Test.Component: - - + added test.component.cstring_readline - -Test.Scratch: - - ~ moved/renamed test/C to test/scratch/test.scratch.cstring - ~ moved/renamed test/cstring_dynload_test to test/scratch/test.scratch.cstring.dynload - ~ moved/renamed test/cstring_test to test/scratch/test.scratch.cstring_create - -Depends on: - - STLSoft 1.9.85 (for test programs only) - xTests 0.13 (for test programs only) - shwild 0.9 (for test programs only) - - - -Version 3.4.4 (4th May 2008) -============================= - -Summary: --------- - - * additional error codes in API - * compatible with Win64 - * compatible with Safe String library - -Details: --------- - -General: - - + CSTRING_RC enumerator CSTRING_RC_ARENAOVERLOADED - - ~ compatible with Win64 - ~ compatible with Safe String library - - + implicit linking with bc582, vc8 x64, vc8 IA64, vc9, vc9 x64, vc9 IA64 - -Distribution: - -Makefiles / Project-files: - - + vc8_x64 - + vc9 - + vc9_x64 - -Examples: - -Test: - -Test.Unit: - -Test.Component: - -Test.Scratch: - -Depends on: - - - - -Version 3.4.3 (26th January 2007) ---------------------------------- - - + now roots the distribution under cstring-X.Y, e.g. cstring-3.4.3 - -Version 3.4.2 (30th April 2006) -------------------------------- - - Only minor edits, and little fixes. - -Version 3.4.1 (7th October 2005) --------------------------------- - - ~ The makefiles now build libraries whose names are comprised of the - major version number, e.g. cstring.3.vc6.lib, in addition to the one - created in previous cstring versions: e.g. cstring.vc6.lib - + Type cstring_flags_t is defined to disambiguate flags params from - size params (which use the size_t) - + Added CSTRING_RC_CANNOTYIELDFROMSO return code, used when trying to - yield a string from a dynamic library implementation of the library - that has been allocated using realloc(). - ~ cstring_yield() has been deprecated, in favour of cstring_yield2(). - If you want the old behaviour, you must define CSTRING_OBSOLETE. - - -Version 3.3.1 (8th August 2005) ------------------------------- - - ~ Changed the memory allocation algorithm, such that each reallocation - is at least twice the size of the extant block - + Now dynamically loads the CoTaskMemRealloc function from OLE32.DLL, - so easing the linking burden when working with a variety of compilers. - - -Version 3.2.1 (29th July 2005) ------------------------------- - - This is the first public release of this formerly proprietary library - from Synesis Software (http://synesis.com.au/). It is a plain-C library, - and is platform/compiler independent. When compiled under Win32 it - provides the facility to use Win32 Global, Process Heap and COM Task - Allocator memory, rather than the default C library realloc(). - - -=============================== end of file ================================ - From 5ceb9b9b7beaaceac17127b3a9149dc8fc7896ea Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 11:11:08 +1000 Subject: [PATCH 02/35] chore: misc markdown changes --- AUTHORS.md | 2 +- KNOWN_ISSUES.md | 2 +- NEWS.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 05380f0..540adcd 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,4 +1,4 @@ -# cstring - Authors +# cstring - Authors ## Major Contributors: diff --git a/KNOWN_ISSUES.md b/KNOWN_ISSUES.md index 0fc6edb..8a7f9fa 100644 --- a/KNOWN_ISSUES.md +++ b/KNOWN_ISSUES.md @@ -1,4 +1,4 @@ -# cstring - Known Issues +# cstring - Known Issues ## cstring 4 Known Issues: diff --git a/NEWS.md b/NEWS.md index ae240b1..249822e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# cstring - News +# cstring - News | Date | News Item | From 0beda691a61a549c935d635ed5b9e40d01162ec1 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 11:11:42 +1000 Subject: [PATCH 03/35] chore: removed now-redundant **HISTORY.md** --- HISTORY.md | 144 ----------------------------------------------------- 1 file changed, 144 deletions(-) delete mode 100644 HISTORY.md diff --git a/HISTORY.md b/HISTORY.md deleted file mode 100644 index e6e3b32..0000000 --- a/HISTORY.md +++ /dev/null @@ -1,144 +0,0 @@ -# cstring - History - - ----- - - -1st September 2025 - 4.0.12 released ------------------------------------- - - * CMake helper scripts now define default make command as "mingw32-make.exe" if recognise MinGW; - * *.sh : ~ moved info-lines into ./.sis/script_info_lines.txt; - * . . . - - -23rd February 2025 - 4.0.11 released ------------------------------------- - - * Boilerplate; - * Simplication of dependencies; - - -25th October 2024 - 4.0.10 released ------------------------------------ - - * Substantial CMake improvements; - * MinGW compatibility; - - -28th January 2024 - 4.0.9 released ------------------------------------ - - * improved CMake support - * CMake language standards now C-11 and C++14 - * fixed typo defect in definition of `CSTRING_F_USE_WINDOWS_PROCESSHEAP_MEMORY`` - + project boilerplate files - - -12th January 2024 - 4.0.8 released ------------------------------------ - - * added **cstring.vector API** - * added API function `cstring_write()` - * wide string support (indicated via `CSTRING_USE_WIDE_STRINGS` - * partial CMake support - * added result code `CSTRING_RC_REQUESTTOOLARGE` - * added component test **test.component.cstring_writeline** - * added scratch test **test.scratch.cstring_vector** - * added unit test **test.unit.cstring.cstring_vector** - - -20th February 2012 - 3.6.2 released ------------------------------------ - - * added CSTRING_RC_SYSTEMSPECIFICFAILURE - * all makefiles now build cstring.3.core*.(lib|a) rather than cstring.3*.(lib|a) : this was erroneously omitted from the 3.6.1 release - - -24th January 2012 - 3.6.1 released ------------------------------------ - - * added CSTRING_F_MEMORY_CAN_GROW_TO_HEAP flag, which allows a borrowed buffer to grow (into the heap) - * renamed output library to cstring.core.* (in preparation for coming 4.x expansions) - * added string access shims for CSTRING_RC - * added cstring_getStatusCodeStringLength() - * renamed cstring_error() => cstring_getStatusCodeString() - * added VC10 solution and project files - * added VC9 solution and project files - * added test.unit.cstring.auto_buffer - * added test.unit.cstring.cstring_getStatusCodeString - * added test.scratch.auto_buffer - * full Win64 compatibility - * fixed up minor documentation mistakes - - -22nd January 2012 - 3.5.4 released ----------------------------------- - - * Win64-compatibility - * added test.scratch.HGLOBAL_on_x64 project - * VC++ 10 compatibility - - -11th January 2010 - 3.5.3 released ----------------------------------- - - * trivial formatting changes - - -11th July 2009 - 3.5.2 released -------------------------------- - - * fixed implicit link defects - * completed Win64 compatibility - * minor adjustments to compiler warnings - - -10th July 2009 - 3.5.1 released -------------------------------- - - * added new API functions for cstring I/O, replacing and inserting substrings, and initialisation - * added compatibility with Borland C/C++ 5.8.2, 5.9 and 6.1, Intel C/C++ 9-11, and GCC 4.1-4.4 - * added three unit/component test programs - - -13th May 2007 - 3.4.4 released ------------------------------- - - * additional error codes in API - * compatible with Win64 - * compatible with Safe String library - - -26th January 2007 - 3.4.3 released ----------------------------------- - - * distribution now roots under cstring-X.Y, e.g. cstring-3.4.3 - - -30th April 2006 - 3.4.2 released --------------------------------- - - * Only minor edits, and little fixes. - - -7th October 2005 - 3.4.1 released ---------------------------------- - - * added flag; added new API function; fixes to makefiles - - -8th August 2005 - 3.3.1 released --------------------------------- - - * change memory allocation algorithm - * reduced system library dependencies - - -29th July 2005 - 3.2.1 released -------------------------------- - - * initial public release - - -=============================== End of file ================================ From 628572e29320a56a3a7ca391b8ed9784b8db2f87 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 11:25:51 +1000 Subject: [PATCH 04/35] chore: standardised **run_all_unit_tests.sh** --- run_all_unit_tests.sh | 57 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/run_all_unit_tests.sh b/run_all_unit_tests.sh index a949656..12fe51a 100755 --- a/run_all_unit_tests.sh +++ b/run_all_unit_tests.sh @@ -9,6 +9,8 @@ MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ListOnly=0 RunMake=1 +UnitOnly=0 +ComponentOnly=0 Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}} @@ -26,6 +28,14 @@ while [[ $# -gt 0 ]]; do RunMake=0 ;; + --unit-only) + + UnitOnly=1 + ;; + --component-only) + + ComponentOnly=1 + ;; --verbosity) shift @@ -35,7 +45,7 @@ while [[ $# -gt 0 ]]; do [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF -Runs all (matching) component-test and unit-test programs +Runs all (matching) unit-test and/or component-test programs $ScriptPath [ ... flags/options ... ] @@ -51,6 +61,12 @@ Flags/options: --no-make does not execute CMake and make before running tests + --unit-only + runs only unit-test programs (test.unit.* / test_unit*) + + --component-only + runs only component-test programs (test.component.* / test_component*) + --verbosity specifies an explicit verbosity for the unit-test(s) @@ -75,17 +91,35 @@ EOF shift done +if [ $UnitOnly -ne 0 ] && [ $ComponentOnly -ne 0 ]; then + + >&2 echo "$ScriptPath: --unit-only and --component-only are mutually exclusive" + + exit 1 +fi + # ########################################################## # main() status=0 +if [ $UnitOnly -ne 0 ]; then + + TestKindDescription='unit test' +elif [ $ComponentOnly -ne 0 ]; then + + TestKindDescription='component test' +else + + TestKindDescription='component and unit test' +fi + if [ $RunMake -ne 0 ]; then if [ $ListOnly -eq 0 ]; then - echo "Executing build (via command \`$MakeCmd\`) and then running all component and unit test programs" + echo "Executing build (via command \`$MakeCmd\`) and then running all ${TestKindDescription} programs" mkdir -p $CMakeDir || exit 1 @@ -101,6 +135,8 @@ else if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ] || [ ! -d "$CMakeDir/CMakeFiles" ]; then >&2 echo "$ScriptPath: cannot run in '--no-make' mode without a previous successful build step" + + exit 1 fi fi @@ -108,13 +144,24 @@ if [ $status -eq 0 ]; then if [ $ListOnly -ne 0 ]; then - echo "Listing all component and unit test programs" + echo "Listing all ${TestKindDescription} programs" + else + + echo "Running all ${TestKindDescription} programs" + fi + + if [ $UnitOnly -ne 0 ]; then + + find_name_expr=( \( -name 'test_unit*' -o -name 'test.unit.*' \) ) + elif [ $ComponentOnly -ne 0 ]; then + + find_name_expr=( \( -name 'test_component*' -o -name 'test.component.*' \) ) else - echo "Running all component and unit test programs" + find_name_expr=( \( -name 'test_unit*' -o -name 'test.unit.*' -o -name 'test_component*' -o -name 'test.component.*' \) ) fi - for f in $(find $CMakeDir -type f '(' -name 'test_unit*' -o -name 'test.unit.*' -o -name 'test_component*' -o -name 'test.component.*' ')' -exec test -x {} \; -print) + for f in $(find "$CMakeDir" -type f "${find_name_expr[@]}" -exec test -x {} \; -print | sort) do if [ $ListOnly -ne 0 ]; then From 8e7f5e2c8da438354f661d89e2271a265cc579ca Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:04:56 +1000 Subject: [PATCH 05/35] feature: **prepare_cmake.sh**: added '--no-cpp' / `NO_CSTRING_CPP_API` --- CMakeLists.txt | 18 +++++++++++++++++- examples/CMakeLists.txt | 8 ++++++++ prepare_cmake.sh | 18 ++++++++++++++++-- test/component/CMakeLists.txt | 8 +++++--- test/scratch/CMakeLists.txt | 13 +++++++++---- test/unit/CMakeLists.txt | 11 +++++++---- 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d5686e..fba28fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ # Purpose: Top-level CMake lists file for cstring # # Created: 21st December 2023 -# Updated: 7th September 2025 +# Updated: 2nd August 2026 # # ######################################################################## # @@ -66,6 +66,11 @@ set(CMAKE_CXX_EXTENSIONS ON) if(MSVC) + if(MSVC_VERSION LESS 1800) + + add_compile_options("/wd4996") + endif() + if(MSVC_VERSION LESS 1930) set(CMAKE_C_STANDARD 90) @@ -89,6 +94,7 @@ endif(MSVC) # ########################################################## # dependencies, features, includes, and options + # ################################################ # includes - 1 @@ -100,8 +106,18 @@ include(TargetMacros) # ################################################ # dependencies, features, and options + +# ###################################### +# options + option(BUILD_EXAMPLES "Build examples" ON) +option(BUILD_TESTING "Build tests" ON) + + +# ###################################### +# features + # ###################################### # dependencies diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5d65590..64b0b20 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -35,6 +35,14 @@ endif() foreach(d c cpp) + if(NO_CSTRING_CPP_API) + + if ("${d}" EQUAL "cpp") + + continue() + endif() + endif() + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${d}") add_subdirectory(${d}) diff --git a/prepare_cmake.sh b/prepare_cmake.sh index 564d023..6f8842d 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -18,6 +18,7 @@ Configuration=Release ExamplesDisabled=0 MSVC_MT=0 MinGW="${MinGW:=0}" +NO_cxx=0 RunMake=0 STLSoftDirGiven= TestingDisabled=0 @@ -54,6 +55,10 @@ while [[ $# -gt 0 ]]; do MSVC_MT=1 ;; + --no-cpp|--no-cxx|-C) + + NO_cxx=1 + ;; --run-make|-m) RunMake=1 @@ -91,7 +96,9 @@ Flags/options: -T --disable-testing - disables building of tests (by setting BUILD_TESTING=OFF) + disables building of tests (by setting BUILD_TESTING=OFF). Unless + testing is disabled the STLSoft and xTests libraries will be + required to be available to CMake --mingw uses explicitly the "MinGW Makefiles" generator, and defaults the @@ -101,6 +108,11 @@ Flags/options: when using Visual C++ (MSVC), the static runtime library will be selected; the default is the dynamic runtime library + -C + --no-cpp + --no-cxx + does not install, prepare, or use C++ API (which requires STLSoft) + -m --run-make executes make after a successful running of CMake @@ -144,6 +156,7 @@ echo "Executing CMake (in ${CMakeDir})" if [ $ExamplesDisabled -eq 0 ]; then CMakeBuildExamplesFlag="ON" ; else CMakeBuildExamplesFlag="OFF" ; fi if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="ON" ; fi +if [ $NO_cxx -eq 0 ]; then CMakeNoCppApiFlag="OFF" ; else CMakeNoCppApiFlag="ON" ; fi if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi if [ $TestingDisabled -eq 0 ]; then CMakeBuildTestingFlag="ON" ; else CMakeBuildTestingFlag="OFF" ; fi if [ $VerboseMakefile -eq 0 ]; then CMakeVerboseMakefileFlag="OFF" ; else CMakeVerboseMakefileFlag="ON" ; fi @@ -155,6 +168,7 @@ if [ $MinGW -ne 0 ]; then -DBUILD_EXAMPLES:BOOL=$CMakeBuildExamplesFlag \ -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ + -DNO_CSTRING_CPP_API:BOOL=$CMakeNoCppApiFlag \ -G "MinGW Makefiles" \ -S $Dir \ -B $CMakeDir \ @@ -168,12 +182,12 @@ else -DCMAKE_BUILD_TYPE=$Configuration \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ + -DNO_CSTRING_CPP_API:BOOL=$CMakeNoCppApiFlag \ -S $Dir \ -B $CMakeDir \ || (cd ->/dev/null ; exit 1) fi - status=0 if [ $RunMake -ne 0 ]; then diff --git a/test/component/CMakeLists.txt b/test/component/CMakeLists.txt index 7dc68f4..ab18c18 100644 --- a/test/component/CMakeLists.txt +++ b/test/component/CMakeLists.txt @@ -1,3 +1,5 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -add_subdirectory(test.component.cstring_readline) -add_subdirectory(test.component.cstring_writeline) \ No newline at end of file +if(NOT NO_CSTRING_CPP_API) + + add_subdirectory(test.component.cstring_readline) + add_subdirectory(test.component.cstring_writeline) +endif() diff --git a/test/scratch/CMakeLists.txt b/test/scratch/CMakeLists.txt index 2fd2d42..ded91e8 100644 --- a/test/scratch/CMakeLists.txt +++ b/test/scratch/CMakeLists.txt @@ -1,8 +1,13 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -add_subdirectory(libver) +if(NOT NO_CSTRING_CPP_API) + + add_subdirectory(libver) +endif() add_subdirectory(test.scratch.auto_buffer) add_subdirectory(test.scratch.cstring) add_subdirectory(test.scratch.cstring_create) add_subdirectory(test.scratch.cstring_vector) -add_subdirectory(test.scratch.cstring.dynload) -add_subdirectory(test.scratch.HGLOBAL_on_x64) +if(NOT NO_CSTRING_CPP_API) + + add_subdirectory(test.scratch.cstring.dynload) + add_subdirectory(test.scratch.HGLOBAL_on_x64) +endif() diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index c79eab9..f9c5d24 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,8 +1,11 @@ -add_subdirectory(test.unit.cstring.1) -add_subdirectory(test.unit.cstring.2) -add_subdirectory(test.unit.cstring.auto_buffer) -add_subdirectory(test.unit.cstring.cstring_getStatusCodeString) +if(NOT NO_CSTRING_CPP_API) + + add_subdirectory(test.unit.cstring.1) + add_subdirectory(test.unit.cstring.2) + add_subdirectory(test.unit.cstring.auto_buffer) + add_subdirectory(test.unit.cstring.cstring_getStatusCodeString) +endif() add_subdirectory(test.unit.cstring.cstring_vector) From 0bf4f0d27fd628d5d970df1eb971998f2d6fb248 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:24:14 +1000 Subject: [PATCH 06/35] feature: CI: using '--no-cpp' / `NO_CSTRING_CPP_API` --- .github/workflows/cmake-multi-platform.yml | 77 +++++++++++++++++++++- CHANGES.md | 6 +- CMakeLists.txt | 2 + 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index ff254a3..6ea1daa 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -4,9 +4,16 @@ name: CMake on multiple platforms on: push: - branches: [ "master", "dev", "gha" ] + branches: + - master + - dev + - boileplate + - rc1 + - rc2 + - rc3 + - rc4 + - rc5 pull_request: - branches: [ "master", "dev", "gha" ] jobs: build: @@ -90,3 +97,69 @@ jobs: # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: ctest --build-config ${{ matrix.build_type }} + + no-cpp: + name: Build with --no-cpp + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies (STLSoft + shwild + xTests) + shell: bash + run: | + set -euo pipefail + + DEPS="${RUNNER_TEMP}/sis-deps" + STLSRC="${RUNNER_TEMP}/stlsoft-src" + STLBUILD="${RUNNER_TEMP}/stlsoft-build" + SHWSRC="${RUNNER_TEMP}/shwild-src" + SHWBUILD="${RUNNER_TEMP}/shwild-build" + XTSRC="${RUNNER_TEMP}/xtests-src" + XTBUILD="${RUNNER_TEMP}/xtests-build" + + mkdir -p "$DEPS" + + git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" + cmake -S "$STLSRC" -B "$STLBUILD" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$STLBUILD" --parallel + cmake --install "$STLBUILD" + + git clone --depth 1 https://github.com/synesissoftware/shwild "$SHWSRC" + cmake -S "$SHWSRC" -B "$SHWBUILD" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$SHWBUILD" --parallel + cmake --install "$SHWBUILD" + + git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" + cmake -S "$XTSRC" -B "$XTBUILD" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$XTBUILD" --parallel + cmake --install "$XTBUILD" + + echo "SIS_DEPS=$DEPS" >> "$GITHUB_ENV" + + - name: Configure and build via prepare_cmake.sh --no-cpp + shell: bash + run: | + set -euo pipefail + export CMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" + ./prepare_cmake.sh --no-cpp -m -s "${{ env.SIS_DEPS }}" + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/_build" ./run_all_unit_tests.sh -M --unit-only diff --git a/CHANGES.md b/CHANGES.md index e584ce8..142003f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -111,7 +111,7 @@ ## 3.4.1 - 7th October 2005 -* Makefiles now build libraries whose names include the major version number, e.g. `cstring.3.vc6.lib`, in addition to the unversioned form, e.g. `cstring.vc6.lib`; +* Makefiles now build libraries whose names include the major version number, e.g. **cstring.3.vc6.lib**, in addition to the unversioned form, e.g. **cstring.vc6.lib**; * Type `cstring_flags_t` is defined to disambiguate flags params from size params (which use `size_t`); * Added `CSTRING_RC_CANNOTYIELDFROMSO` return code, used when trying to yield a string from a dynamic library implementation that has been allocated using `realloc()`; * `cstring_yield()` has been deprecated in favour of `cstring_yield2()`; define `CSTRING_OBSOLETE` for the old behaviour; @@ -120,14 +120,14 @@ ## 3.3.1 - 8th August 2005 * Changed the memory allocation algorithm such that each reallocation is at least twice the size of the extant block; -* Now dynamically loads the `CoTaskMemRealloc` function from **OLE32.DLL**, easing the linking burden when working with a variety of compilers; +* Now dynamically loads the `CoTaskMemRealloc()` function from **OLE32.DLL**, easing the linking burden when working with a variety of compilers; ## 3.2.1 - 29th July 2005 * Initial public release of this formerly proprietary library from Synesis Software; * Plain-C library, platform/compiler independent; -* When compiled under Win32, provides facility to use Win32 Global, Process Heap and COM Task Allocator memory, rather than the default C library `realloc()`; +* When compiled under Win32, provides facility to use Win32 **Global**, **Process Heap** and **COM Task Allocator** memory, rather than the default C library `realloc()`; diff --git a/CMakeLists.txt b/CMakeLists.txt index fba28fa..54c7d5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,8 @@ option(BUILD_EXAMPLES "Build examples" ON) option(BUILD_TESTING "Build tests" ON) +option(NO_CSTRING_CPP_API "Disable C++ API (and associated C++ examples/tests)" OFF) + # ###################################### # features From 9ae49393255c80833a0b8be6e1afb0a73a6224d7 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:26:11 +1000 Subject: [PATCH 07/35] fix --- .github/workflows/cmake-multi-platform.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index 6ea1daa..e8fd300 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -155,8 +155,11 @@ jobs: shell: bash run: | set -euo pipefail + # Prefer CMAKE_PREFIX_PATH (find_package) over prepare_cmake -s / + # -DSTLSOFT: xTests::core links STLSoft::STLSoft, which only exists + # when the STLSoft CMake package is imported. export CMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" - ./prepare_cmake.sh --no-cpp -m -s "${{ env.SIS_DEPS }}" + ./prepare_cmake.sh --no-cpp -m - name: Run unit tests shell: bash From 9c01f09454571b83c4defa3c971c68b39a90049f Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:28:19 +1000 Subject: [PATCH 08/35] chore: standardising all test implementation file names --- test/component/test.component.cstring_readline/CMakeLists.txt | 3 +-- .../{test.component.cstring_readline.cpp => entry.cpp} | 2 +- test/component/test.component.cstring_writeline/CMakeLists.txt | 2 +- .../{test.component.cstring_writeline.cpp => entry.cpp} | 2 +- test/scratch/libver/CMakeLists.txt | 3 +-- test/scratch/libver/{main.cpp => entry.cpp} | 0 .../{test.scratch.HGLOBAL_on_x64.cpp => entry.cpp} | 0 test/scratch/test.scratch.auto_buffer/CMakeLists.txt | 3 +-- .../{test.scratch.auto_buffer.c => entry.c} | 2 +- .../{test.scratch.cstring.dynload.cpp => entry.cpp} | 2 +- test/scratch/test.scratch.cstring/CMakeLists.txt | 3 +-- .../test.scratch.cstring/{test.scratch.cstring.c => entry.c} | 2 +- test/scratch/test.scratch.cstring_create/CMakeLists.txt | 2 +- .../{test.scratch.cstring_create.c => entry.c} | 0 test/scratch/test.scratch.cstring_vector/CMakeLists.txt | 2 +- .../{test.scratch.cstring_vector.c => entry.c} | 0 test/unit/test.unit.cstring.1/CMakeLists.txt | 3 +-- .../test.unit.cstring.1/{test.unit.cstring.1.cpp => entry.cpp} | 2 +- test/unit/test.unit.cstring.2/CMakeLists.txt | 3 +-- .../test.unit.cstring.2/{test.unit.cstring.2.cpp => entry.cpp} | 2 +- test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt | 3 +-- .../{test.unit.cstring.auto_buffer.cpp => entry.cpp} | 2 +- .../CMakeLists.txt | 3 +-- ....unit.cstring.cstring_getStatusCodeString.cpp => entry.cpp} | 2 +- test/unit/test.unit.cstring.cstring_vector/CMakeLists.txt | 3 +-- .../{test.unit.cstring.cstring_vector.c => entry.c} | 0 26 files changed, 21 insertions(+), 30 deletions(-) rename test/component/test.component.cstring_readline/{test.component.cstring_readline.cpp => entry.cpp} (99%) rename test/component/test.component.cstring_writeline/{test.component.cstring_writeline.cpp => entry.cpp} (99%) rename test/scratch/libver/{main.cpp => entry.cpp} (100%) rename test/scratch/test.scratch.HGLOBAL_on_x64/{test.scratch.HGLOBAL_on_x64.cpp => entry.cpp} (100%) rename test/scratch/test.scratch.auto_buffer/{test.scratch.auto_buffer.c => entry.c} (97%) rename test/scratch/test.scratch.cstring.dynload/{test.scratch.cstring.dynload.cpp => entry.cpp} (98%) rename test/scratch/test.scratch.cstring/{test.scratch.cstring.c => entry.c} (99%) rename test/scratch/test.scratch.cstring_create/{test.scratch.cstring_create.c => entry.c} (100%) rename test/scratch/test.scratch.cstring_vector/{test.scratch.cstring_vector.c => entry.c} (100%) rename test/unit/test.unit.cstring.1/{test.unit.cstring.1.cpp => entry.cpp} (99%) rename test/unit/test.unit.cstring.2/{test.unit.cstring.2.cpp => entry.cpp} (99%) rename test/unit/test.unit.cstring.auto_buffer/{test.unit.cstring.auto_buffer.cpp => entry.cpp} (99%) rename test/unit/test.unit.cstring.cstring_getStatusCodeString/{test.unit.cstring.cstring_getStatusCodeString.cpp => entry.cpp} (98%) rename test/unit/test.unit.cstring.cstring_vector/{test.unit.cstring.cstring_vector.c => entry.c} (100%) diff --git a/test/component/test.component.cstring_readline/CMakeLists.txt b/test/component/test.component.cstring_readline/CMakeLists.txt index 02330ea..5dad2a6 100644 --- a/test/component/test.component.cstring_readline/CMakeLists.txt +++ b/test/component/test.component.cstring_readline/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_automated_test_program(test_component_cstring_cstring_readline test.component.cstring_readline.cpp) +define_automated_test_program(test_component_cstring_cstring_readline entry.cpp) diff --git a/test/component/test.component.cstring_readline/test.component.cstring_readline.cpp b/test/component/test.component.cstring_readline/entry.cpp similarity index 99% rename from test/component/test.component.cstring_readline/test.component.cstring_readline.cpp rename to test/component/test.component.cstring_readline/entry.cpp index 74d7edf..0fd4a27 100644 --- a/test/component/test.component.cstring_readline/test.component.cstring_readline.cpp +++ b/test/component/test.component.cstring_readline/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.component.cstring_readline.cpp + * File: test.component.cstring_readline/entry.cpp * * Purpose: Unit-tests `cstring_readline()`. * diff --git a/test/component/test.component.cstring_writeline/CMakeLists.txt b/test/component/test.component.cstring_writeline/CMakeLists.txt index d88f68c..5cfac58 100644 --- a/test/component/test.component.cstring_writeline/CMakeLists.txt +++ b/test/component/test.component.cstring_writeline/CMakeLists.txt @@ -1,2 +1,2 @@ list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_automated_test_program(test_component_cstring_cstring_writeline test.component.cstring_writeline.cpp) +define_automated_test_program(test_component_cstring_cstring_writeline entry.cpp) diff --git a/test/component/test.component.cstring_writeline/test.component.cstring_writeline.cpp b/test/component/test.component.cstring_writeline/entry.cpp similarity index 99% rename from test/component/test.component.cstring_writeline/test.component.cstring_writeline.cpp rename to test/component/test.component.cstring_writeline/entry.cpp index 55e14c5..e9d7a99 100644 --- a/test/component/test.component.cstring_writeline/test.component.cstring_writeline.cpp +++ b/test/component/test.component.cstring_writeline/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.component.cstring_writeline.cpp + * File: test.component.cstring_writeline/entry.cpp * * Purpose: Unit-tests of `cstring_write()` and `cstring_writeline()`. * diff --git a/test/scratch/libver/CMakeLists.txt b/test/scratch/libver/CMakeLists.txt index f7b34a2..55fb744 100644 --- a/test/scratch/libver/CMakeLists.txt +++ b/test/scratch/libver/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_example_program(libver main.cpp) +define_example_program(libver entry.cpp) diff --git a/test/scratch/libver/main.cpp b/test/scratch/libver/entry.cpp similarity index 100% rename from test/scratch/libver/main.cpp rename to test/scratch/libver/entry.cpp diff --git a/test/scratch/test.scratch.HGLOBAL_on_x64/test.scratch.HGLOBAL_on_x64.cpp b/test/scratch/test.scratch.HGLOBAL_on_x64/entry.cpp similarity index 100% rename from test/scratch/test.scratch.HGLOBAL_on_x64/test.scratch.HGLOBAL_on_x64.cpp rename to test/scratch/test.scratch.HGLOBAL_on_x64/entry.cpp diff --git a/test/scratch/test.scratch.auto_buffer/CMakeLists.txt b/test/scratch/test.scratch.auto_buffer/CMakeLists.txt index 269b6c9..159c1cc 100644 --- a/test/scratch/test.scratch.auto_buffer/CMakeLists.txt +++ b/test/scratch/test.scratch.auto_buffer/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_example_program(test_scratch_cstring_auto_buffer test.scratch.auto_buffer.c) +define_example_program(test_scratch_cstring_auto_buffer entry.c) diff --git a/test/scratch/test.scratch.auto_buffer/test.scratch.auto_buffer.c b/test/scratch/test.scratch.auto_buffer/entry.c similarity index 97% rename from test/scratch/test.scratch.auto_buffer/test.scratch.auto_buffer.c rename to test/scratch/test.scratch.auto_buffer/entry.c index b2ef65b..e0208ad 100644 --- a/test/scratch/test.scratch.auto_buffer/test.scratch.auto_buffer.c +++ b/test/scratch/test.scratch.auto_buffer/entry.c @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.auto_buffer.c + * File: test.scratch.auto_buffer/entry.c * * Purpose: Implementation file for the test.scratch.auto_buffer project. * diff --git a/test/scratch/test.scratch.cstring.dynload/test.scratch.cstring.dynload.cpp b/test/scratch/test.scratch.cstring.dynload/entry.cpp similarity index 98% rename from test/scratch/test.scratch.cstring.dynload/test.scratch.cstring.dynload.cpp rename to test/scratch/test.scratch.cstring.dynload/entry.cpp index 74d99d2..0ed3ed7 100644 --- a/test/scratch/test.scratch.cstring.dynload/test.scratch.cstring.dynload.cpp +++ b/test/scratch/test.scratch.cstring.dynload/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.cstring.dynload.cpp + * File: test.scratch.cstring.dynload/entry.cpp * * Purpose: Implementation file for the test.scratch.cstring.dynload project. * diff --git a/test/scratch/test.scratch.cstring/CMakeLists.txt b/test/scratch/test.scratch.cstring/CMakeLists.txt index d0c0cc6..db13203 100644 --- a/test/scratch/test.scratch.cstring/CMakeLists.txt +++ b/test/scratch/test.scratch.cstring/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_example_program(test_scratch_cstring test.scratch.cstring.c) +define_example_program(test_scratch_cstring entry.c) diff --git a/test/scratch/test.scratch.cstring/test.scratch.cstring.c b/test/scratch/test.scratch.cstring/entry.c similarity index 99% rename from test/scratch/test.scratch.cstring/test.scratch.cstring.c rename to test/scratch/test.scratch.cstring/entry.c index ec156bb..ab4133c 100644 --- a/test/scratch/test.scratch.cstring/test.scratch.cstring.c +++ b/test/scratch/test.scratch.cstring/entry.c @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.cstring.c + * File: test.scratch.cstring/entry.c * * Purpose: Implementation file for the test.scratch.cstring project. * diff --git a/test/scratch/test.scratch.cstring_create/CMakeLists.txt b/test/scratch/test.scratch.cstring_create/CMakeLists.txt index 7d7769b..1e29d89 100644 --- a/test/scratch/test.scratch.cstring_create/CMakeLists.txt +++ b/test/scratch/test.scratch.cstring_create/CMakeLists.txt @@ -1,2 +1,2 @@ list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4477) -define_example_program(test_scratch_cstring_create test.scratch.cstring_create.c) +define_example_program(test_scratch_cstring_create entry.c) diff --git a/test/scratch/test.scratch.cstring_create/test.scratch.cstring_create.c b/test/scratch/test.scratch.cstring_create/entry.c similarity index 100% rename from test/scratch/test.scratch.cstring_create/test.scratch.cstring_create.c rename to test/scratch/test.scratch.cstring_create/entry.c diff --git a/test/scratch/test.scratch.cstring_vector/CMakeLists.txt b/test/scratch/test.scratch.cstring_vector/CMakeLists.txt index 6b29464..7088862 100644 --- a/test/scratch/test.scratch.cstring_vector/CMakeLists.txt +++ b/test/scratch/test.scratch.cstring_vector/CMakeLists.txt @@ -1,3 +1,3 @@ list(APPEND X_GCC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED format format-extra-args) list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4127 4473 4996) -define_example_program(test_scratch_cstring_vector test.scratch.cstring_vector.c) +define_example_program(test_scratch_cstring_vector entry.c) diff --git a/test/scratch/test.scratch.cstring_vector/test.scratch.cstring_vector.c b/test/scratch/test.scratch.cstring_vector/entry.c similarity index 100% rename from test/scratch/test.scratch.cstring_vector/test.scratch.cstring_vector.c rename to test/scratch/test.scratch.cstring_vector/entry.c diff --git a/test/unit/test.unit.cstring.1/CMakeLists.txt b/test/unit/test.unit.cstring.1/CMakeLists.txt index 7b6bcbe..71d6cbb 100644 --- a/test/unit/test.unit.cstring.1/CMakeLists.txt +++ b/test/unit/test.unit.cstring.1/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_automated_test_program(test_unit_cstring_1 test.unit.cstring.1.cpp) +define_automated_test_program(test_unit_cstring_1 entry.cpp) diff --git a/test/unit/test.unit.cstring.1/test.unit.cstring.1.cpp b/test/unit/test.unit.cstring.1/entry.cpp similarity index 99% rename from test/unit/test.unit.cstring.1/test.unit.cstring.1.cpp rename to test/unit/test.unit.cstring.1/entry.cpp index 5ca61ab..0f09234 100644 --- a/test/unit/test.unit.cstring.1/test.unit.cstring.1.cpp +++ b/test/unit/test.unit.cstring.1/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.1.cpp + * File: test.unit.cstring.1/entry.cpp * * Purpose: Unit-tests for general functionality. * diff --git a/test/unit/test.unit.cstring.2/CMakeLists.txt b/test/unit/test.unit.cstring.2/CMakeLists.txt index b495fa3..9b69680 100644 --- a/test/unit/test.unit.cstring.2/CMakeLists.txt +++ b/test/unit/test.unit.cstring.2/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_automated_test_program(test_unit_cstring_2 test.unit.cstring.2.cpp) +define_automated_test_program(test_unit_cstring_2 entry.cpp) diff --git a/test/unit/test.unit.cstring.2/test.unit.cstring.2.cpp b/test/unit/test.unit.cstring.2/entry.cpp similarity index 99% rename from test/unit/test.unit.cstring.2/test.unit.cstring.2.cpp rename to test/unit/test.unit.cstring.2/entry.cpp index 0aee4a0..e5a1d3a 100644 --- a/test/unit/test.unit.cstring.2/test.unit.cstring.2.cpp +++ b/test/unit/test.unit.cstring.2/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.2.cpp + * File: test.unit.cstring.2/entry.cpp * * Purpose: Unit-tests for general functionality. * diff --git a/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt b/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt index 61a28d8..5ea9455 100644 --- a/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt +++ b/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_automated_test_program(test_unit_cstring_auto_buffer test.unit.cstring.auto_buffer.cpp) +define_automated_test_program(test_unit_cstring_auto_buffer entry.cpp) diff --git a/test/unit/test.unit.cstring.auto_buffer/test.unit.cstring.auto_buffer.cpp b/test/unit/test.unit.cstring.auto_buffer/entry.cpp similarity index 99% rename from test/unit/test.unit.cstring.auto_buffer/test.unit.cstring.auto_buffer.cpp rename to test/unit/test.unit.cstring.auto_buffer/entry.cpp index c85615c..d79098c 100644 --- a/test/unit/test.unit.cstring.auto_buffer/test.unit.cstring.auto_buffer.cpp +++ b/test/unit/test.unit.cstring.auto_buffer/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.auto_buffer.cpp + * File: test.unit.cstring.auto_buffer/entry.cpp * * Purpose: Implementation file for the test.unit.cstring.auto_buffer project. * diff --git a/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt b/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt index 6022e01..dc1340e 100644 --- a/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt +++ b/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_automated_test_program(test_unit_cstring_cstring_getStatusCodeString test.unit.cstring.cstring_getStatusCodeString.cpp) +define_automated_test_program(test_unit_cstring_cstring_getStatusCodeString entry.cpp) diff --git a/test/unit/test.unit.cstring.cstring_getStatusCodeString/test.unit.cstring.cstring_getStatusCodeString.cpp b/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.cpp similarity index 98% rename from test/unit/test.unit.cstring.cstring_getStatusCodeString/test.unit.cstring.cstring_getStatusCodeString.cpp rename to test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.cpp index 8fea285..b8ef6fb 100644 --- a/test/unit/test.unit.cstring.cstring_getStatusCodeString/test.unit.cstring.cstring_getStatusCodeString.cpp +++ b/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.cpp @@ -1,5 +1,5 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.cstring_getStatusCodeString.cpp + * File: test.unit.cstring.cstring_getStatusCodeString/entry.cpp * * Purpose: Unit-tests `cstring_error()`, `cstring_getStatusCodeString()`. * diff --git a/test/unit/test.unit.cstring.cstring_vector/CMakeLists.txt b/test/unit/test.unit.cstring.cstring_vector/CMakeLists.txt index 5ccb333..d0288b6 100644 --- a/test/unit/test.unit.cstring.cstring_vector/CMakeLists.txt +++ b/test/unit/test.unit.cstring.cstring_vector/CMakeLists.txt @@ -1,2 +1 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -define_automated_test_program(test_unit_cstring_cstring_vector test.unit.cstring.cstring_vector.c) +define_automated_test_program(test_unit_cstring_cstring_vector entry.c) diff --git a/test/unit/test.unit.cstring.cstring_vector/test.unit.cstring.cstring_vector.c b/test/unit/test.unit.cstring.cstring_vector/entry.c similarity index 100% rename from test/unit/test.unit.cstring.cstring_vector/test.unit.cstring.cstring_vector.c rename to test/unit/test.unit.cstring.cstring_vector/entry.c From 0bb4ac22fcbefa975e9a418d0cd06cb2caad6f4d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:38:37 +1000 Subject: [PATCH 09/35] chore: convert three unit-tests from C++ to C Move cstring.2, auto_buffer, and cstring_getStatusCodeString to entry.c so they build under NO_CSTRING_CPP_API. --- test/unit/CMakeLists.txt | 7 +- test/unit/test.unit.cstring.2/CMakeLists.txt | 2 +- .../{entry.cpp => entry.c} | 82 ++++++------- .../CMakeLists.txt | 2 +- .../{entry.cpp => entry.c} | 44 +++---- .../CMakeLists.txt | 2 +- .../{entry.cpp => entry.c} | 108 ++++++++---------- 7 files changed, 108 insertions(+), 139 deletions(-) rename test/unit/test.unit.cstring.2/{entry.cpp => entry.c} (91%) rename test/unit/test.unit.cstring.auto_buffer/{entry.cpp => entry.c} (94%) rename test/unit/test.unit.cstring.cstring_getStatusCodeString/{entry.cpp => entry.c} (64%) diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index f9c5d24..5fb1b6f 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -2,12 +2,11 @@ if(NOT NO_CSTRING_CPP_API) add_subdirectory(test.unit.cstring.1) - add_subdirectory(test.unit.cstring.2) - add_subdirectory(test.unit.cstring.auto_buffer) - add_subdirectory(test.unit.cstring.cstring_getStatusCodeString) endif() +add_subdirectory(test.unit.cstring.2) +add_subdirectory(test.unit.cstring.auto_buffer) +add_subdirectory(test.unit.cstring.cstring_getStatusCodeString) add_subdirectory(test.unit.cstring.cstring_vector) # ############################## end of file ############################# # - diff --git a/test/unit/test.unit.cstring.2/CMakeLists.txt b/test/unit/test.unit.cstring.2/CMakeLists.txt index 9b69680..3dc32ed 100644 --- a/test/unit/test.unit.cstring.2/CMakeLists.txt +++ b/test/unit/test.unit.cstring.2/CMakeLists.txt @@ -1 +1 @@ -define_automated_test_program(test_unit_cstring_2 entry.cpp) +define_automated_test_program(test_unit_cstring_2 entry.c) diff --git a/test/unit/test.unit.cstring.2/entry.cpp b/test/unit/test.unit.cstring.2/entry.c similarity index 91% rename from test/unit/test.unit.cstring.2/entry.cpp rename to test/unit/test.unit.cstring.2/entry.c index e5a1d3a..4e83762 100644 --- a/test/unit/test.unit.cstring.2/entry.cpp +++ b/test/unit/test.unit.cstring.2/entry.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.2/entry.cpp + * File: test.unit.cstring.2/entry.c * * Purpose: Unit-tests for general functionality. * * Created: 4th June 2009 - * Updated: 2nd September 2025 + * Updated: 2nd August 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -28,38 +28,35 @@ /* STLSoft header files */ #include -#ifdef WIN32 -# include -#endif /* Standard C header files */ +#include #include #include +#include /* ///////////////////////////////////////////////////////////////////////// * forward declarations */ -namespace -{ - - static void test_createN(void); - static void test_insert(void); - static void test_insertLen(void); - static void test_replace(void); - static void test_replaceLen(void); - static void test_replaceAll_1(void); - static void test_replaceAll_2(void); - static void test_replaceAll_3(void); -} // anonymous namespace +static void test_createN(void); +static void test_insert(void); +static void test_insertLen(void); +static void test_replace(void); +static void test_replaceLen(void); +static void test_replaceAll_1(void); +static void test_replaceAll_2(void); +static void test_replaceAll_3(void); /* ///////////////////////////////////////////////////////////////////////// * constants & definitions */ -const char TEST_FILE_NAME[] = "test.unit.cstring.2.txt"; +static char const TEST_FILE_NAME[] = "test.unit.cstring.2.txt"; + +static char const alphabet[] = "abcdefghijklmnopqrstuvwxyz"; /* ///////////////////////////////////////////////////////////////////////// @@ -122,12 +119,7 @@ int main(int argc, char **argv) * test function implementations */ -namespace -{ - - static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz"; - -static void test_createN() +static void test_createN(void) { { for (size_t volatile i = 0; i != 1000000u; i = (0u == i) ? 1u : i * 10u) { @@ -137,7 +129,7 @@ static void test_createN() if (CSTRING_RC_SUCCESS == rc) { - TEST_INT_EQ(size_t(i), str.len); + TEST_INT_EQ((size_t)i, str.len); TEST_PTR_NE(NULL, str.ptr); TEST_INT_GE(str.len, str.capacity); @@ -157,9 +149,9 @@ static void test_createN() }} } -static void test_insert() +static void test_insert(void) { - { // Forwards + { /* Forwards */ cstring_t str = cstring_t_DEFAULT; @@ -170,10 +162,10 @@ static void test_insert() { for (size_t i = 0; i != STLSOFT_NUM_ELEMENTS(alphabet) - 1; ++i) { - const char sz[2] = { alphabet[i], '\0' }; - cstring_insert(&str, int(i), sz); + char const sz[2] = { alphabet[i], '\0' }; + cstring_insert(&str, (int)i, sz); - XTESTS_TEST_MULTIBYTE_STRING_EQUAL_N(alphabet, str.ptr, int(i)); + XTESTS_TEST_MULTIBYTE_STRING_EQUAL_N(alphabet, str.ptr, (int)i); }} cstring_destroy(&str); @@ -184,7 +176,7 @@ static void test_insert() TEST_INT_EQ(0, str.flags); } - { // Backwards + { /* Backwards */ cstring_t str = cstring_t_DEFAULT; @@ -195,10 +187,10 @@ static void test_insert() { for (size_t i = 0; i != STLSOFT_NUM_ELEMENTS(alphabet) - 1; ++i) { - const char sz[2] = { alphabet[(STLSOFT_NUM_ELEMENTS(alphabet) - 1) - (1 + i)], '\0' }; + char const sz[2] = { alphabet[(STLSOFT_NUM_ELEMENTS(alphabet) - 1) - (1 + i)], '\0' }; cstring_insert(&str, 0, sz); - XTESTS_TEST_MULTIBYTE_STRING_EQUAL_N(alphabet + ((STLSOFT_NUM_ELEMENTS(alphabet) - 1) - (1 + i)), static_cast(str.ptr), int(i)); + XTESTS_TEST_MULTIBYTE_STRING_EQUAL_N(alphabet + ((STLSOFT_NUM_ELEMENTS(alphabet) - 1) - (1 + i)), (char const*)str.ptr, (int)i); }} cstring_destroy(&str); @@ -210,7 +202,7 @@ static void test_insert() } } -static void test_insertLen() +static void test_insertLen(void) { cstring_t str = cstring_t_DEFAULT; @@ -265,7 +257,7 @@ static void test_insertLen() { for (size_t i = 0; i != 13; ++i) { - const char ch = (char)('z' - i); + char const ch = (char)('z' - i); cstring_insertLen(&str, CSTRING_FROM_END(1 + i), &ch, 1); }} @@ -282,7 +274,7 @@ static void test_insertLen() TEST_INT_EQ(0, str.flags); } -static void test_replace() +static void test_replace(void) { cstring_t str = cstring_t_DEFAULT; @@ -312,7 +304,7 @@ static void test_replace() TEST_INT_EQ(0, str.flags); } -static void test_replaceLen() +static void test_replaceLen(void) { cstring_t str; CSTRING_RC rc = cstring_create(&str, "abcdefghijklmnopqrstuvwxyz"); @@ -330,9 +322,9 @@ static void test_replaceLen() { for (size_t i = 0; i != str.len; ++i) { - char ch = static_cast(toupper(str.ptr[i])); + char ch = (char)toupper((unsigned char)str.ptr[i]); - cstring_replaceLen(&str, int(i), 1u, &ch, 1u); + cstring_replaceLen(&str, (int)i, 1u, &ch, 1u); }} TEST_INT_EQ(26u, str.len); @@ -349,7 +341,7 @@ static void test_replaceLen() } } -static void test_replaceAll_1() +static void test_replaceAll_1(void) { { cstring_t str = cstring_t_DEFAULT; @@ -391,7 +383,7 @@ static void test_replaceAll_1() } } -static void test_replaceAll_2() +static void test_replaceAll_2(void) { { cstring_t str; @@ -438,7 +430,7 @@ static void test_replaceAll_2() } } -static void test_replaceAll_3() +static void test_replaceAll_3(void) { { cstring_t str; @@ -588,14 +580,14 @@ static void test_replaceAll_3() { for (size_t i = 0; 0 != str.len; ++i) { - const char sz[2] = { str.ptr[0], '\0' }; + char const sz[2] = { str.ptr[0], '\0' }; rc = cstring_replaceAll(&str, sz, NULL, &n); XTESTS_REQUIRE(XTESTS_TEST_ENUM_EQUAL(CSTRING_RC_SUCCESS, rc)); TEST_INT_EQ(22u - 2 * (1 + i), str.len); TEST_PTR_NE(NULL, str.ptr); -// TEST_MS_EQ("pqrstuvwklpqrstuvwxyz", str.ptr); +/* TEST_MS_EQ("pqrstuvwklpqrstuvwxyz", str.ptr); */ TEST_INT_GE(str.len, str.capacity); TEST_INT_EQ(0, str.flags); TEST_INT_EQ(0u, n); @@ -609,8 +601,6 @@ static void test_replaceAll_3() TEST_INT_EQ(0, str.flags); } } -} // anonymous namespace /* ///////////////////////////// end of file //////////////////////////// */ - diff --git a/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt b/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt index 5ea9455..309fce2 100644 --- a/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt +++ b/test/unit/test.unit.cstring.auto_buffer/CMakeLists.txt @@ -1 +1 @@ -define_automated_test_program(test_unit_cstring_auto_buffer entry.cpp) +define_automated_test_program(test_unit_cstring_auto_buffer entry.c) diff --git a/test/unit/test.unit.cstring.auto_buffer/entry.cpp b/test/unit/test.unit.cstring.auto_buffer/entry.c similarity index 94% rename from test/unit/test.unit.cstring.auto_buffer/entry.cpp rename to test/unit/test.unit.cstring.auto_buffer/entry.c index d79098c..9f11c82 100644 --- a/test/unit/test.unit.cstring.auto_buffer/entry.cpp +++ b/test/unit/test.unit.cstring.auto_buffer/entry.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.auto_buffer/entry.cpp + * File: test.unit.cstring.auto_buffer/entry.c * * Purpose: Implementation file for the test.unit.cstring.auto_buffer project. * * Created: 28th July 2011 - * Updated: 12th January 2024 + * Updated: 2nd August 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -15,6 +15,7 @@ #include + /* ///////////////////////////////////////////////////////////////////////// * includes */ @@ -24,39 +25,31 @@ /* STLSoft header files */ #include -#ifdef WIN32 -# include -#endif -#include -#include -#include /* Standard C header files */ #include + /* ///////////////////////////////////////////////////////////////////////// * forward declarations */ -namespace -{ - - static void test_badFlags(void); - static void test_createEx(void); - static void test_createLenEx(void); - static void test_setCapacity(void); - static void test_assign(void); - static void test_assignLen(void); - static void test_append(void); - static void test_appendLen(void); +static void test_badFlags(void); +static void test_createEx(void); +static void test_createLenEx(void); +static void test_setCapacity(void); +static void test_assign(void); +static void test_assignLen(void); +static void test_append(void); +static void test_appendLen(void); -} // anonymous namespace /* ///////////////////////////////////////////////////////////////////////// * constants & definitions */ -const char TEST_FILE_NAME[] = "test.unit.cstring.auto_buffer.txt"; +static char const TEST_FILE_NAME[] = "test.unit.cstring.auto_buffer.txt"; + /* ///////////////////////////////////////////////////////////////////////// * compiler compatibility @@ -69,6 +62,7 @@ const char TEST_FILE_NAME[] = "test.unit.cstring.auto_buffer.txt"; # pragma warning(disable : 4702) #endif /* compiler */ + /* ///////////////////////////////////////////////////////////////////////// * main */ @@ -101,6 +95,7 @@ int main(int argc, char **argv) return retCode; } + /* ///////////////////////////////////////////////////////////////////////// * compiler compatibility */ @@ -111,13 +106,11 @@ int main(int argc, char **argv) # endif /* compiler */ #endif /* compiler */ + /* ///////////////////////////////////////////////////////////////////////// * test function implementations */ -namespace -{ - static void test_badFlags(void) { static int const goods[] = @@ -511,7 +504,4 @@ static void test_appendLen(void) } -} // anonymous namespace - /* ///////////////////////////// end of file //////////////////////////// */ - diff --git a/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt b/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt index dc1340e..01d3475 100644 --- a/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt +++ b/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt @@ -1 +1 @@ -define_automated_test_program(test_unit_cstring_cstring_getStatusCodeString entry.cpp) +define_automated_test_program(test_unit_cstring_cstring_getStatusCodeString entry.c) diff --git a/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.cpp b/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c similarity index 64% rename from test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.cpp rename to test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c index b8ef6fb..db5e062 100644 --- a/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.cpp +++ b/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.unit.cstring.cstring_getStatusCodeString/entry.cpp + * File: test.unit.cstring.cstring_getStatusCodeString/entry.c * * Purpose: Unit-tests `cstring_error()`, `cstring_getStatusCodeString()`. * * Created: 28th July 2011 - * Updated: 12th January 2024 + * Updated: 2nd August 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -15,6 +15,7 @@ #include + /* ///////////////////////////////////////////////////////////////////////// * includes */ @@ -24,38 +25,54 @@ /* STLSoft header files */ #include -#ifdef WIN32 -# include -#endif -#include -#include -#include /* Standard C header files */ #include + /* ///////////////////////////////////////////////////////////////////////// * forward declarations */ -namespace -{ - - static void test_0(void); - static void test_known(void); - static void test_random(void); +static void test_0(void); +static void test_known(void); +static void test_random(void); - static void test_0_deprecated(void); - static void test_known_deprecated(void); - static void test_random_deprecated(void); +static void test_0_deprecated(void); +static void test_known_deprecated(void); +static void test_random_deprecated(void); -} // anonymous namespace /* ///////////////////////////////////////////////////////////////////////// * constants & definitions */ -const char TEST_FILE_NAME[] = "test.unit.cstring.cstring_getStatusCodeString.txt"; +static char const TEST_FILE_NAME[] = "test.unit.cstring.cstring_getStatusCodeString.txt"; + +static CSTRING_RC const knownCodes[] = +{ + CSTRING_RC_SUCCESS + , CSTRING_RC_OUTOFMEMORY + , CSTRING_RC_FIXED + , CSTRING_RC_BORROWED + , CSTRING_RC_READONLY + , CSTRING_RC_INVALIDARENA + , CSTRING_RC_CUSTOMARENANOTSUPPORTED + , CSTRING_RC_EXCEEDFIXEDCAPACITY + , CSTRING_RC_EXCEEDBORROWEDCAPACITY + , CSTRING_RC_CANNOTYIELDFROMSO + , CSTRING_RC_ARENAOVERLOADED + /* cstring 3.5+ */ + , CSTRING_RC_INVALIDSTREAM + , CSTRING_RC_EOF + , CSTRING_RC_INVALIDSECTION + , CSTRING_RC_IOERROR + /* cstring 3.6.2+ */ + , CSTRING_RC_SYSTEMSPECIFICFAILURE + /* cstring 4.0+ */ + , CSTRING_RC_REQUESTTOOLARGE +}; + /* ///////////////////////////////////////////////////////////////////////// * compiler compatibility @@ -68,6 +85,7 @@ const char TEST_FILE_NAME[] = "test.unit.cstring.cstring_getStatusCodeString.txt # pragma warning(disable : 4702) #endif /* compiler */ + /* ///////////////////////////////////////////////////////////////////////// * main */ @@ -99,6 +117,7 @@ int main(int argc, char **argv) return retCode; } + /* ///////////////////////////////////////////////////////////////////////// * compiler compatibility */ @@ -109,43 +128,17 @@ int main(int argc, char **argv) # endif /* compiler */ #endif /* compiler */ + /* ///////////////////////////////////////////////////////////////////////// * test function implementations */ -namespace -{ - - static CSTRING_RC const knownCodes[] = - { - CSTRING_RC_SUCCESS - , CSTRING_RC_OUTOFMEMORY - , CSTRING_RC_FIXED - , CSTRING_RC_BORROWED - , CSTRING_RC_READONLY - , CSTRING_RC_INVALIDARENA - , CSTRING_RC_CUSTOMARENANOTSUPPORTED - , CSTRING_RC_EXCEEDFIXEDCAPACITY - , CSTRING_RC_EXCEEDBORROWEDCAPACITY - , CSTRING_RC_CANNOTYIELDFROMSO - , CSTRING_RC_ARENAOVERLOADED - /* cstring 3.5+ */ - , CSTRING_RC_INVALIDSTREAM - , CSTRING_RC_EOF - , CSTRING_RC_INVALIDSECTION - , CSTRING_RC_IOERROR - /* cstring 3.6.2+ */ - , CSTRING_RC_SYSTEMSPECIFICFAILURE - /* cstring 4.0+ */ - , CSTRING_RC_REQUESTTOOLARGE - }; - -static void test_0() +static void test_0(void) { XTESTS_TEST_MULTIBYTE_STRING_EQUAL("operation completed successfully", cstring_getStatusCodeString((CSTRING_RC)0)); } -static void test_known() +static void test_known(void) { { for (size_t i = 0; i != STLSOFT_NUM_ELEMENTS(knownCodes); ++i) { @@ -153,24 +146,24 @@ static void test_known() }} } -static void test_random() +static void test_random(void) { { for (size_t i = 0; i != 100000; ++i) { - int r = ::rand(); - CSTRING_RC rc = static_cast(STLSOFT_NUM_ELEMENTS(knownCodes) + r + 1); + int r = rand(); + CSTRING_RC rc = (CSTRING_RC)(STLSOFT_NUM_ELEMENTS(knownCodes) + r + 1); XTESTS_TEST_MULTIBYTE_STRING_EQUAL("<>", cstring_getStatusCodeString(rc)); }} } -static void test_0_deprecated() +static void test_0_deprecated(void) { XTESTS_TEST_MULTIBYTE_STRING_EQUAL("operation completed successfully", cstring_error((CSTRING_RC)0)); } -static void test_known_deprecated() +static void test_known_deprecated(void) { { for (size_t i = 0; i != STLSOFT_NUM_ELEMENTS(knownCodes); ++i) { @@ -178,19 +171,16 @@ static void test_known_deprecated() }} } -static void test_random_deprecated() +static void test_random_deprecated(void) { { for (size_t i = 0; i != 100000; ++i) { - int r = ::rand(); - CSTRING_RC rc = static_cast(STLSOFT_NUM_ELEMENTS(knownCodes) + r + 1); + int r = rand(); + CSTRING_RC rc = (CSTRING_RC)(STLSOFT_NUM_ELEMENTS(knownCodes) + r + 1); XTESTS_TEST_MULTIBYTE_STRING_EQUAL("<>", cstring_error(rc)); }} } -} // anonymous namespace - /* ///////////////////////////// end of file //////////////////////////// */ - From e9a734fd1cf1b45dd315a661b9b9f5655124dfd3 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:43:06 +1000 Subject: [PATCH 10/35] chore: documenting effect of "no C++" option --- CHANGES.md | 8 ++++++++ CMakeLists.txt | 8 ++++++-- README.md | 12 ++++++------ prepare_cmake.sh | 3 ++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 142003f..6b675d3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,14 @@ # **cstring** Changes +## 4.0.13 - 2nd August 2026 + +* Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; +* CI job for `--no-cpp` builds and unit-tests; +* Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); +* Clarified dependencies documentation in **README.md**; + + ## 4.0.12 - 2nd September 2025 * GitHub Actions; diff --git a/CMakeLists.txt b/CMakeLists.txt index 54c7d5e..98653f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,11 +124,15 @@ option(NO_CSTRING_CPP_API "Disable C++ API (and associated C++ examples/tests)" # ###################################### # dependencies # -# required: -# - STLSoft - required for testing; +# required (when BUILD_TESTING): +# - STLSoft - required for testing (also used by remaining C++ tests/examples); # - xTests - required for testing; # # optional: +# - (none) +# +# note: NO_CSTRING_CPP_API skips C++ examples and remaining C++ tests; C +# unit-tests still require STLSoft and xTests. # ############################ diff --git a/README.md b/README.md index a9e4042..6628111 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,6 @@ Extensible dynamic character strings - and arrays of strings - in **C**, for Uni - [Where to get help](#where-to-get-help) - [Contribution guidelines](#contribution-guidelines) - [Dependencies](#dependencies) - - [Tests-only Dependencies](#tests-only-dependencies) - [Related projects](#related-projects) - [License](#license) @@ -123,13 +122,14 @@ Defect reports, feature requests, and pull requests are welcome on https://githu ### Dependencies +The **C** API has no non-standard dependencies. -#### Tests-only Dependencies +| Dependency | Role | Required? | +| ---------- | ---- | --------- | +| [**STLSoft**](https://github.com/synesissoftware/STLSoft) 1.11 | Test headers / remaining C++ tests and examples | ⚪ Tests only (`BUILD_TESTING`) | +| [**xTests**](https://github.com/synesissoftware/xTests) (≥ 0.26) | Unit / component / scratch tests | ⚪ Tests only (`BUILD_TESTING`) | -For unit-testing, **cstring** depends on: - -* [**STLSoft 1.11**](http://github.com/synesissoftware/STLSoft-1.11/); -* [**xTests**](http://github.com/synesissoftware/xTests/); +When supplying the `'--no-cpp'` to **prepare_cmake.sh**, - sets the CMake option `NO_CSTRING_CPP_API=ON` - C++ examples and remaining C++ tests are omitted; the **C** unit-tests still require **STLSoft** and **xTests**. ### Related projects diff --git a/prepare_cmake.sh b/prepare_cmake.sh index 6f8842d..ca4f1a5 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -111,7 +111,8 @@ Flags/options: -C --no-cpp --no-cxx - does not install, prepare, or use C++ API (which requires STLSoft) + omits the C++ API, C++ examples, and remaining C++ tests (CMake + NO_CSTRING_CPP_API). C unit-tests still require STLSoft and xTests -m --run-make From 53f68c39f5fbed7135c38f611f0093e0174ab523 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:44:18 +1000 Subject: [PATCH 11/35] 4.0.13 --- NEWS.md | 1 + README.md | 12 ++---------- include/cstring/cstring.h | 10 +++++----- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/NEWS.md b/NEWS.md index 249822e..d34c890 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,6 +3,7 @@ | Date | News Item | | --------------------- | ------------------------------------------------------------- | +| 2nd August 2026 | Release of [cstring 4.0.13](https://github.com/synesissoftware/cstring/releases/tag/4.0.13) | | 2nd September 2025 | Release of [cstring 4.0.12](https://github.com/synesissoftware/cstring/releases/tag/4.0.12) | | 23rd February 2025 | Release of cstring 4.0.11 | | 25th October 2024 | Release of cstring 4.0.10 | diff --git a/README.md b/README.md index 6628111..c1a73fe 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,14 @@ # cstring -![C](https://img.shields.io/badge/C-00599C?style=flat&logo=c&logoColor=white) -[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) -[![GitHub release](https://img.shields.io/github/v/release/synesissoftware/cstring.svg)](https://github.com/synesissoftware/cstring/releases/latest) -[![Last Commit](https://img.shields.io/github/last-commit/synesissoftware/cstring)](https://github.com/synesissoftware/cstring/commits/master) -[![CMake on multiple platforms](https://github.com/synesissoftware/cstring/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/synesissoftware/cstring/actions/workflows/cmake-multi-platform.yml) +**C**-style **string**s is a small, standalone library, that provides extensible C-style string instances and extensible arrays of such, for Unix and Windows. -Extensible dynamic character strings - and arrays of strings - in **C**, for Unix and Windows. -![Language](https://img.shields.io/badge/C-00599C?style=flat&logo=c%2B%2B&logoColor=white) +![C](https://img.shields.io/badge/C-00599C?style=flat&logo=c&logoColor=white) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![GitHub release](https://img.shields.io/github/v/release/synesissoftware/cstring.svg)](https://github.com/synesissoftware/cstring/releases/latest) [![Last Commit](https://img.shields.io/github/last-commit/synesissoftware/cstring)](https://github.com/synesissoftware/cstring/commits/master) - -**C**-style **string**s is a small, standalone library, that provides extensible C-style string instances and extensible arrays of such. ## Table of Contents diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index 132fcac..df99274 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -4,11 +4,11 @@ * Purpose: Definition of the cstring.core API. * * Created: 16th June 1994 - * Updated: 1st September 2025 + * Updated: 2nd August 2026 * * Home: http://synesis.com.au/software/ * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 1994-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -55,8 +55,8 @@ #ifndef CSTRING_DOCUMENTATION_SKIP_SECTION # define CSTRING_VER_CSTRING_H_CSTRING_MAJOR 3 # define CSTRING_VER_CSTRING_H_CSTRING_MINOR 11 -# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 9 -# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 80 +# define CSTRING_VER_CSTRING_H_CSTRING_REVISION 10 +# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 81 #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ /** \def CSTRING_VER_MAJOR @@ -131,7 +131,7 @@ #define CSTRING_VER_MAJOR 4 #define CSTRING_VER_MINOR 0 -#define CSTRING_VER_PATCH 12 +#define CSTRING_VER_PATCH 13 #define CSTRING_VER_ALPHABETA 0xFF #define CSTRING_VER \ From a8b26333b24679d49237834bc7cfbd560b2d5140 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:50:33 +1000 Subject: [PATCH 12/35] chore: standardised GitHub Actions CI script(s) --- .github/workflows/ci-cell.yml | 332 +++++++++++++++++++++ .github/workflows/ci.yml | 269 +++++++++++++++++ .github/workflows/cmake-multi-platform.yml | 168 ----------- CHANGES.md | 3 + README.md | 2 +- 5 files changed, 605 insertions(+), 169 deletions(-) create mode 100644 .github/workflows/ci-cell.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/cmake-multi-platform.yml diff --git a/.github/workflows/ci-cell.yml b/.github/workflows/ci-cell.yml new file mode 100644 index 0000000..dc1f587 --- /dev/null +++ b/.github/workflows/ci-cell.yml @@ -0,0 +1,332 @@ +name: CI cell + +on: + workflow_call: + inputs: + cell-id: + required: true + type: string + os: + required: true + type: string + c-compiler: + required: true + type: string + cpp-compiler: + required: true + type: string + build-type: + required: false + type: string + default: Release + +jobs: + build: + name: Build (${{ inputs.cell-id }}) + runs-on: ${{ inputs.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Install Clang (Ubuntu) + if: runner.os == 'Linux' && inputs.c-compiler == 'clang' + run: sudo apt-get update && sudo apt-get install -y clang + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: >- + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-cmake + mingw-w64-x86_64-make + + - name: Install test dependencies (STLSoft + shwild + xTests) + shell: bash + run: | + set -euxo pipefail + + DEPS="${RUNNER_TEMP}/sis-deps" + STLSRC="${RUNNER_TEMP}/stlsoft-src" + STLBUILD="${RUNNER_TEMP}/stlsoft-build" + SHWSRC="${RUNNER_TEMP}/shwild-src" + SHWBUILD="${RUNNER_TEMP}/shwild-build" + XTSRC="${RUNNER_TEMP}/xtests-src" + XTBUILD="${RUNNER_TEMP}/xtests-build" + + mkdir -p "$DEPS" + + # 1. STLSoft + git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -S "$STLSRC" -B "$STLBUILD" \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$STLBUILD" --config "${{ inputs.build-type }}" --parallel + cmake --install "$STLBUILD" --config "${{ inputs.build-type }}" + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake -S "$STLSRC" -B "$STLBUILD" -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$STLBUILD" --parallel 2 + cmake --install "$STLBUILD" + else + cmake -S "$STLSRC" -B "$STLBUILD" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$STLBUILD" --parallel + cmake --install "$STLBUILD" + fi + + # 2. shwild + git clone --depth 1 https://github.com/synesissoftware/shwild "$SHWSRC" + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -S "$SHWSRC" -B "$SHWBUILD" \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$SHWBUILD" --config "${{ inputs.build-type }}" --parallel + cmake --install "$SHWBUILD" --config "${{ inputs.build-type }}" + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake -S "$SHWSRC" -B "$SHWBUILD" -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$SHWBUILD" --parallel 2 + cmake --install "$SHWBUILD" + else + cmake -S "$SHWSRC" -B "$SHWBUILD" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$SHWBUILD" --parallel + cmake --install "$SHWBUILD" + fi + + # 3. xTests + git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -S "$XTSRC" -B "$XTBUILD" \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$XTBUILD" --config "${{ inputs.build-type }}" --parallel + cmake --install "$XTBUILD" --config "${{ inputs.build-type }}" + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake -S "$XTSRC" -B "$XTBUILD" -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$XTBUILD" --parallel 2 + cmake --install "$XTBUILD" + else + cmake -S "$XTSRC" -B "$XTBUILD" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$XTBUILD" --parallel + cmake --install "$XTBUILD" + fi + + - name: Configure + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -B build -S . \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=ON + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake -B build -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER=gcc \ + -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=ON + else + cmake -B build -S . \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=ON + fi + + - name: Build + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake --build build --config "${{ inputs.build-type }}" --parallel + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake --build build --parallel 2 + else + cmake --build build --parallel + fi + + - name: Upload build tree + uses: actions/upload-artifact@v4 + with: + name: sis-build-${{ inputs.cell-id }} + path: build + retention-days: 1 + + run-examples: + name: Examples (${{ inputs.cell-id }}) + needs: build + runs-on: ${{ inputs.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: mingw-w64-x86_64-toolchain + + - name: Download build tree + uses: actions/download-artifact@v4 + with: + name: sis-build-${{ inputs.cell-id }} + path: build + + - name: Run examples + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_examples.sh -M + + test-unit: + name: Unit tests (${{ inputs.cell-id }}) + needs: build + runs-on: ${{ inputs.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: mingw-w64-x86_64-toolchain + + - name: Download build tree + uses: actions/download-artifact@v4 + with: + name: sis-build-${{ inputs.cell-id }} + path: build + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_unit_tests.sh -M --unit-only + + test-component: + name: Component tests (${{ inputs.cell-id }}) + needs: build + runs-on: ${{ inputs.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: mingw-w64-x86_64-toolchain + + - name: Download build tree + uses: actions/download-artifact@v4 + with: + name: sis-build-${{ inputs.cell-id }} + path: build + + - name: Run component tests + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_unit_tests.sh -M --component-only + + test-scratch: + name: Scratch tests (${{ inputs.cell-id }}) + needs: build + continue-on-error: true + runs-on: ${{ inputs.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: mingw-w64-x86_64-toolchain + + - name: Download build tree + uses: actions/download-artifact@v4 + with: + name: sis-build-${{ inputs.cell-id }} + path: build + + - name: Run scratch tests + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_scratch_tests.sh -M diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6bcfc80 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,269 @@ +name: CI + +on: + push: + branches: + - master + - dev + - boilerplate + - rc1 + - rc2 + - rc3 + - rc4 + - rc5 + - update + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + BUILD_TYPE: Release + +jobs: + cell: + name: CI (${{ matrix.id }}) + strategy: + fail-fast: false + matrix: + include: + - id: linux-clang + os: ubuntu-latest + c_compiler: clang + cpp_compiler: clang++ + - id: linux-gcc + os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + - id: macos-clang + os: macos-latest + c_compiler: clang + cpp_compiler: clang++ + - id: macos-gcc + os: macos-latest + c_compiler: gcc + cpp_compiler: g++ + - id: windows-cl + os: windows-latest + c_compiler: cl + cpp_compiler: cl + - id: windows-mingw + os: windows-latest + c_compiler: mingw + cpp_compiler: g++ + uses: ./.github/workflows/ci-cell.yml + with: + cell-id: ${{ matrix.id }} + os: ${{ matrix.os }} + c-compiler: ${{ matrix.c_compiler }} + cpp-compiler: ${{ matrix.cpp_compiler }} + build-type: Release + secrets: inherit + + install-smoke: + name: Install smoke (${{ matrix.os }}, ${{ matrix.c_compiler }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + - os: ubuntu-latest + c_compiler: clang + cpp_compiler: clang++ + - os: macos-latest + c_compiler: clang + cpp_compiler: clang++ + - os: windows-latest + c_compiler: cl + cpp_compiler: cl + - os: windows-latest + c_compiler: mingw + cpp_compiler: g++ + + steps: + - uses: actions/checkout@v4 + + - name: Install Clang (Ubuntu) + if: runner.os == 'Linux' && matrix.c_compiler == 'clang' + run: sudo apt-get update && sudo apt-get install -y clang + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && matrix.c_compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: >- + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-cmake + mingw-w64-x86_64-make + + - name: Configure + shell: bash + run: | + set -euo pipefail + if [ "${{ matrix.c_compiler }}" = "cl" ]; then + cmake -B build -S . \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake -B build -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DCMAKE_C_COMPILER=gcc \ + -DCMAKE_CXX_COMPILER=g++ \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + else + cmake -B build -S . \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + fi + + - name: Build + shell: bash + run: | + set -euo pipefail + if [ "${{ matrix.c_compiler }}" = "cl" ]; then + cmake --build build --config "${{ env.BUILD_TYPE }}" --parallel + elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake --build build --parallel 2 + else + cmake --build build --parallel + fi + + - name: Install + shell: bash + run: | + set -euo pipefail + PREFIX="${RUNNER_TEMP}/install-prefix" + echo "INSTALL_PREFIX=$PREFIX" >> "$GITHUB_ENV" + if [ "${{ matrix.c_compiler }}" = "cl" ]; then + cmake --install build --config "${{ env.BUILD_TYPE }}" --prefix "$PREFIX" + else + cmake --install build --prefix "$PREFIX" + fi + + - name: Verify install tree + shell: bash + run: | + set -euo pipefail + test -f "${INSTALL_PREFIX}/include/cstring/cstring.h" + test -f "${INSTALL_PREFIX}/lib/cmake/cstring/cstring-config.cmake" + + - name: Configure and run install smoke consumer + shell: bash + run: | + set -euo pipefail + CONSUMER="${RUNNER_TEMP}/consumer" + mkdir -p "$CONSUMER" + cat > "$CONSUMER/CMakeLists.txt" <<'EOF' + cmake_minimum_required(VERSION 3.13) + project(cstring_install_smoke C) + find_package(cstring REQUIRED) + add_executable(consumer consumer.c) + target_link_libraries(consumer PRIVATE cstring::core) + EOF + cat > "$CONSUMER/consumer.c" <<'EOF' + #include + int main(void) { return 0; } + EOF + if [ "${{ matrix.c_compiler }}" = "cl" ]; then + cmake -S "$CONSUMER" -B consumer-build \ + -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX};${{ env.SIS_DEPS }}" + cmake --build consumer-build --config "${{ env.BUILD_TYPE }}" --parallel + consumer-build/${{ env.BUILD_TYPE }}/consumer.exe + elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + cmake -S "$CONSUMER" -B consumer-build -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" + cmake --build consumer-build --parallel 2 + consumer-build/consumer.exe + else + cmake -S "$CONSUMER" -B consumer-build \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ + -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" + cmake --build consumer-build --parallel + consumer-build/consumer + fi + + no-cpp: + name: Build with --no-cpp + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies (STLSoft + shwild + xTests) + shell: bash + run: | + set -euo pipefail + + DEPS="${RUNNER_TEMP}/sis-deps" + STLSRC="${RUNNER_TEMP}/stlsoft-src" + STLBUILD="${RUNNER_TEMP}/stlsoft-build" + SHWSRC="${RUNNER_TEMP}/shwild-src" + SHWBUILD="${RUNNER_TEMP}/shwild-build" + XTSRC="${RUNNER_TEMP}/xtests-src" + XTBUILD="${RUNNER_TEMP}/xtests-build" + + mkdir -p "$DEPS" + + git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" + cmake -S "$STLSRC" -B "$STLBUILD" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$STLBUILD" --parallel + cmake --install "$STLBUILD" + + git clone --depth 1 https://github.com/synesissoftware/shwild "$SHWSRC" + cmake -S "$SHWSRC" -B "$SHWBUILD" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$SHWBUILD" --parallel + cmake --install "$SHWBUILD" + + git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" + cmake -S "$XTSRC" -B "$XTBUILD" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF + cmake --build "$XTBUILD" --parallel + cmake --install "$XTBUILD" + + echo "SIS_DEPS=$DEPS" >> "$GITHUB_ENV" + + - name: Configure and build via prepare_cmake.sh --no-cpp + shell: bash + run: | + set -euo pipefail + # Prefer CMAKE_PREFIX_PATH (find_package) over prepare_cmake -s / + # -DSTLSOFT: xTests::core links STLSoft::STLSoft, which only exists + # when the STLSoft CMake package is imported. + export CMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" + ./prepare_cmake.sh --no-cpp -m + + - name: Run unit tests + shell: bash + run: | + set -euo pipefail + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/_build" ./run_all_unit_tests.sh -M --unit-only diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml deleted file mode 100644 index e8fd300..0000000 --- a/.github/workflows/cmake-multi-platform.yml +++ /dev/null @@ -1,168 +0,0 @@ -# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. -# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml -name: CMake on multiple platforms - -on: - push: - branches: - - master - - dev - - boileplate - - rc1 - - rc2 - - rc3 - - rc4 - - rc5 - pull_request: - -jobs: - build: - runs-on: ${{ matrix.os }} - - strategy: - # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. - fail-fast: false - - # Set up a matrix to run the following 3 configurations: - # 1. - # 2. - # 3. - # - # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list. - matrix: - os: - - macos-latest - - ubuntu-latest - - windows-latest - build_type: [Release] - c_compiler: - - cl - - clang - - gcc - include: - - os: macos-latest - c_compiler: clang - cpp_compiler: clang++ - - os: macos-latest - c_compiler: gcc - cpp_compiler: g++ - - os: ubuntu-latest - c_compiler: clang - cpp_compiler: clang++ - - os: ubuntu-latest - c_compiler: gcc - cpp_compiler: g++ - - os: windows-latest - c_compiler: cl - cpp_compiler: cl - exclude: - - os: macos-latest - c_compiler: cl - - os: ubuntu-latest - c_compiler: cl - - os: windows-latest - c_compiler: clang - - os: windows-latest - c_compiler: gcc - - steps: - - uses: actions/checkout@v4 - - - name: Set reusable strings - # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. - id: strings - shell: bash - run: | - echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: > - cmake - -B ${{ steps.strings.outputs.build-output-dir }} - -DBUILD_EXAMPLES:BOOL=FALSE - -DBUILD_TESTING:BOOL=FALSE - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} - -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} - -S ${{ github.workspace }} - - - name: Build - # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} - - - name: Test - working-directory: ${{ steps.strings.outputs.build-output-dir }} - # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest --build-config ${{ matrix.build_type }} - - no-cpp: - name: Build with --no-cpp - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Install dependencies (STLSoft + shwild + xTests) - shell: bash - run: | - set -euo pipefail - - DEPS="${RUNNER_TEMP}/sis-deps" - STLSRC="${RUNNER_TEMP}/stlsoft-src" - STLBUILD="${RUNNER_TEMP}/stlsoft-build" - SHWSRC="${RUNNER_TEMP}/shwild-src" - SHWBUILD="${RUNNER_TEMP}/shwild-build" - XTSRC="${RUNNER_TEMP}/xtests-src" - XTBUILD="${RUNNER_TEMP}/xtests-build" - - mkdir -p "$DEPS" - - git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" - cmake -S "$STLSRC" -B "$STLBUILD" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --parallel - cmake --install "$STLBUILD" - - git clone --depth 1 https://github.com/synesissoftware/shwild "$SHWSRC" - cmake -S "$SHWSRC" -B "$SHWBUILD" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$SHWBUILD" --parallel - cmake --install "$SHWBUILD" - - git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" - cmake -S "$XTSRC" -B "$XTBUILD" \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$XTBUILD" --parallel - cmake --install "$XTBUILD" - - echo "SIS_DEPS=$DEPS" >> "$GITHUB_ENV" - - - name: Configure and build via prepare_cmake.sh --no-cpp - shell: bash - run: | - set -euo pipefail - # Prefer CMAKE_PREFIX_PATH (find_package) over prepare_cmake -s / - # -DSTLSOFT: xTests::core links STLSoft::STLSoft, which only exists - # when the STLSoft CMake package is imported. - export CMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" - ./prepare_cmake.sh --no-cpp -m - - - name: Run unit tests - shell: bash - run: | - set -euo pipefail - SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/_build" ./run_all_unit_tests.sh -M --unit-only diff --git a/CHANGES.md b/CHANGES.md index 6b675d3..ffa429c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,9 @@ ## 4.0.13 - 2nd August 2026 +* Modular GitHub Actions CI (**ci.yml** + **ci-cell.yml**), with install-smoke and MinGW cells; +* Retained `--no-cpp` CI job; retired **cmake-multi-platform.yml**; +* README CI badge now targets **ci.yml**; * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/README.md b/README.md index c1a73fe..e7efef8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![GitHub release](https://img.shields.io/github/v/release/synesissoftware/cstring.svg)](https://github.com/synesissoftware/cstring/releases/latest) [![Last Commit](https://img.shields.io/github/last-commit/synesissoftware/cstring)](https://github.com/synesissoftware/cstring/commits/master) -[![CMake on multiple platforms](https://github.com/synesissoftware/cstring/actions/workflows/cmake-multi-platform.yml/badge.svg)](https://github.com/synesissoftware/cstring/actions/workflows/cmake-multi-platform.yml) +[![CMake on multiple platforms](https://github.com/synesissoftware/cstring/actions/workflows/ci.yml/badge.svg)](https://github.com/synesissoftware/cstring/actions/workflows/ci.yml) From 69286cb6d06d67e87f6a05bad17f03dc9e70930d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:58:27 +1000 Subject: [PATCH 13/35] fix: replaced leftover `cstring_error()` calls with `cstring_getStatusCodeString()` in **test.unit.cstring.1** and **test.unit.cstring.2** --- CHANGES.md | 1 + test/unit/test.unit.cstring.1/entry.cpp | 34 ++++++++++++------------- test/unit/test.unit.cstring.2/entry.c | 2 +- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ffa429c..4408485 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ * Modular GitHub Actions CI (**ci.yml** + **ci-cell.yml**), with install-smoke and MinGW cells; * Retained `--no-cpp` CI job; retired **cmake-multi-platform.yml**; * README CI badge now targets **ci.yml**; +* Replaced leftover `cstring_error()` calls with `cstring_getStatusCodeString()` in **test.unit.cstring.1** and **test.unit.cstring.2**; * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/test/unit/test.unit.cstring.1/entry.cpp b/test/unit/test.unit.cstring.1/entry.cpp index 0f09234..424cc3a 100644 --- a/test/unit/test.unit.cstring.1/entry.cpp +++ b/test/unit/test.unit.cstring.1/entry.cpp @@ -216,7 +216,7 @@ static void test_1_2() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not set capacity", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not set capacity", cstring_getStatusCodeString(rc)); } else { @@ -242,7 +242,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_getStatusCodeString(rc)); } else { @@ -267,7 +267,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_getStatusCodeString(rc)); } else { @@ -292,7 +292,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create", cstring_getStatusCodeString(rc)); } else { @@ -317,7 +317,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create", cstring_getStatusCodeString(rc)); } else { @@ -342,7 +342,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_getStatusCodeString(rc)); } else { @@ -367,7 +367,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_getStatusCodeString(rc)); } else { @@ -392,7 +392,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_getStatusCodeString(rc)); } else { @@ -423,7 +423,7 @@ static void test_1_3() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_getStatusCodeString(rc)); } else { @@ -460,7 +460,7 @@ static void test_1_4() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_getStatusCodeString(rc)); } else { @@ -490,7 +490,7 @@ static void test_1_4() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign", cstring_getStatusCodeString(rc)); } else { @@ -519,7 +519,7 @@ static void test_1_4() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create", cstring_getStatusCodeString(rc)); } else { @@ -550,7 +550,7 @@ static void test_1_5() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign (with length)", cstring_getStatusCodeString(rc)); } else { @@ -580,7 +580,7 @@ static void test_1_5() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not assign (with length)", cstring_getStatusCodeString(rc)); } else { @@ -609,7 +609,7 @@ static void test_1_5() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create (with length)", cstring_getStatusCodeString(rc)); } else { @@ -641,7 +641,7 @@ static void test_1_6() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not append", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not append", cstring_getStatusCodeString(rc)); } else { @@ -670,7 +670,7 @@ static void test_1_6() if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not append (with length)", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not append (with length)", cstring_getStatusCodeString(rc)); } else { diff --git a/test/unit/test.unit.cstring.2/entry.c b/test/unit/test.unit.cstring.2/entry.c index 4e83762..8672f00 100644 --- a/test/unit/test.unit.cstring.2/entry.c +++ b/test/unit/test.unit.cstring.2/entry.c @@ -311,7 +311,7 @@ static void test_replaceLen(void) if (CSTRING_RC_SUCCESS != rc) { - XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create string", cstring_error(rc)); + XTESTS_TEST_FAIL_WITH_QUALIFIER("could not create string", cstring_getStatusCodeString(rc)); } else { From ff99f55b46cb9fee88f3e42f69af7defe041cfaa Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 12:59:20 +1000 Subject: [PATCH 14/35] fix --- .../test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt b/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt index 01d3475..69051a0 100644 --- a/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt +++ b/test/unit/test.unit.cstring.cstring_getStatusCodeString/CMakeLists.txt @@ -1 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) define_automated_test_program(test_unit_cstring_cstring_getStatusCodeString entry.c) From cdb73797cecdf5d2a1045f456fd9296140de3b09 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 13:02:39 +1000 Subject: [PATCH 15/35] fix: suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c** --- CHANGES.md | 1 + src/cstring.core.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 4408485..2118de4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ * Retained `--no-cpp` CI job; retired **cmake-multi-platform.yml**; * README CI badge now targets **ci.yml**; * Replaced leftover `cstring_error()` calls with `cstring_getStatusCodeString()` in **test.unit.cstring.1** and **test.unit.cstring.2**; +* Suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c**; * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/src/cstring.core.c b/src/cstring.core.c index b6e1628..9d661a2 100644 --- a/src/cstring.core.c +++ b/src/cstring.core.c @@ -1833,9 +1833,18 @@ win32_comtask_realloc( if (1 == ++s_cstring_PfnCoTaskMemRealloc_init) { +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" +#endif /* __GNUC__ */ + s_cstring_ole32_HINSTANCE = LoadLibraryA("OLE32"); s_cstring_pfnCoTaskMemRealloc = (PfnCoTaskMemRealloc)GetProcAddress(s_cstring_ole32_HINSTANCE, "CoTaskMemRealloc"); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif /* __GNUC__ */ + if (NULL == s_cstring_ole32_HINSTANCE || NULL == s_cstring_pfnCoTaskMemRealloc) { From dde920f57433353868a55896185ff45f51accc3f Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 13:09:32 +1000 Subject: [PATCH 16/35] fix: MinGW `size_t` printf format in **test.scratch.cstring_create** --- CHANGES.md | 1 + test/scratch/test.scratch.cstring_create/entry.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2118de4..4c814c8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ * README CI badge now targets **ci.yml**; * Replaced leftover `cstring_error()` calls with `cstring_getStatusCodeString()` in **test.unit.cstring.1** and **test.unit.cstring.2**; * Suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c**; +* Fixed MinGW `size_t` printf format in **test.scratch.cstring_create**; * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/test/scratch/test.scratch.cstring_create/entry.c b/test/scratch/test.scratch.cstring_create/entry.c index dd0c680..7ab48ca 100644 --- a/test/scratch/test.scratch.cstring_create/entry.c +++ b/test/scratch/test.scratch.cstring_create/entry.c @@ -33,8 +33,8 @@ int main(int argc, char* argv[]) { printf( "successfully created string with length %lu capacity %lu and contents '%.*s'\n" - , cs.len - , cs.capacity + , (unsigned long)cs.len + , (unsigned long)cs.capacity , (int)cs.len, cs.ptr ); From 00fe77d47e045bfaca83ab0782486c225daeda16 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 13:37:54 +1000 Subject: [PATCH 17/35] feature: moved scratch programs (except **libver**) into **examples/** as `example.c.*` / `example.cpp.*` with `main.c` / `main.cpp` and per-example **README.md** --- CHANGES.md | 3 +- README.md | 11 ++- examples/CMakeLists.txt | 20 +---- examples/c/CMakeLists.txt | 7 ++ .../c/example.c.auto_buffer/CMakeLists.txt | 1 + examples/c/example.c.auto_buffer/README.md | 31 +++++++ .../c/example.c.auto_buffer/main.c | 19 ++++- examples/c/example.c.cstring/CMakeLists.txt | 1 + examples/c/example.c.cstring/README.md | 80 +++++++++++++++++++ .../c/example.c.cstring/main.c | 8 +- .../c/example.c.cstring_create/CMakeLists.txt | 1 + examples/c/example.c.cstring_create/README.md | 30 +++++++ .../c/example.c.cstring_create/main.c | 18 +++-- .../example.c.cstring_vector}/CMakeLists.txt | 2 +- examples/c/example.c.cstring_vector/README.md | 47 +++++++++++ .../c/example.c.cstring_vector/main.c | 16 +++- examples/cpp/CMakeLists.txt | 8 ++ .../example.cpp.HGLOBAL_on_x64/CMakeLists.txt | 1 + .../cpp/example.cpp.HGLOBAL_on_x64/README.md | 26 ++++++ .../cpp/example.cpp.HGLOBAL_on_x64/main.cpp | 0 .../CMakeLists.txt | 1 + .../cpp/example.cpp.cstring.dynload/README.md | 35 ++++++++ .../cpp/example.cpp.cstring.dynload/main.cpp | 9 ++- include/cstring/internal/safestr.h | 39 ++++----- run_all_examples.sh | 2 +- src/cstring.core.c | 4 +- src/dllmain.c | 39 ++++----- test/scratch/CMakeLists.txt | 9 --- .../CMakeLists.txt | 4 - .../test.scratch.auto_buffer/CMakeLists.txt | 1 - .../CMakeLists.txt | 4 - .../test.scratch.cstring/CMakeLists.txt | 1 - .../CMakeLists.txt | 2 - .../test.unit.cstring.auto_buffer/entry.c | 3 +- 34 files changed, 379 insertions(+), 104 deletions(-) create mode 100644 examples/c/example.c.auto_buffer/CMakeLists.txt create mode 100644 examples/c/example.c.auto_buffer/README.md rename test/scratch/test.scratch.auto_buffer/entry.c => examples/c/example.c.auto_buffer/main.c (74%) create mode 100644 examples/c/example.c.cstring/CMakeLists.txt create mode 100644 examples/c/example.c.cstring/README.md rename test/scratch/test.scratch.cstring/entry.c => examples/c/example.c.cstring/main.c (97%) create mode 100644 examples/c/example.c.cstring_create/CMakeLists.txt create mode 100644 examples/c/example.c.cstring_create/README.md rename test/scratch/test.scratch.cstring_create/entry.c => examples/c/example.c.cstring_create/main.c (78%) rename {test/scratch/test.scratch.cstring_vector => examples/c/example.c.cstring_vector}/CMakeLists.txt (70%) create mode 100644 examples/c/example.c.cstring_vector/README.md rename test/scratch/test.scratch.cstring_vector/entry.c => examples/c/example.c.cstring_vector/main.c (91%) create mode 100644 examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt create mode 100644 examples/cpp/example.cpp.HGLOBAL_on_x64/README.md rename test/scratch/test.scratch.HGLOBAL_on_x64/entry.cpp => examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp (100%) create mode 100644 examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt create mode 100644 examples/cpp/example.cpp.cstring.dynload/README.md rename test/scratch/test.scratch.cstring.dynload/entry.cpp => examples/cpp/example.cpp.cstring.dynload/main.cpp (92%) delete mode 100644 test/scratch/test.scratch.HGLOBAL_on_x64/CMakeLists.txt delete mode 100644 test/scratch/test.scratch.auto_buffer/CMakeLists.txt delete mode 100644 test/scratch/test.scratch.cstring.dynload/CMakeLists.txt delete mode 100644 test/scratch/test.scratch.cstring/CMakeLists.txt delete mode 100644 test/scratch/test.scratch.cstring_create/CMakeLists.txt diff --git a/CHANGES.md b/CHANGES.md index 4c814c8..a75b049 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,8 @@ * README CI badge now targets **ci.yml**; * Replaced leftover `cstring_error()` calls with `cstring_getStatusCodeString()` in **test.unit.cstring.1** and **test.unit.cstring.2**; * Suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c**; -* Fixed MinGW `size_t` printf format in **test.scratch.cstring_create**; +* Fixed MinGW `size_t` printf format in **example.c.cstring_create** (formerly **test.scratch.cstring_create**); +* Moved scratch programs (except **libver**) into **examples/** as `example.c.*` / `example.cpp.*` with `main.c` / `main.cpp` and per-example **README.md**; * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/README.md b/README.md index e7efef8..13bb0da 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,16 @@ The C API is based around two structures: ## Examples -Examples are provided in the ```examples``` directory, along with a markdown description for each. +Examples live under **examples/** (`c/` and `cpp/`), each with a short **README.md**. Build them with `BUILD_EXAMPLES` (on by default); run via **run_all_examples.sh**. + +| Example | Language | Notes | +| ------- | -------- | ----- | +| [**example.c.auto_buffer**](./examples/c/example.c.auto_buffer/) | C | Borrowed buffer that may grow to the heap | +| [**example.c.cstring**](./examples/c/example.c.cstring/) | C | Core `cstring_t` create / assign / append / truncate / copy / swap | +| [**example.c.cstring_create**](./examples/c/example.c.cstring_create/) | C | Minimal `cstring_create()` | +| [**example.c.cstring_vector**](./examples/c/example.c.cstring_vector/) | C | Read lines into `cstring_vector_t` and sort (requires input path or `--`) | +| [**example.cpp.cstring.dynload**](./examples/cpp/example.cpp.cstring.dynload/) | C++ | Windows-only dynamic load of the cstring DLL | +| [**example.cpp.HGLOBAL_on_x64**](./examples/cpp/example.cpp.HGLOBAL_on_x64/) | C++ | Windows-only `CSTRING_F_USE_WIN32_GLOBAL_MEMORY` | ## Project Information diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 64b0b20..6de1334 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,23 +32,11 @@ if((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914)) add_definitions(-D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) endif() +add_subdirectory(c) +if(NOT NO_CSTRING_CPP_API) -foreach(d c cpp) - - if(NO_CSTRING_CPP_API) - - if ("${d}" EQUAL "cpp") - - continue() - endif() - endif() - - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${d}") - - add_subdirectory(${d}) - endif() -endforeach() + add_subdirectory(cpp) +endif() # ############################## end of file ############################# # - diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index e69de29..7a7aa81 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(example.c.auto_buffer) +add_subdirectory(example.c.cstring) +add_subdirectory(example.c.cstring_create) +add_subdirectory(example.c.cstring_vector) + + +# ############################## end of file ############################# # diff --git a/examples/c/example.c.auto_buffer/CMakeLists.txt b/examples/c/example.c.auto_buffer/CMakeLists.txt new file mode 100644 index 0000000..b41d275 --- /dev/null +++ b/examples/c/example.c.auto_buffer/CMakeLists.txt @@ -0,0 +1 @@ +define_example_program(example.c.auto_buffer main.c) diff --git a/examples/c/example.c.auto_buffer/README.md b/examples/c/example.c.auto_buffer/README.md new file mode 100644 index 0000000..265181a --- /dev/null +++ b/examples/c/example.c.auto_buffer/README.md @@ -0,0 +1,31 @@ +# example.c.auto_buffer + + +## Purpose + +Demonstrates creating a `cstring_t` on a fixed borrowed buffer, then appending past that capacity so the string grows onto the heap (`CSTRING_F_MEMORY_IS_BORROWED` | `CSTRING_F_MEMORY_CAN_GROW_TO_HEAP`). + + +## Build + +Built when `BUILD_EXAMPLES` is enabled (the default). + + +## Run + +```sh +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/c/example.c.auto_buffer/example.c.auto_buffer +``` + + +## Expected output + +``` +cs=: 'String-#1' +cs=: 'String-#1 : something very long' +``` + +The first line is the string still in the borrowed 10-byte buffer; the second is after `cstring_append()` forces a heap reallocation (capacity grows beyond the original buffer). + + + diff --git a/test/scratch/test.scratch.auto_buffer/entry.c b/examples/c/example.c.auto_buffer/main.c similarity index 74% rename from test/scratch/test.scratch.auto_buffer/entry.c rename to examples/c/example.c.auto_buffer/main.c index e0208ad..75bfe32 100644 --- a/test/scratch/test.scratch.auto_buffer/entry.c +++ b/examples/c/example.c.auto_buffer/main.c @@ -1,10 +1,12 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.auto_buffer/entry.c + * File: examples/c/example.c.auto_buffer/main.c * - * Purpose: Implementation file for the test.scratch.auto_buffer project. + * Purpose: Example illustrating borrowed buffer growth to the heap + * (`CSTRING_F_MEMORY_IS_BORROWED` + + * `CSTRING_F_MEMORY_CAN_GROW_TO_HEAP`). * * Created: 28th July 2011 - * Updated: 23rd February 2025 + * Updated: 2nd August 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -52,6 +54,12 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } + printf("cs=: '%.*s'\n" + , (unsigned long)cs.len + , (unsigned long)cs.capacity + , (int)cs.len, cs.ptr + ); + /* add some more to exceed capacity */ rc = cstring_append(&cs, " : something very long"); @@ -62,6 +70,11 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } + printf("cs=: '%.*s'\n" + , (unsigned long)cs.len + , (unsigned long)cs.capacity + , (int)cs.len, cs.ptr + ); cstring_destroy(&cs); diff --git a/examples/c/example.c.cstring/CMakeLists.txt b/examples/c/example.c.cstring/CMakeLists.txt new file mode 100644 index 0000000..c5cde46 --- /dev/null +++ b/examples/c/example.c.cstring/CMakeLists.txt @@ -0,0 +1 @@ +define_example_program(example.c.cstring main.c) diff --git a/examples/c/example.c.cstring/README.md b/examples/c/example.c.cstring/README.md new file mode 100644 index 0000000..8d1810f --- /dev/null +++ b/examples/c/example.c.cstring/README.md @@ -0,0 +1,80 @@ +# example.c.cstring + + +## Purpose + +Exercises common `cstring_t` operations: create (including length-bounded and Windows allocator flags where available), assign, append, truncate, copy, and swap. + + +## Build + +Built when `BUILD_EXAMPLES` is enabled (the default). + + +## Run + +```sh +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/c/example.c.cstring/example.c.cstring +``` + + +## Expected output + +On non-Windows hosts, two scenarios are printed (default heap, then fixed/borrowed). Pointer values in copy/swap lines vary per run. Illustrative sample: + +``` +======================================== +cstring_createLen(): + Initial contents: string-#1 + + Assigning another C-style string to the instance: + Contents: another string + + Assigning part of another C-style string to the instance: + Contents: some more content + + Appending another C-style string to the instance: + Contents: some more content - + + Appending part of another C-style string to the instance: + Contents: some more content - and another + + Appending part of another C-style string to the instance: + Contents: some more content - and another; and a whole lot more stringy stuff to try and precipitate a reallocation, in order to check that the 3.3 change will be tested + + Appending part of another C-style string to the instance: + Contents: some more content - and another; and a whole lot more stringy stuff to try and precipitate a reallocation, in order to check that the 3.3 change will be tested; and a last bit to try and get the remaining reallocation + + Truncating the instance to 10 characters: + Contents: some more + + Copying the instance: + Contents: 0x… some more + Contents of copy: 0x… some more + + Copying the instance (by C-style string): + Contents: 0x… some more + Contents of copy: 0x… some more + + Swapping with the copy: + Contents: 0x… some more + Contents of copy: 0x… some more + + Destroying the copy: + +======================================== +cstring_createLenEx(CSTRING_F_MEMORY_IS_FIXED | CSTRING_F_MEMORY_IS_BORROWED): + Initial contents: string-#4 + … + error: operation cannot procede because the current capacity would be exceeded and the cstring has fixed capacity + … + error: operation cannot procede because the current capacity would be exceeded and the cstring is borrowed + … + error: operation cannot procede because the cstring is borrowed + … +``` + +On Windows, additional scenarios for process-heap and COM-task allocators are also printed. + + + diff --git a/test/scratch/test.scratch.cstring/entry.c b/examples/c/example.c.cstring/main.c similarity index 97% rename from test/scratch/test.scratch.cstring/entry.c rename to examples/c/example.c.cstring/main.c index ab4133c..0539361 100644 --- a/test/scratch/test.scratch.cstring/entry.c +++ b/examples/c/example.c.cstring/main.c @@ -1,10 +1,12 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.cstring/entry.c + * File: examples/c/example.c.cstring/main.c * - * Purpose: Implementation file for the test.scratch.cstring project. + * Purpose: Example exercising core `cstring_t` create/assign/append/ + * truncate/copy/swap paths (including Windows allocator flags + * where available). * * Created: 7th July 2005 - * Updated: 23rd March 2025 + * Updated: 2nd August 2026 * * ////////////////////////////////////////////////////////////////////// */ diff --git a/examples/c/example.c.cstring_create/CMakeLists.txt b/examples/c/example.c.cstring_create/CMakeLists.txt new file mode 100644 index 0000000..5300bb0 --- /dev/null +++ b/examples/c/example.c.cstring_create/CMakeLists.txt @@ -0,0 +1 @@ +define_example_program(example.c.cstring_create main.c) diff --git a/examples/c/example.c.cstring_create/README.md b/examples/c/example.c.cstring_create/README.md new file mode 100644 index 0000000..117f0c9 --- /dev/null +++ b/examples/c/example.c.cstring_create/README.md @@ -0,0 +1,30 @@ +# example.c.cstring_create + + +## Purpose + +Minimal illustration of `cstring_create()` and `cstring_destroy()`, printing the resulting length, capacity, and contents. + + +## Build + +Built when `BUILD_EXAMPLES` is enabled (the default). + + +## Run + +```sh +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/c/example.c.cstring_create/example.c.cstring_create +``` + + +## Expected output + +``` +successfully created string with length 9 capacity 16 and contents 'String-#1' +``` + +Capacity may vary by allocator / growth policy; length and contents should match. + + + diff --git a/test/scratch/test.scratch.cstring_create/entry.c b/examples/c/example.c.cstring_create/main.c similarity index 78% rename from test/scratch/test.scratch.cstring_create/entry.c rename to examples/c/example.c.cstring_create/main.c index 7ab48ca..fcca051 100644 --- a/test/scratch/test.scratch.cstring_create/entry.c +++ b/examples/c/example.c.cstring_create/main.c @@ -1,6 +1,13 @@ -/* - * TODO: move to examples - */ +/* ///////////////////////////////////////////////////////////////////////// + * File: examples/c/example.c.cstring_create/main.c + * + * Purpose: Minimal example of `cstring_create()` / `cstring_destroy()`. + * + * Created: ... + * Updated: 2nd August 2026 + * + * ////////////////////////////////////////////////////////////////////// */ + /* cstring header files */ #include @@ -8,11 +15,6 @@ /* Standard C header files */ #include -/* ///////////////////////////////////////////////////////////////////////// - * forward declarations - */ - - /* ///////////////////////////////////////////////////////////////////////// * main() */ diff --git a/test/scratch/test.scratch.cstring_vector/CMakeLists.txt b/examples/c/example.c.cstring_vector/CMakeLists.txt similarity index 70% rename from test/scratch/test.scratch.cstring_vector/CMakeLists.txt rename to examples/c/example.c.cstring_vector/CMakeLists.txt index 7088862..02ad8ad 100644 --- a/test/scratch/test.scratch.cstring_vector/CMakeLists.txt +++ b/examples/c/example.c.cstring_vector/CMakeLists.txt @@ -1,3 +1,3 @@ list(APPEND X_GCC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED format format-extra-args) list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4127 4473 4996) -define_example_program(test_scratch_cstring_vector entry.c) +define_example_program(example.c.cstring_vector main.c) diff --git a/examples/c/example.c.cstring_vector/README.md b/examples/c/example.c.cstring_vector/README.md new file mode 100644 index 0000000..2e5f4bb --- /dev/null +++ b/examples/c/example.c.cstring_vector/README.md @@ -0,0 +1,47 @@ +# example.c.cstring_vector + + +## Purpose + +Reads lines from a text stream into a `cstring_vector_t`, prints them, then sorts forward and reverse. + + +## Build + +Built when `BUILD_EXAMPLES` is enabled (the default). + + +## Run + +Requires an input source: + +```sh +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/c/example.c.cstring_vector/example.c.cstring_vector path/to/file.txt +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/c/example.c.cstring_vector/example.c.cstring_vector -- # stdin +printf 'beta\nalpha\ngamma\n' | ${SIS_CMAKE_BUILD_DIR:-./_build}/examples/c/example.c.cstring_vector/example.c.cstring_vector -- +``` + + +## Expected output + +For the `printf 'beta\nalpha\ngamma\n' | … --` invocation above: + +``` +#lines: 3 +line-0: beta +line-1: alpha +line-2: gamma + +#sorted-lines (forward): 3 +line-0: alpha +line-1: beta +line-2: gamma + +#sorted-lines (reverse): 3 +line-0: gamma +line-1: beta +line-2: alpha +``` + + + diff --git a/test/scratch/test.scratch.cstring_vector/entry.c b/examples/c/example.c.cstring_vector/main.c similarity index 91% rename from test/scratch/test.scratch.cstring_vector/entry.c rename to examples/c/example.c.cstring_vector/main.c index a2deb2c..d8314d0 100644 --- a/test/scratch/test.scratch.cstring_vector/entry.c +++ b/examples/c/example.c.cstring_vector/main.c @@ -1,6 +1,14 @@ -/* - * TODO: move to examples - */ +/* ///////////////////////////////////////////////////////////////////////// + * File: examples/c/example.c.cstring_vector/main.c + * + * Purpose: Example reading lines into a `cstring_vector_t` and sorting + * them. + * + * Created: ... + * Updated: 2nd August 2026 + * + * ////////////////////////////////////////////////////////////////////// */ + /* cstring header files */ #include @@ -11,7 +19,7 @@ #include #include -/* ************************************************************************* +/* ///////////////////////////////////////////////////////////////////////// * main() */ diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index e69de29..7028c62 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -0,0 +1,8 @@ +if(WIN32) + + add_subdirectory(example.cpp.cstring.dynload) + add_subdirectory(example.cpp.HGLOBAL_on_x64) +endif(WIN32) + + +# ############################## end of file ############################# # diff --git a/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt b/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt new file mode 100644 index 0000000..91420d2 --- /dev/null +++ b/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt @@ -0,0 +1 @@ +define_example_program(example.cpp.HGLOBAL_on_x64 main.cpp) diff --git a/examples/cpp/example.cpp.HGLOBAL_on_x64/README.md b/examples/cpp/example.cpp.HGLOBAL_on_x64/README.md new file mode 100644 index 0000000..ab71c09 --- /dev/null +++ b/examples/cpp/example.cpp.HGLOBAL_on_x64/README.md @@ -0,0 +1,26 @@ +# example.cpp.HGLOBAL_on_x64 + + +## Purpose + +Windows-only C++ example that allocates a `cstring_t` with `CSTRING_F_USE_WIN32_GLOBAL_MEMORY` (process `HGLOBAL` heap) and appends several fragments. + + +## Build + +Built when `BUILD_EXAMPLES` is enabled, `NO_CSTRING_CPP_API` is off, and the target is Windows. + + +## Run + +```sh +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/cpp/example.cpp.HGLOBAL_on_x64/example.cpp.HGLOBAL_on_x64 +``` + + +## Expected output + +None (exit status 0 on success). The example exercises allocation/append/destroy without printing. + + + diff --git a/test/scratch/test.scratch.HGLOBAL_on_x64/entry.cpp b/examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp similarity index 100% rename from test/scratch/test.scratch.HGLOBAL_on_x64/entry.cpp rename to examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp diff --git a/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt b/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt new file mode 100644 index 0000000..834cf31 --- /dev/null +++ b/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt @@ -0,0 +1 @@ +define_example_program(example.cpp.cstring.dynload main.cpp) diff --git a/examples/cpp/example.cpp.cstring.dynload/README.md b/examples/cpp/example.cpp.cstring.dynload/README.md new file mode 100644 index 0000000..e33bffc --- /dev/null +++ b/examples/cpp/example.cpp.cstring.dynload/README.md @@ -0,0 +1,35 @@ +# example.cpp.cstring.dynload + + +## Purpose + +Windows-only C++ example that loads the **cstring** shared library at runtime (`LoadLibrary` / `GetProcAddress`) and calls selected API entry points. + + +## Build + +Built when `BUILD_EXAMPLES` is enabled, `NO_CSTRING_CPP_API` is off, and the target is Windows. + + +## Run + +```sh +${SIS_CMAKE_BUILD_DIR:-./_build}/examples/cpp/example.cpp.cstring.dynload/example.cpp.cstring.dynload +``` + +Expects a suitable **cstring** DLL (for example `cstring.3.debug.dll`) to be loadable on the process search path. + + +## Expected output + +Depends on whether the DLL loads and which entry points resolve. On a successful path you may see lines such as: + +``` +caught expected exception: … +string=Hello +``` + +If the DLL is missing, the program typically exits quietly with status 0 after a failed `LoadLibrary` / null proc check. Treat this example as a Windows integration sketch rather than a fixed golden-output demo. + + + diff --git a/test/scratch/test.scratch.cstring.dynload/entry.cpp b/examples/cpp/example.cpp.cstring.dynload/main.cpp similarity index 92% rename from test/scratch/test.scratch.cstring.dynload/entry.cpp rename to examples/cpp/example.cpp.cstring.dynload/main.cpp index 0ed3ed7..5ac3cbe 100644 --- a/test/scratch/test.scratch.cstring.dynload/entry.cpp +++ b/examples/cpp/example.cpp.cstring.dynload/main.cpp @@ -1,10 +1,11 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.cstring.dynload/entry.cpp + * File: examples/cpp/example.cpp.cstring.dynload/main.cpp * - * Purpose: Implementation file for the test.scratch.cstring.dynload project. + * Purpose: Windows-only example loading the cstring DLL dynamically via + * `LoadLibrary` / `GetProcAddress`. * * Created: 19th August 2005 - * Updated: 26th October 2024 + * Updated: 2nd August 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -142,7 +143,7 @@ int main(int argc, char** argv) { #if defined(_DEBUG) || \ defined(__SYNSOFT_DBS_DEBUG) - puts("test.scratch.cstring.dynload: " STLSOFT_COMPILER_LABEL_STRING); + puts("example.cpp.cstring.dynload: " STLSOFT_COMPILER_LABEL_STRING); #endif /* debug */ return main_(argc, argv); diff --git a/include/cstring/internal/safestr.h b/include/cstring/internal/safestr.h index bb42553..b2c75e1 100644 --- a/include/cstring/internal/safestr.h +++ b/include/cstring/internal/safestr.h @@ -4,38 +4,39 @@ * Purpose: Internal utility header for the cstring API. * * Created: 13th May 2008 - * Updated: 23rd March 2025 + * Updated: 2nd August 2026 * * Home: http://synesis.com.au/software/ * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2008-2019, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted provided that the following conditions are + * met: * - * - Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - Neither the names of Matthew Wilson and Synesis Information Systems nor * the names of any contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////// */ diff --git a/run_all_examples.sh b/run_all_examples.sh index 36154da..3b97b83 100755 --- a/run_all_examples.sh +++ b/run_all_examples.sh @@ -105,7 +105,7 @@ if [ $status -eq 0 ]; then echo "Running all example programs" fi - for f in $(find $CMakeDir/examples -type f -exec test -x {} \; -print) + for f in $(find $CMakeDir -type f '(' -name 'example.c.*' -o -name 'example.cpp.*' ')' -exec test -x {} \; -print) do if [ $ListOnly -ne 0 ]; then diff --git a/src/cstring.core.c b/src/cstring.core.c index 9d661a2..2e9608b 100644 --- a/src/cstring.core.c +++ b/src/cstring.core.c @@ -4,11 +4,11 @@ * Purpose: The implementation of the cstring core API * * Created: 16th June 1994 - * Updated: 22nd March 2025 + * Updated: 2nd August 2026 * * Home: http://synesis.com.au/software/ * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 1994-2019, Matthew Wilson and Synesis Software * All rights reserved. * diff --git a/src/dllmain.c b/src/dllmain.c index 8676db9..382b994 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -4,38 +4,39 @@ * Purpose: Definition of DllMain for the Win32 platform * * Created: 19th August 2005 - * Updated: 23rd February 2025 + * Updated: 2nd August 2026 * * Home: http://synesis.com.au/software/ * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2005-2019, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: + * modification, are permitted provided that the following conditions are + * met: * - * - Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - Neither the names of Matthew Wilson and Synesis Information Systems nor * the names of any contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////// */ diff --git a/test/scratch/CMakeLists.txt b/test/scratch/CMakeLists.txt index ded91e8..ae4e779 100644 --- a/test/scratch/CMakeLists.txt +++ b/test/scratch/CMakeLists.txt @@ -2,12 +2,3 @@ if(NOT NO_CSTRING_CPP_API) add_subdirectory(libver) endif() -add_subdirectory(test.scratch.auto_buffer) -add_subdirectory(test.scratch.cstring) -add_subdirectory(test.scratch.cstring_create) -add_subdirectory(test.scratch.cstring_vector) -if(NOT NO_CSTRING_CPP_API) - - add_subdirectory(test.scratch.cstring.dynload) - add_subdirectory(test.scratch.HGLOBAL_on_x64) -endif() diff --git a/test/scratch/test.scratch.HGLOBAL_on_x64/CMakeLists.txt b/test/scratch/test.scratch.HGLOBAL_on_x64/CMakeLists.txt deleted file mode 100644 index c87db4c..0000000 --- a/test/scratch/test.scratch.HGLOBAL_on_x64/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - - -# ############################## end of file ############################# # - diff --git a/test/scratch/test.scratch.auto_buffer/CMakeLists.txt b/test/scratch/test.scratch.auto_buffer/CMakeLists.txt deleted file mode 100644 index 159c1cc..0000000 --- a/test/scratch/test.scratch.auto_buffer/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -define_example_program(test_scratch_cstring_auto_buffer entry.c) diff --git a/test/scratch/test.scratch.cstring.dynload/CMakeLists.txt b/test/scratch/test.scratch.cstring.dynload/CMakeLists.txt deleted file mode 100644 index c87db4c..0000000 --- a/test/scratch/test.scratch.cstring.dynload/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - - -# ############################## end of file ############################# # - diff --git a/test/scratch/test.scratch.cstring/CMakeLists.txt b/test/scratch/test.scratch.cstring/CMakeLists.txt deleted file mode 100644 index db13203..0000000 --- a/test/scratch/test.scratch.cstring/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -define_example_program(test_scratch_cstring entry.c) diff --git a/test/scratch/test.scratch.cstring_create/CMakeLists.txt b/test/scratch/test.scratch.cstring_create/CMakeLists.txt deleted file mode 100644 index 1e29d89..0000000 --- a/test/scratch/test.scratch.cstring_create/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4477) -define_example_program(test_scratch_cstring_create entry.c) diff --git a/test/unit/test.unit.cstring.auto_buffer/entry.c b/test/unit/test.unit.cstring.auto_buffer/entry.c index 9f11c82..5bd10b2 100644 --- a/test/unit/test.unit.cstring.auto_buffer/entry.c +++ b/test/unit/test.unit.cstring.auto_buffer/entry.c @@ -1,7 +1,8 @@ /* ///////////////////////////////////////////////////////////////////////// * File: test.unit.cstring.auto_buffer/entry.c * - * Purpose: Implementation file for the test.unit.cstring.auto_buffer project. + * Purpose: Implementation file for the test.unit.cstring.auto_buffer + * project. * * Created: 28th July 2011 * Updated: 2nd August 2026 From 0a36d169ba6a6cbc759dab1ddd2a9cca40599ffd Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 13:46:08 +1000 Subject: [PATCH 18/35] fix: **example.cpp.cstring.dynload**: use `stlsoft::integer_to_decimal_string` (avoids MSVC C4996 on deprecated `integer_to_string`) --- CHANGES.md | 1 + examples/cpp/example.cpp.cstring.dynload/main.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index a75b049..851e918 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ * Suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c**; * Fixed MinGW `size_t` printf format in **example.c.cstring_create** (formerly **test.scratch.cstring_create**); * Moved scratch programs (except **libver**) into **examples/** as `example.c.*` / `example.cpp.*` with `main.c` / `main.cpp` and per-example **README.md**; +* **example.cpp.cstring.dynload**: use `stlsoft::integer_to_decimal_string` (avoids MSVC C4996 on deprecated `integer_to_string`); * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/examples/cpp/example.cpp.cstring.dynload/main.cpp b/examples/cpp/example.cpp.cstring.dynload/main.cpp index 5ac3cbe..a27b354 100644 --- a/examples/cpp/example.cpp.cstring.dynload/main.cpp +++ b/examples/cpp/example.cpp.cstring.dynload/main.cpp @@ -15,7 +15,11 @@ /* STLSoft header files */ #include +#if _STLSOFT_VER >= 0x010a01ff +#include +#else /* ? _STLSOFT_VER */ #include +#endif /* _STLSOFT_VER */ #include /* Standard C++ header files */ @@ -73,7 +77,11 @@ static char const* cstring_error_(CSTRING_RC rc) { static char s_sz[21]; +#if _STLSOFT_VER >= 0x010a01ff + return stlsoft::integer_to_decimal_string(&s_sz[0], STLSOFT_NUM_ELEMENTS(s_sz), rc); +#else /* ? _STLSOFT_VER */ return stlsoft::integer_to_string(&s_sz[0], STLSOFT_NUM_ELEMENTS(s_sz), rc); +#endif /* _STLSOFT_VER */ } #define cstring_error cstring_error_ From 9779ee03609a001c2c594a91470a7487cffe874d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 13:52:14 +1000 Subject: [PATCH 19/35] fix --- CHANGES.md | 2 +- examples/cpp/example.cpp.cstring.dynload/main.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 851e918..ae2ec87 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,7 @@ * Suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c**; * Fixed MinGW `size_t` printf format in **example.c.cstring_create** (formerly **test.scratch.cstring_create**); * Moved scratch programs (except **libver**) into **examples/** as `example.c.*` / `example.cpp.*` with `main.c` / `main.cpp` and per-example **README.md**; -* **example.cpp.cstring.dynload**: use `stlsoft::integer_to_decimal_string` (avoids MSVC C4996 on deprecated `integer_to_string`); +* **example.cpp.cstring.dynload**: use `stlsoft::integer_to_decimal_string` with `static_cast(rc)` (avoids MSVC C4996 and enum static-assert); * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/examples/cpp/example.cpp.cstring.dynload/main.cpp b/examples/cpp/example.cpp.cstring.dynload/main.cpp index a27b354..e0d3e16 100644 --- a/examples/cpp/example.cpp.cstring.dynload/main.cpp +++ b/examples/cpp/example.cpp.cstring.dynload/main.cpp @@ -76,12 +76,17 @@ namespace cstring static char const* cstring_error_(CSTRING_RC rc) { static char s_sz[21]; + int const i = static_cast(rc); #if _STLSOFT_VER >= 0x010a01ff - return stlsoft::integer_to_decimal_string(&s_sz[0], STLSOFT_NUM_ELEMENTS(s_sz), rc); + return stlsoft::integer_to_decimal_string( #else /* ? _STLSOFT_VER */ - return stlsoft::integer_to_string(&s_sz[0], STLSOFT_NUM_ELEMENTS(s_sz), rc); + return stlsoft::integer_to_string( #endif /* _STLSOFT_VER */ + &s_sz[0] + , STLSOFT_NUM_ELEMENTS(s_sz) + , i + ); } #define cstring_error cstring_error_ From 7d84ec538cbb2261d721828c84c02e70b8ffb087 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 13:57:39 +1000 Subject: [PATCH 20/35] fix --- .../cpp/example.cpp.HGLOBAL_on_x64/main.cpp | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp b/examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp index 0c5ea8a..ec7aa1e 100644 --- a/examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp +++ b/examples/cpp/example.cpp.HGLOBAL_on_x64/main.cpp @@ -1,12 +1,13 @@ #include +#include +#include + #ifndef STLSOFT_NUM_ELEMENTS # define STLSOFT_NUM_ELEMENTS(ar) (sizeof(ar) / sizeof(ar[0])) #endif /*!STLSOFT_NUM_ELEMENTS*/ -#include - int main() { @@ -24,18 +25,49 @@ int main() cchTotal += ::strlen(strings[i]); }} - cstring_t payload = cstring_t_DEFAULT; - - CSTRING_RC rc; - cstring_flags_t flags = CSTRING_F_USE_WIN32_GLOBAL_MEMORY; + cstring_t payload = cstring_t_DEFAULT; + cstring_flags_t flags = CSTRING_F_USE_WIN32_GLOBAL_MEMORY; + CSTRING_RC rc = CSTRING_RC_SUCCESS; rc = ::cstring_createLenFn(&payload, NULL, 0, flags, NULL, cchTotal, NULL, NULL); + if (CSTRING_RC_SUCCESS != rc) + { + fprintf(stderr, "cstring_createLenFn() failed: %s\n", cstring_getStatusCodeString(rc)); + + return EXIT_FAILURE; + } rc = ::cstring_createLenEx(&payload, NULL, 0, flags, NULL, cchTotal); + if (CSTRING_RC_SUCCESS != rc) + { + fprintf(stderr, "cstring_createLenEx() failed: %s\n", cstring_getStatusCodeString(rc)); + + return EXIT_FAILURE; + } rc = ::cstring_createEx(&payload, NULL, flags, NULL, cchTotal); + if (CSTRING_RC_SUCCESS != rc) + { + fprintf(stderr, "cstring_createEx() failed: %s\n", cstring_getStatusCodeString(rc)); + + return EXIT_FAILURE; + } { for(size_t i = 0; i != STLSOFT_NUM_ELEMENTS(strings); ++i) { - cstring_append(&payload, strings[i]); + rc = cstring_append(&payload, strings[i]); + if (CSTRING_RC_SUCCESS == rc) + { + printf("appended '%s' => '%.*s'\n" + , strings[i] + , (int)payload.len, payload.ptr + ); + } + else + { + fprintf(stderr, "cstring_append() failed: %s\n", cstring_getStatusCodeString(rc)); + cstring_destroy(&payload); + + return EXIT_FAILURE; + } }} cstring_destroy(&payload); From e1dc6c269f5f1a1d16c3157d4a78e18a0a7b044c Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:03:16 +1000 Subject: [PATCH 21/35] fix --- examples/cpp/example.cpp.cstring.dynload/main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/cpp/example.cpp.cstring.dynload/main.cpp b/examples/cpp/example.cpp.cstring.dynload/main.cpp index e0d3e16..8998a3b 100644 --- a/examples/cpp/example.cpp.cstring.dynload/main.cpp +++ b/examples/cpp/example.cpp.cstring.dynload/main.cpp @@ -102,10 +102,19 @@ static int main_(int /* argc */, char ** /*argv*/) CSTRING_RC (*_yield)(cstring_t* pcs, char** ); CSTRING_RC (*_createEx)(cstring_t* , char const* , size_t , void* , size_t ); +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcast-function-type" +#endif /* __GNUC__ */ + (FARPROC&)(_create) = ::GetProcAddress(hinst, "cstring_create"); (FARPROC&)(_createEx) = ::GetProcAddress(hinst, "cstring_createEx"); (FARPROC&)(_yield) = ::GetProcAddress(hinst, "cstring_yield"); +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif /* __GNUC__ */ + if (NULL != _create && NULL != _yield) { From a90aebb1ccc8f56b4ad4c9d2796bff0bd6ae15ec Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:09:05 +1000 Subject: [PATCH 22/35] fix --- CHANGES.md | 2 +- examples/cpp/example.cpp.cstring.dynload/main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ae2ec87..5676021 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,7 @@ * Suppressed MinGW `-Wcast-function-type` on `GetProcAddress` cast in **cstring.core.c**; * Fixed MinGW `size_t` printf format in **example.c.cstring_create** (formerly **test.scratch.cstring_create**); * Moved scratch programs (except **libver**) into **examples/** as `example.c.*` / `example.cpp.*` with `main.c` / `main.cpp` and per-example **README.md**; -* **example.cpp.cstring.dynload**: use `stlsoft::integer_to_decimal_string` with `static_cast(rc)` (avoids MSVC C4996 and enum static-assert); +* **example.cpp.cstring.dynload**: use `stlsoft::integer_to_decimal_string` with `static_cast(rc)` (avoids MSVC C4996 and enum static-assert); replace `(FARPROC&)` punning with `reinterpret_cast` (MinGW `-Wstrict-aliasing`); * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); diff --git a/examples/cpp/example.cpp.cstring.dynload/main.cpp b/examples/cpp/example.cpp.cstring.dynload/main.cpp index 8998a3b..c43d034 100644 --- a/examples/cpp/example.cpp.cstring.dynload/main.cpp +++ b/examples/cpp/example.cpp.cstring.dynload/main.cpp @@ -107,9 +107,9 @@ static int main_(int /* argc */, char ** /*argv*/) # pragma GCC diagnostic ignored "-Wcast-function-type" #endif /* __GNUC__ */ - (FARPROC&)(_create) = ::GetProcAddress(hinst, "cstring_create"); - (FARPROC&)(_createEx) = ::GetProcAddress(hinst, "cstring_createEx"); - (FARPROC&)(_yield) = ::GetProcAddress(hinst, "cstring_yield"); + _create = reinterpret_cast(::GetProcAddress(hinst, "cstring_create")); + _createEx = reinterpret_cast(::GetProcAddress(hinst, "cstring_createEx")); + _yield = reinterpret_cast(::GetProcAddress(hinst, "cstring_yield")); #if defined(__GNUC__) # pragma GCC diagnostic pop From 9f17a7b42edd76f3bcab28c9d749e9e84ff0ee61 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:16:48 +1000 Subject: [PATCH 23/35] boilerplate --- examples/c/CMakeLists.txt | 4 +--- examples/c/example.c.auto_buffer/CMakeLists.txt | 1 + examples/c/example.c.cstring/CMakeLists.txt | 1 + examples/c/example.c.cstring_create/CMakeLists.txt | 1 + examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt | 1 + examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt | 1 + test/component/test.component.cstring_readline/CMakeLists.txt | 1 + test/scratch/libver/CMakeLists.txt | 1 + 8 files changed, 8 insertions(+), 3 deletions(-) diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 7a7aa81..bd7b7b5 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -1,7 +1,5 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten add_subdirectory(example.c.auto_buffer) add_subdirectory(example.c.cstring) add_subdirectory(example.c.cstring_create) add_subdirectory(example.c.cstring_vector) - - -# ############################## end of file ############################# # diff --git a/examples/c/example.c.auto_buffer/CMakeLists.txt b/examples/c/example.c.auto_buffer/CMakeLists.txt index b41d275..8b26151 100644 --- a/examples/c/example.c.auto_buffer/CMakeLists.txt +++ b/examples/c/example.c.auto_buffer/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_example_program(example.c.auto_buffer main.c) diff --git a/examples/c/example.c.cstring/CMakeLists.txt b/examples/c/example.c.cstring/CMakeLists.txt index c5cde46..44fc9e9 100644 --- a/examples/c/example.c.cstring/CMakeLists.txt +++ b/examples/c/example.c.cstring/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_example_program(example.c.cstring main.c) diff --git a/examples/c/example.c.cstring_create/CMakeLists.txt b/examples/c/example.c.cstring_create/CMakeLists.txt index 5300bb0..77b8a8d 100644 --- a/examples/c/example.c.cstring_create/CMakeLists.txt +++ b/examples/c/example.c.cstring_create/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_example_program(example.c.cstring_create main.c) diff --git a/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt b/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt index 91420d2..722def6 100644 --- a/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt +++ b/examples/cpp/example.cpp.HGLOBAL_on_x64/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_example_program(example.cpp.HGLOBAL_on_x64 main.cpp) diff --git a/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt b/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt index 834cf31..5d9abb1 100644 --- a/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt +++ b/examples/cpp/example.cpp.cstring.dynload/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_example_program(example.cpp.cstring.dynload main.cpp) diff --git a/test/component/test.component.cstring_readline/CMakeLists.txt b/test/component/test.component.cstring_readline/CMakeLists.txt index 5dad2a6..af6840b 100644 --- a/test/component/test.component.cstring_readline/CMakeLists.txt +++ b/test/component/test.component.cstring_readline/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_automated_test_program(test_component_cstring_cstring_readline entry.cpp) diff --git a/test/scratch/libver/CMakeLists.txt b/test/scratch/libver/CMakeLists.txt index 55fb744..7363bfb 100644 --- a/test/scratch/libver/CMakeLists.txt +++ b/test/scratch/libver/CMakeLists.txt @@ -1 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_example_program(libver entry.cpp) From 0c91fe944a0105da2f16347e80e24dbcbf7f9c04 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:19:35 +1000 Subject: [PATCH 24/35] feature: optional shwild for xTests pattern-match assertions Recognise shwild unless --no-shwild / NO_SHWILD; strengthen cstring_getStatusCodeString and cstring.2 test_createN with MATCHES when available. --- CHANGES.md | 2 + CMakeLists.txt | 21 ++++++++- README.md | 4 +- cmake/TargetMacros.cmake | 1 + prepare_cmake.sh | 12 +++++ test/unit/test.unit.cstring.2/entry.c | 13 +++++ .../entry.c | 47 +++++++++++++++++++ 7 files changed, 98 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5676021..54c93d4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,8 @@ * Added **prepare_cmake.sh** `--no-cpp` / CMake `NO_CSTRING_CPP_API`; * CI job for `--no-cpp` builds and unit-tests; * Converted unit-tests **test.unit.cstring.2**, **test.unit.cstring.auto_buffer**, and **test.unit.cstring.cstring_getStatusCodeString** from C++ to C (so they build under `NO_CSTRING_CPP_API`); +* Optional **shwild** recognition (`--no-shwild` / `NO_SHWILD`) for **xTests** pattern-match assertions; +* Applied `XTESTS_TEST_MULTIBYTE_STRING_MATCHES` / `DOES_NOT_MATCH` in **cstring_getStatusCodeString** and **cstring.2** `test_createN` (when **shwild** is available); * Clarified dependencies documentation in **README.md**; diff --git a/CMakeLists.txt b/CMakeLists.txt index 98653f9..248208d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,7 +129,7 @@ option(NO_CSTRING_CPP_API "Disable C++ API (and associated C++ examples/tests)" # - xTests - required for testing; # # optional: -# - (none) +# - shwild - for enhanced match constructs in xTests (unless NO_SHWILD); # # note: NO_CSTRING_CPP_API skips C++ examples and remaining C++ tests; C # unit-tests still require STLSoft and xTests. @@ -177,6 +177,25 @@ if(BUILD_TESTING) endif(BUILD_TESTING) +# ############################ +# shwild (optional) + +if(NOT (NO_SHWILD)) + + if(BUILD_TESTING) + + find_package(shwild QUIET) + + if(shwild_FOUND) + + message("-- CMake package shwild found (version ${shwild_VERSION})") + + add_compile_definitions(XTESTS_HAS_SHWILD) + endif(shwild_FOUND) + endif(BUILD_TESTING) +endif() + + # ############################ # xTests diff --git a/README.md b/README.md index 13bb0da..ba2322e 100644 --- a/README.md +++ b/README.md @@ -129,9 +129,11 @@ The **C** API has no non-standard dependencies. | ---------- | ---- | --------- | | [**STLSoft**](https://github.com/synesissoftware/STLSoft) 1.11 | Test headers / remaining C++ tests and examples | ⚪ Tests only (`BUILD_TESTING`) | | [**xTests**](https://github.com/synesissoftware/xTests) (≥ 0.26) | Unit / component / scratch tests | ⚪ Tests only (`BUILD_TESTING`) | +| [**shwild**](https://github.com/synesissoftware/shwild) | Enhanced pattern-match assertions in **xTests** | ⚪ Optional; tests only (unless `NO_SHWILD` / `--no-shwild`) | -When supplying the `'--no-cpp'` to **prepare_cmake.sh**, - sets the CMake option `NO_CSTRING_CPP_API=ON` - C++ examples and remaining C++ tests are omitted; the **C** unit-tests still require **STLSoft** and **xTests**. +When supplying `'--no-cpp'` to **prepare_cmake.sh** — sets the CMake option `NO_CSTRING_CPP_API=ON` — C++ examples and remaining C++ tests are omitted; the **C** unit-tests still require **STLSoft** and **xTests**. +When supplying `'--no-shwild'` — sets `NO_SHWILD=ON` — **shwild** is not recognised and pattern-match assertions are compiled out; other unit-tests still run. ### Related projects diff --git a/cmake/TargetMacros.cmake b/cmake/TargetMacros.cmake index ecde942..8981dbc 100644 --- a/cmake/TargetMacros.cmake +++ b/cmake/TargetMacros.cmake @@ -49,6 +49,7 @@ function(define_automated_test_program program_name entry_point_source_name) PRIVATE core $<$:STLSoft::STLSoft> + $<$:shwild::core> $,xTests::xTests.core,xTests::core> ) diff --git a/prepare_cmake.sh b/prepare_cmake.sh index ca4f1a5..acff6fe 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -19,6 +19,7 @@ ExamplesDisabled=0 MSVC_MT=0 MinGW="${MinGW:=0}" NO_cxx=0 +NO_shwild=0 RunMake=0 STLSoftDirGiven= TestingDisabled=0 @@ -59,6 +60,10 @@ while [[ $# -gt 0 ]]; do NO_cxx=1 ;; + --no-shwild) + + NO_shwild=1 + ;; --run-make|-m) RunMake=1 @@ -114,6 +119,10 @@ Flags/options: omits the C++ API, C++ examples, and remaining C++ tests (CMake NO_CSTRING_CPP_API). C unit-tests still require STLSoft and xTests + --no-shwild + prevents recognising shwild library (CMake NO_SHWILD); xTests + pattern-match assertions are then unavailable + -m --run-make executes make after a successful running of CMake @@ -158,6 +167,7 @@ echo "Executing CMake (in ${CMakeDir})" if [ $ExamplesDisabled -eq 0 ]; then CMakeBuildExamplesFlag="ON" ; else CMakeBuildExamplesFlag="OFF" ; fi if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="ON" ; fi if [ $NO_cxx -eq 0 ]; then CMakeNoCppApiFlag="OFF" ; else CMakeNoCppApiFlag="ON" ; fi +if [ $NO_shwild -eq 0 ]; then CMakeNoShwild="OFF" ; else CMakeNoShwild="ON" ; fi if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi if [ $TestingDisabled -eq 0 ]; then CMakeBuildTestingFlag="ON" ; else CMakeBuildTestingFlag="OFF" ; fi if [ $VerboseMakefile -eq 0 ]; then CMakeVerboseMakefileFlag="OFF" ; else CMakeVerboseMakefileFlag="ON" ; fi @@ -170,6 +180,7 @@ if [ $MinGW -ne 0 ]; then -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ -DNO_CSTRING_CPP_API:BOOL=$CMakeNoCppApiFlag \ + -DNO_SHWILD:BOOL=$CMakeNoShwild \ -G "MinGW Makefiles" \ -S $Dir \ -B $CMakeDir \ @@ -184,6 +195,7 @@ else -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ -DNO_CSTRING_CPP_API:BOOL=$CMakeNoCppApiFlag \ + -DNO_SHWILD:BOOL=$CMakeNoShwild \ -S $Dir \ -B $CMakeDir \ || (cd ->/dev/null ; exit 1) diff --git a/test/unit/test.unit.cstring.2/entry.c b/test/unit/test.unit.cstring.2/entry.c index 8672f00..4603462 100644 --- a/test/unit/test.unit.cstring.2/entry.c +++ b/test/unit/test.unit.cstring.2/entry.c @@ -23,6 +23,11 @@ * general includes */ +#ifdef XTESTS_HAS_SHWILD + /* shwild header files */ +# include +#endif /* XTESTS_HAS_SHWILD */ + /* xTests header files */ #include @@ -133,7 +138,15 @@ static void test_createN(void) TEST_PTR_NE(NULL, str.ptr); TEST_INT_GE(str.len, str.capacity); +#ifdef XTESTS_HAS_SHWILD + + /* created string must be entirely '~' */ + TEST_MS_DOES_NOT_MATCH("*[a-zA-Z0-9]*", str.ptr); + TEST_MS_DOES_NOT_MATCH("*[ ,.<>/?'\";:[{]}`!@#$%^&*()=_+\\\\|-]*", str.ptr); +#else /* ? XTESTS_HAS_SHWILD */ + TEST_PTR_EQ(NULL, strpbrk(str.ptr, "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890,<.>/?'\";:[{]}`!@#$%^&*()-_=+\\|")); +#endif /* XTESTS_HAS_SHWILD */ cstring_destroy(&str); diff --git a/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c b/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c index db5e062..9b6347c 100644 --- a/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c +++ b/test/unit/test.unit.cstring.cstring_getStatusCodeString/entry.c @@ -20,6 +20,11 @@ * includes */ +#ifdef XTESTS_HAS_SHWILD + /* shwild header files */ +# include +#endif /* XTESTS_HAS_SHWILD */ + /* xTests header files */ #include @@ -144,6 +149,27 @@ static void test_known(void) { XTESTS_TEST_MULTIBYTE_STRING_NOT_EQUAL("<>", cstring_getStatusCodeString(knownCodes[i])); }} + +#ifdef XTESTS_HAS_SHWILD + + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation completed successfully", cstring_getStatusCodeString(CSTRING_RC_SUCCESS)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("out of memory", cstring_getStatusCodeString(CSTRING_RC_OUTOFMEMORY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the cstring *", cstring_getStatusCodeString(CSTRING_RC_FIXED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the cstring *", cstring_getStatusCodeString(CSTRING_RC_BORROWED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the cstring *", cstring_getStatusCodeString(CSTRING_RC_READONLY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("*invalid*", cstring_getStatusCodeString(CSTRING_RC_INVALIDARENA)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("custom arena functionality not currently supported", cstring_getStatusCodeString(CSTRING_RC_CUSTOMARENANOTSUPPORTED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the current capacity would be exceeded*", cstring_getStatusCodeString(CSTRING_RC_EXCEEDFIXEDCAPACITY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the current capacity would be exceeded*", cstring_getStatusCodeString(CSTRING_RC_EXCEEDBORROWEDCAPACITY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("yield operation from a dynamic-library version of cstring was not allowed", cstring_getStatusCodeString(CSTRING_RC_CANNOTYIELDFROMSO)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("cannot use arena parameter for both borrowed memory and custom arena", cstring_getStatusCodeString(CSTRING_RC_ARENAOVERLOADED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("*invalid*", cstring_getStatusCodeString(CSTRING_RC_INVALIDSTREAM)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("reached the end of stream", cstring_getStatusCodeString(CSTRING_RC_EOF)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("*invalid*", cstring_getStatusCodeString(CSTRING_RC_INVALIDSECTION)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("an I/O error occured", cstring_getStatusCodeString(CSTRING_RC_IOERROR)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("system-specific failure occurred", cstring_getStatusCodeString(CSTRING_RC_SYSTEMSPECIFICFAILURE)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("request exceeded inherent or runtime limit", cstring_getStatusCodeString(CSTRING_RC_REQUESTTOOLARGE)); +#endif /* XTESTS_HAS_SHWILD */ } static void test_random(void) @@ -169,6 +195,27 @@ static void test_known_deprecated(void) { XTESTS_TEST_MULTIBYTE_STRING_NOT_EQUAL("<>", cstring_error(knownCodes[i])); }} + +#ifdef XTESTS_HAS_SHWILD + + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation completed successfully", cstring_error(CSTRING_RC_SUCCESS)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("out of memory", cstring_error(CSTRING_RC_OUTOFMEMORY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the cstring *", cstring_error(CSTRING_RC_FIXED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the cstring *", cstring_error(CSTRING_RC_BORROWED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the cstring *", cstring_error(CSTRING_RC_READONLY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("*invalid*", cstring_error(CSTRING_RC_INVALIDARENA)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("custom arena functionality not currently supported", cstring_error(CSTRING_RC_CUSTOMARENANOTSUPPORTED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the current capacity would be exceeded*", cstring_error(CSTRING_RC_EXCEEDFIXEDCAPACITY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("operation cannot procede because the current capacity would be exceeded*", cstring_error(CSTRING_RC_EXCEEDBORROWEDCAPACITY)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("yield operation from a dynamic-library version of cstring was not allowed", cstring_error(CSTRING_RC_CANNOTYIELDFROMSO)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("cannot use arena parameter for both borrowed memory and custom arena", cstring_error(CSTRING_RC_ARENAOVERLOADED)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("*invalid*", cstring_error(CSTRING_RC_INVALIDSTREAM)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("reached the end of stream", cstring_error(CSTRING_RC_EOF)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("*invalid*", cstring_error(CSTRING_RC_INVALIDSECTION)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("an I/O error occured", cstring_error(CSTRING_RC_IOERROR)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("system-specific failure occurred", cstring_error(CSTRING_RC_SYSTEMSPECIFICFAILURE)); + XTESTS_TEST_MULTIBYTE_STRING_MATCHES("request exceeded inherent or runtime limit", cstring_error(CSTRING_RC_REQUESTTOOLARGE)); +#endif /* XTESTS_HAS_SHWILD */ } static void test_random_deprecated(void) From f2b16394783385161e5a331f55adf17dd0c1ba99 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:32:58 +1000 Subject: [PATCH 25/35] boilerplate --- AUTHORS.md | 9 +++++++-- FAQ.md | 6 +++++- INSTALL.md | 14 +++++++++++--- KNOWN_ISSUES.md | 4 +--- README.md | 5 +++-- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 540adcd..631520a 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,12 +1,17 @@ # cstring - Authors -## Major Contributors: + +## Major Contributors * Matt Wilson ([mwsis](https://github.com/mwsis)) +## Defect reports, fixes and suggestions (for which we are very grateful) + +* \ + + Contributions are welcomed. - diff --git a/FAQ.md b/FAQ.md index a89362e..c5ae929 100644 --- a/FAQ.md +++ b/FAQ.md @@ -4,20 +4,24 @@ The FAQ list is under (constant) development. If you post a question on the Issues forum (https://github.com/synesissoftware/cstring/issues) it will be used to create one. + +## Table of Contents + - [Q1: "How do I build cstring?"](#q1-how-do-i-build-cstring) - [Q2: "Does cstring have its own unit-tests?"](#q2-does-cstring-have-its-own-unit-tests) # FAQs: + ## Q1: "How do I build cstring?" See instructions in [INSTALL.md](./INSTALL.md). + ## Q2: "Does cstring have its own unit-tests?" Yes, under the **./test/unit** and **./test/unit** directorie. - diff --git a/INSTALL.md b/INSTALL.md index 856d887..db31033 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,8 +1,16 @@ -# cstring - Install +# cstring - Installation and Use ----- +## Table of Contents +- [CMake](#cmake) +- [Bundled](#bundled) + + +## CMake - +## Bundled + + + diff --git a/KNOWN_ISSUES.md b/KNOWN_ISSUES.md index 8a7f9fa..c2ef3c5 100644 --- a/KNOWN_ISSUES.md +++ b/KNOWN_ISSUES.md @@ -1,11 +1,9 @@ # cstring - Known Issues -## cstring 4 Known Issues: ------------------------- +## cstring 4 Known Issues * \ - diff --git a/README.md b/README.md index ba2322e..a298e2a 100644 --- a/README.md +++ b/README.md @@ -27,11 +27,12 @@ ## Installation -**ctring** comes with **CMake** configuration/build files. +Detailed instructions - via **CMake**, via bundling - are provided in the accompanying [INSTALL.md](./INSTALL.md) file. ## Components + ### API / core library The C API is based around two structures: @@ -59,7 +60,6 @@ The C API is based around two structures: and must not be modified by any application code. */ }; ``` - the structure, defined as follows: **Creation/destruction functions**: @@ -135,6 +135,7 @@ When supplying `'--no-cpp'` to **prepare_cmake.sh** — sets the CMake option `N When supplying `'--no-shwild'` — sets `NO_SHWILD=ON` — **shwild** is not recognised and pattern-match assertions are compiled out; other unit-tests still run. + ### Related projects Projects in which **cstring** is used include: From 7e520dbeb06816bbc5425ce810f505fb6e9a691b Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:37:54 +1000 Subject: [PATCH 26/35] chore: full **INSTALL.md** --- INSTALL.md | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index db31033..d0c9b93 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,5 +1,17 @@ # cstring - Installation and Use +**cstring** is a classic-form C library, insofar as it has implementation +files in its **src** directory and header files in its **include/cstring** +directory. Thus, once "installed", one must simply include +**cstring/cstring.h** (and, where needed, **cstring/cstring.vector.h**), and +compile-in or link-in the implementation. + +The **C** API has no non-standard dependencies. Building the project's tests +additionally requires **STLSoft** and **xTests** (and optionally recognises +**shwild**). C++ examples and remaining C++ tests may be omitted with +`--no-cpp` / `NO_CSTRING_CPP_API`; the **C** unit-tests still require +**STLSoft** and **xTests** unless testing is disabled. + ## Table of Contents @@ -9,8 +21,146 @@ ## CMake +The primary choice for installation is by use of **CMake**. + +1. Obtain the latest distribution of **cstring**, from + https://github.com/synesissoftware/cstring/, e.g. + + ```bash + $ mkdir -p ~/open-source + $ cd ~/open-source + $ git clone https://github.com/synesissoftware/cstring/ + ``` + +2. Prepare the CMake configuration, via the **prepare_cmake.sh** script. + + For a minimal library install (no **STLSoft** / **xTests** required): + + ```bash + $ cd ~/open-source/cstring + $ ./prepare_cmake.sh --no-cpp --disable-testing -v + ``` + + For a full build including examples and tests, install **STLSoft** 1.11 + (and **xTests** for tests) via their own **CMake** scripts first, then: + + ```bash + $ cd ~/open-source/cstring + $ ./prepare_cmake.sh -v + ``` + + Useful optional flags: + + * `--no-cpp` / `-C` — omit C++ examples and remaining C++ tests + (`NO_CSTRING_CPP_API`); + * `--no-shwild` — do not recognise **shwild** (`NO_SHWILD`); + * `--disable-examples` / `-E` — omit examples (`BUILD_EXAMPLES=OFF`); + * `--disable-testing` / `-T` — omit tests (`BUILD_TESTING=OFF`); + * `--stlsoft-root-dir` / `-s` — pass an **STLSoft** source-tree root when + it is not available as an installed **CMake** package; + + (**Hint**: execute `$ ./prepare_cmake.sh --help` for more information.) + +3. Run a build of the generated **CMake**-derived build files via the + **build_cmake.sh** script, as in: + + ```bash + $ ./build_cmake.sh + ``` + + (**NOTE**: if you provide the flag `--run-make` (=== `-m`) in step 2 then + you do not need this step.) + +4. As a check (when testing was not disabled), execute the built unit-test + programs via **run_all_unit_tests.sh**, as in: + + ```bash + $ ./run_all_unit_tests.sh + ``` + + Examples (when enabled) may be exercised via **run_all_examples.sh**. + +5. Install the library on the host, via `cmake`, as in: + + ```bash + $ sudo cmake --install ${SIS_CMAKE_BUILD_DIR:-./_build} --config Release + ``` + +6. Then to use the library, it is a simple matter as follows: + + 1. Assuming a simplest possible program to verify the installation: + + ```c + /* main.c */ + #include + + #include + #include + + int main(void) + { + cstring_t cs; + CSTRING_RC rc = cstring_create(&cs, "Hello"); + + if (CSTRING_RC_SUCCESS != rc) + { + fprintf(stderr, "cstring_create: %s\n", cstring_getStatusCodeString(rc)); + + return EXIT_FAILURE; + } + + printf("len=%zu contents='%s'\n", cs.len, cs.ptr); + + cstring_destroy(&cs); + + return EXIT_SUCCESS; + } + ``` + + 2. Compile your project against **cstring**: + + Due to the installation step (step 5 above) there is no requirement + for an explicit include directory for **cstring**: + + ```bash + $ cc -c main.c + ``` + + 3. Link your project against **cstring**: + + Due to the installation step (step 5 above) there is no requirement + for an explicit library directory for **cstring**: + + ```bash + $ cc main.o -lcstring + ``` + + 4. Test your project: + + ```bash + $ ./a.out + len=5 contents='Hello' + $ + ``` + + Consumers that use **CMake** may instead depend on the installed package: + + ```cmake + find_package(cstring REQUIRED) + target_link_libraries(your_target PRIVATE cstring::core) + ``` + ## Bundled +**cstring** is small enough that it is commonly bundled into other projects. +In that case: + +* add **cstring**'s **include** directory to your project's include path; +* compile **src/cstring.core.c** and **src/cstring.vector.c** into your build + (or link a previously built **libcstring**); and +* `#include ` (and **cstring/cstring.vector.h** where + needed). + From b1e24777be7346c08899e7c53a00e2d62beaded4 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:48:14 +1000 Subject: [PATCH 27/35] Add Doxygen config and generate_doxygen.sh for API docs. Introduce a Diagnosticism-style Doxyfile and mainpage, allow tracking doc/, and fix the vector header \file path so generation is warning-clean. --- .gitignore | 1 - Doxyfile | 69 +++++++++++++++++++++++++++ doc/mainpage.md | 55 ++++++++++++++++++++++ generate_doxygen.sh | 81 ++++++++++++++++++++++++++++++++ include/cstring/cstring.vector.h | 8 ++-- 5 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 Doxyfile create mode 100644 doc/mainpage.md create mode 100755 generate_doxygen.sh diff --git a/.gitignore b/.gitignore index eed185f..bb24aff 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,6 @@ bin/ ipch/ lib/ -/doc/ /docs/ /dox/ /dox diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..47aae46 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,69 @@ +# Doxyfile for cstring (C API) + +PROJECT_NAME = "cstring" +PROJECT_BRIEF = "Extensible C-style strings and vectors of such, for Unix and Windows" +PROJECT_NUMBER = 4.0.13 + +# Prefer SIS_CMAKE_BUILD_DIR-aligned output (same convention as Diagnosticism). +# ./dox/ remains gitignored for legacy/local runs that override OUTPUT_DIRECTORY. +OUTPUT_DIRECTORY = _build/doxygen +CREATE_SUBDIRS = NO + +OPTIMIZE_OUTPUT_FOR_C = YES +OUTPUT_LANGUAGE = English +TAB_SIZE = 4 +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = . +STRIP_FROM_INC_PATH = include +TIMESTAMP = NO + +INPUT = include/cstring \ + doc +FILE_PATTERNS = *.h \ + *.md +RECURSIVE = NO +EXCLUDE = include/cstring/internal + +USE_MDFILE_AS_MAINPAGE = doc/mainpage.md + +EXAMPLE_PATH = examples +EXAMPLE_RECURSIVE = YES + +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO + +GENERATE_HTML = YES +GENERATE_LATEX = NO +HTML_OUTPUT = html + +GENERATE_TREEVIEW = YES +DISABLE_INDEX = NO +SEARCHENGINE = YES +SOURCE_BROWSER = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES + +MARKDOWN_SUPPORT = YES +JAVADOC_AUTOBRIEF = YES +QUIET = YES + +WARN_IF_UNDOCUMENTED = YES +WARN_NO_PARAMDOC = YES +WARN_IF_DOC_ERROR = YES + +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SKIP_FUNCTION_MACROS = YES +# Skip internal version/edit noise; strip linkage macros for cleaner prototypes. +PREDEFINED = CSTRING_DOCUMENTATION_SKIP_SECTION \ + CSTRING_EXTERN_C= + +HAVE_DOT = NO + + +# ########################### end of file ########################### # diff --git a/doc/mainpage.md b/doc/mainpage.md new file mode 100644 index 0000000..f45677c --- /dev/null +++ b/doc/mainpage.md @@ -0,0 +1,55 @@ +# cstring {#mainpage} + +**cstring** is a small, standalone library that provides extensible C-style +string instances and extensible arrays of such, for Unix and Windows. + + +## Components + +| Module | Header | Summary | +| ------ | ------ | ------- | +| @ref group__cstring_api | `` | Core `cstring_t` API (create, mutate, stream I/O, status codes) | +| @ref group__cstring_api__flags | `` | Memory-arena and capacity control flags | +| Vector API | `` | `cstring_vector_t` sequences of `cstring_t` | + + +## Quick start + +```c +#include + +#include +#include + +int main(void) +{ + cstring_t cs; + CSTRING_RC rc = cstring_create(&cs, "Hello"); + + if (CSTRING_RC_SUCCESS != rc) + { + fprintf(stderr, "%s\n", cstring_getStatusCodeString(rc)); + + return EXIT_FAILURE; + } + + printf("len=%zu contents='%s'\n", cs.len, cs.ptr); + + cstring_destroy(&cs); + + return EXIT_SUCCESS; +} +``` + +Consumer **CMake** projects may use `find_package(cstring)` and link +`cstring::core`. See +[INSTALL.md](https://github.com/synesissoftware/cstring/blob/master/INSTALL.md) +for build and install instructions. + + +## Related projects + +* [shwild.fnmatch](https://github.com/synesissoftware/shwild.fnmatch) + + + diff --git a/generate_doxygen.sh b/generate_doxygen.sh new file mode 100755 index 0000000..cbe6d58 --- /dev/null +++ b/generate_doxygen.sh @@ -0,0 +1,81 @@ +#! /bin/bash + +############################################################################# +# File: generate_doxygen.sh +# +# Purpose: Generates HTML API documentation from public headers via Doxygen +# +############################################################################# + +ScriptPath=$0 +Dir=$(cd "$(dirname "$ScriptPath")" && pwd) +Basename=$(basename "$ScriptPath") +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Generates HTML API documentation from public headers via Doxygen + +$ScriptPath [ ... flags/options ... ] + +Flags/options: + + standard flags: + + --help + displays this help and terminates + +Environment: + + SIS_CMAKE_BUILD_DIR + CMake build directory (default: /_build); documentation is + written to /doxygen/html/ + +EOF + + exit 0 + ;; + *) + + >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +cd "$Dir" || exit 1 + +if ! command -v doxygen >/dev/null 2>&1; then + >&2 echo "$ScriptPath: doxygen not found on PATH" + exit 1 +fi + +mkdir -p "${CMakeDir}/doxygen" + +{ + cat Doxyfile + echo "" + echo "# Output directory (overridden by ${Basename})" + echo "OUTPUT_DIRECTORY = ${CMakeDir}/doxygen" +} | doxygen - + +echo "API documentation written to ${CMakeDir}/doxygen/html/index.html" + + +# ############################## end of file ############################# # diff --git a/include/cstring/cstring.vector.h b/include/cstring/cstring.vector.h index c3778ba..3671f7a 100644 --- a/include/cstring/cstring.vector.h +++ b/include/cstring/cstring.vector.h @@ -4,11 +4,11 @@ * Purpose: Definition of the cstring.vector API. * * Created: 21st January 2012 - * Updated: 1st September 2025 + * Updated: 2nd August 2026 * * Home: http://synesis.com.au/software/ * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2012-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -41,7 +41,7 @@ * ////////////////////////////////////////////////////////////////////// */ -/** \file cstring/vector.h Definition of the cstring.vector API +/** \file cstring/cstring.vector.h Definition of the cstring.vector API */ #ifndef CSTRING_INCL_CSTRING_H_VECTOR @@ -55,7 +55,7 @@ # define CSTRING_VER_CSTRING_H_VECTOR_MAJOR 1 # define CSTRING_VER_CSTRING_H_VECTOR_MINOR 0 # define CSTRING_VER_CSTRING_H_VECTOR_REVISION 2 -# define CSTRING_VER_CSTRING_H_VECTOR_EDIT 7 +# define CSTRING_VER_CSTRING_H_VECTOR_EDIT 8 #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ From 38bbf6ccc4db8eefba659ab71cfb8b203b41f5ae Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:50:59 +1000 Subject: [PATCH 28/35] chore: completed **FAQ.md** --- FAQ.md | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/FAQ.md b/FAQ.md index c5ae929..04d0071 100644 --- a/FAQ.md +++ b/FAQ.md @@ -9,6 +9,8 @@ it will be used to create one. - [Q1: "How do I build cstring?"](#q1-how-do-i-build-cstring) - [Q2: "Does cstring have its own unit-tests?"](#q2-does-cstring-have-its-own-unit-tests) +- [Q3: "How do I build without the C++ examples and tests?"](#q3-how-do-i-build-without-the-c-examples-and-tests) +- [Q4: "Where are the examples?"](#q4-where-are-the-examples) # FAQs: @@ -16,12 +18,53 @@ it will be used to create one. ## Q1: "How do I build cstring?" -See instructions in [INSTALL.md](./INSTALL.md). +See [INSTALL.md](./INSTALL.md) for the recommended **CMake** flow +(**prepare_cmake.sh**, then **build_cmake.sh**). + +For a minimal library install with no external dependencies: + +```bash +$ ./prepare_cmake.sh --no-cpp --disable-testing -m +``` + +For a full build including examples and tests, install **STLSoft** 1.11 and +**xTests** first, then: + +```bash +$ ./prepare_cmake.sh -m +``` + +Execute `$ ./prepare_cmake.sh --help` for the full set of options. ## Q2: "Does cstring have its own unit-tests?" -Yes, under the **./test/unit** and **./test/unit** directorie. +Yes. Automated tests live under: + +* **./test/unit** — unit tests; +* **./test/component** — component tests; +* **./test/scratch** — scratch / exploratory programs (for example **libver**); + +When testing is enabled, build them via **prepare_cmake.sh** / **build_cmake.sh** +and run with **run_all_unit_tests.sh** (and **CTest** where configured). Tests +require **STLSoft** and **xTests** (and may optionally recognise **shwild**). + + +## Q3: "How do I build without the C++ examples and tests?" + +Pass `--no-cpp` (or `-C`) to **prepare_cmake.sh**, which sets CMake +`NO_CSTRING_CPP_API=ON`. That omits C++ examples and remaining C++ tests. + +The **C** unit-tests still require **STLSoft** and **xTests** unless you also +pass `--disable-testing` / `-T`. + + +## Q4: "Where are the examples?" + +Examples live under **examples/** (`c/` and `cpp/`), each with a short +**README.md**. They are built when `BUILD_EXAMPLES` is on (the default); omit +them with `--disable-examples` / `-E`. Run built examples via +**run_all_examples.sh**. See the examples table in [README.md](./README.md). From 90cbcfbc03ebe5f3c1aae7c8db82d16daffcbb5d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:53:58 +1000 Subject: [PATCH 29/35] chore: completed **README.md** --- README.md | 94 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index a298e2a..d2b9096 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,13 @@ - [Installation](#installation) - [Components](#components) - - [API / core library](#api--core-library) + - [Types](#types) + - [String API](#string-api) + - [Status and capacity](#status-and-capacity) + - [Creation/destruction functions](#creationdestruction-functions) + - [Modification functions\*\*](#modification-functions) + - [File functions\*\*](#file-functions) + - [Vector API](#vector-api) - [Examples](#examples) - [Project Information](#project-information) - [Where to get help](#where-to-get-help) @@ -33,7 +39,7 @@ Detailed instructions - via **CMake**, via bundling - are provided in the accomp ## Components -### API / core library +### Types The C API is based around two structures: * `cstring_t`, which represents a resizeable string instance; and @@ -62,36 +68,60 @@ The C API is based around two structures: ``` -**Creation/destruction functions**: - -* `cstring_init()` - initialises an instance to default values (and does not required a following call to `cstring_destroy()`); -* `cstring_create()` - creates an instance from a C-style string; -* `cstring_createLen()` - creates an instance from a (portion of a) C-style string; -* `cstring_createN()` - creates an instance from a a number of repetitions of a `char` value; -* `cstring_createEx()` - creates an instance with special characteristics (such as using stack memory, ...); -* `cstring_createExLen()` - creates an instance with special characteristics (such as using stack memory, ...); -* `cstring_destroy()` - -**Modification functions**: - -* `cstring_assign()` - T.B.C.; -* `cstring_assignLen()` - T.B.C.; -* `cstring_copy()` - T.B.C.; -* `cstring_append()` - T.B.C.; -* `cstring_appendLen()` - T.B.C.; -* `cstring_insert()` - T.B.C.; -* `cstring_insertLen()` - T.B.C.; -* `cstring_replace()` - T.B.C.; -* `cstring_replaceLen()` - T.B.C.; -* `cstring_replaceAll()` - T.B.C.; -* `cstring_truncate()` - T.B.C.; -* `cstring_swap()` - T.B.C.; - -**File functions**: - -* `cstring_readline()` - reads in a line of text from the given text stream; -* `cstring_write()` - writes a string to the given text stream; -* `cstring_writeline()` - writes a line of text to the given text stream; +### String API + +Defined in **cstring/cstring.h**: + + +#### Status and capacity + +* `cstring_getStatusCodeString()` — returns a nul-terminated description of a `CSTRING_RC` code; +* `cstring_setCapacity()` — adjusts capacity (subject to fixed / borrowed / readonly rules); +* `cstring_yield2()` — yields ownership of the payload (and raw buffer) to the caller; + +#### Creation/destruction functions + +* `cstring_init()` — initialises an instance to default values (and does not require a following call to `cstring_destroy()`); +* `cstring_create()` — creates an instance from a C-style string; +* `cstring_createLen()` — creates an instance from a (portion of a) C-style string; +* `cstring_createN()` — creates an instance from a number of repetitions of a character value; +* `cstring_createEx()` — creates an instance with special characteristics (borrowed buffer, allocator flags, …); +* `cstring_createLenEx()` — as `cstring_createEx()`, from a fixed number of characters; +* `cstring_destroy()` — releases resources and resets the instance; + +#### Modification functions** + +* `cstring_assign()` — assigns a C-style string (may reallocate); +* `cstring_assignLen()` — assigns a fixed character count (embedded NULs allowed); +* `cstring_copy()` — copies one `cstring_t` into another; +* `cstring_append()` — appends a C-style string; +* `cstring_appendLen()` — appends a fixed character count; +* `cstring_insert()` — inserts a C-style string at an index (`CSTRING_FROM_END` supported); +* `cstring_insertLen()` — inserts a fixed character count at an index; +* `cstring_replace()` — replaces a section at an index with a C-style string; +* `cstring_replaceLen()` — replaces a section at an index with a fixed character count; +* `cstring_replaceAll()` — replaces all occurrences of one substring with another; +* `cstring_truncate()` — shortens the logical length (capacity unchanged); +* `cstring_swap()` — swaps the contents of two instances; + +#### File functions** + +* `cstring_readline()` — reads a line of text from the given text stream into the instance; +* `cstring_write()` — writes the string to the given text stream; +* `cstring_writeline()` — writes the string followed by a newline to the given text stream; + + +### Vector API + +Defined in **cstring/cstring.vector.h**: + +* `cstring_vector_init()` — initialises a vector, optionally with a minimum capacity; +* `cstring_vector_create()` — creates a vector of a given initial size (elements default-initialised); +* `cstring_vector_destroy()` — destroys each element and frees the vector buffer; +* `cstring_vector_truncate()` — shortens the vector, destroying trailing elements; +* `cstring_vector_insertAt()` — inserts one or more `cstring_t` instances at a position; +* `cstring_vector_append()` / `cstring_vector_prepend()` — macros over `cstring_vector_insertAt()`; +* `cstring_vector_readLines()` — reads lines from a stream into the vector; ## Examples From 3e1126da1bd55f27cbd3a38b0676960821b6e84b Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:55:26 +1000 Subject: [PATCH 30/35] chore: typo --- include/cstring/cstring.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/cstring/cstring.h b/include/cstring/cstring.h index df99274..a07cd43 100644 --- a/include/cstring/cstring.h +++ b/include/cstring/cstring.h @@ -56,7 +56,7 @@ # define CSTRING_VER_CSTRING_H_CSTRING_MAJOR 3 # define CSTRING_VER_CSTRING_H_CSTRING_MINOR 11 # define CSTRING_VER_CSTRING_H_CSTRING_REVISION 10 -# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 81 +# define CSTRING_VER_CSTRING_H_CSTRING_EDIT 82 #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ /** \def CSTRING_VER_MAJOR @@ -114,19 +114,19 @@ #endif /* !CSTRING_DOCUMENTATION_SKIP_SECTION */ /** \def CSTRING_VER_MAJOR - * The major version number of **BDUT** + * The major version number of **cstring** */ /** \def CSTRING_VER_MINOR - * The minor version number of **BDUT** + * The minor version number of **cstring** */ /** \def CSTRING_VER_PATCH - * The patch version number of **BDUT** + * The patch version number of **cstring** */ /** \def CSTRING_VER - * The current composite version number of **BDUT** + * The current composite version number of **cstring** */ #define CSTRING_VER_MAJOR 4 From 7a991748bd50959402b234e3c0c981f8a37f8400 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:56:30 +1000 Subject: [PATCH 31/35] chore: more sophisticated discrimination of Unix compilation --- examples/CMakeLists.txt | 8 ++++---- examples/cpp/CMakeLists.txt | 4 ++-- src/CMakeLists.txt | 10 +++++----- test/CMakeLists.txt | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6de1334..b339d84 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,13 +1,13 @@ include_directories(${CMAKE_SOURCE_DIR}/include) -if(UNIX) +if(_BUILD_AS_UNIX) add_definitions(-DUNIX) add_definitions(-Dunix) -endif(UNIX) +endif(_BUILD_AS_UNIX) -if(WIN32) +if(_BUILD_AS_WIN32) if(CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -23,7 +23,7 @@ if(WIN32) # suppress implicit-link file add_definitions(-DCSTRING_INCL_CSTRING_H_IMPLICIT_LINK) -endif(WIN32) +endif(_BUILD_AS_WIN32) if((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914)) diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index 7028c62..cffad6f 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -1,8 +1,8 @@ -if(WIN32) +if(_BUILD_AS_WIN32) add_subdirectory(example.cpp.cstring.dynload) add_subdirectory(example.cpp.HGLOBAL_on_x64) -endif(WIN32) +endif(_BUILD_AS_WIN32) # ############################## end of file ############################# # diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 320de83..3c14f3c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,18 +5,18 @@ # Purpose: CMake lists file for cstring core library # # Created: ... -# Updated: 23rd February 2025 +# Updated: 2nd August 2026 # # ######################################################################## # -if(UNIX) +if(_BUILD_AS_UNIX) add_definitions(-DUNIX) add_definitions(-Dunix) -endif(UNIX) +endif(_BUILD_AS_UNIX) -if(WIN32) +if(_BUILD_AS_WIN32) if(CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -34,7 +34,7 @@ if(WIN32) add_definitions(-DCSTRING_INCL_CSTRING_H_IMPLICIT_LINK) add_definitions(-DCLASP_CMDLINE_ARGS_NO_RECLS_ON_WINDOWS) -endif(WIN32) +endif(_BUILD_AS_WIN32) if((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914)) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8fd2aa6..b843a40 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,13 +1,13 @@ include_directories(${CMAKE_SOURCE_DIR}/include) -if(UNIX) +if(_BUILD_AS_UNIX) add_definitions(-DUNIX) add_definitions(-Dunix) -endif(UNIX) +endif(_BUILD_AS_UNIX) -if(WIN32) +if(_BUILD_AS_WIN32) if(CMAKE_SIZEOF_VOID_P EQUAL 8) @@ -23,7 +23,7 @@ if(WIN32) # suppress implicit-link file add_definitions(-DCSTRING_INCL_CSTRING_H_IMPLICIT_LINK) -endif(WIN32) +endif(_BUILD_AS_WIN32) if((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914)) From ac8ec0663222fa33eb83229bcb2e6cc3d2d570aa Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 14:59:49 +1000 Subject: [PATCH 32/35] chore: CMake refinement --- CMakeLists.txt | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 248208d..dbed7ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,20 +180,23 @@ endif(BUILD_TESTING) # ############################ # shwild (optional) -if(NOT (NO_SHWILD)) +if(BUILD_TESTING) - if(BUILD_TESTING) + if(NOT (NO_SHWILD)) - find_package(shwild QUIET) + if(BUILD_TESTING) - if(shwild_FOUND) + find_package(shwild QUIET) - message("-- CMake package shwild found (version ${shwild_VERSION})") + if(shwild_FOUND) - add_compile_definitions(XTESTS_HAS_SHWILD) - endif(shwild_FOUND) - endif(BUILD_TESTING) -endif() + message("-- CMake package shwild found (version ${shwild_VERSION})") + + add_compile_definitions(XTESTS_HAS_SHWILD) + endif(shwild_FOUND) + endif(BUILD_TESTING) + endif() +endif(BUILD_TESTING) # ############################ From 1df5f97d64072782ec94d11864f777a10a1ee575 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 15:04:00 +1000 Subject: [PATCH 33/35] chore: completed **TODO.md** --- TODO.md | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/TODO.md b/TODO.md index 9f76f03..516e588 100644 --- a/TODO.md +++ b/TODO.md @@ -10,12 +10,8 @@ ## Functional improvements -* [ ] Examples: - * [ ] . . . -* [ ] Tests: - * [ ] Scratch: - * [ ] **libver**; - * [ ] . . . +* [x] ~~~Examples: moved scratch programs into **examples/** with per-example **README.md**~~~ - ✅; +* [x] ~~~Scratch **libver** retained under **test/scratch**~~~ - ✅; * [x] ~~~Delete Visual Studio 98 files~~~ - ✅; * [x] ~~~Delete Visual Studio 2003+ files~~~ - ✅; @@ -29,31 +25,24 @@ ## Packaging improvements -* [ ] README: - * [x] badges; - * [ ] intro examples; -* [ ] Boilerplate: - * [ ] EOFs; - * [ ] .txt => .md; - * [ ] layout +* [x] ~~~README: badges; Components descriptions; examples table~~~ - ✅; +* [x] ~~~Boilerplate: **INSTALL.md**, **FAQ.md**, **KNOWN_ISSUES.md**, **AUTHORS.md** layout~~~ - ✅; * [ ] CMake: - * [ ] custom definitions: - * [ ] `_BUILD_AS_UNIX` / `_BUILD_AS_WIN32`; - * [ ] . . . - * [ ] `CMAKE_INSTALL_LIBDIR`; - * [ ] **CTest**; + * [x] ~~~custom definitions: `_BUILD_AS_UNIX` / `_BUILD_AS_WIN32`~~~ - ✅; + * [ ] `CMAKE_INSTALL_LIBDIR` (export config still references `LIB_INSTALL_DIR` in one path); + * [x] ~~~**CTest**~~~ - ✅; * [ ] build DLL on Windows; - * [ ] `/MT` build option for Visual C++; - * [ ] **shwild** dependency (testing only) - * [ ] . . . -* [ ] Doxygen; + * [x] ~~~`/MT` build option for Visual C++ (`--msvc-mt` / `MSVC_USE_MT`)~~~ - ✅; + * [x] ~~~**shwild** dependency (testing only; `--no-shwild` / `NO_SHWILD`)~~~ - ✅; +* [x] ~~~Doxygen (**Doxyfile**, **doc/mainpage.md**, **generate_doxygen.sh**)~~~ - ✅; * [x] ~~~Build scripts: remove project/copyright information and pick up from a project-specific file~~~ - ✅; * [ ] GitHub Actions: - * [x] macOS; - * [ ] Unix; - * [x] Windows; + * [x] ~~~macOS~~~ - ✅; + * [x] ~~~Unix (ubuntu)~~~ - ✅; + * [x] ~~~Windows~~~ - ✅; * [ ] Debug configuration; * [ ] Release configuration; + * [ ] exercise `--no-cpp` / `--no-shwild` permutations beyond the current jobs; * [-] ~~~Makefiles (legacy build trees removed; CMake-only)~~~ - ❌; * [ ] Packages: * [ ] vcpkg; From 2b7b3e5498a0bcfec80686f224fed726efb40ac2 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 15:05:02 +1000 Subject: [PATCH 34/35] chore: completed **CHANGES**.md and **NEWS.md** --- CHANGES.md | 9 +++++++++ NEWS.md | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 54c93d4..1d83894 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,15 @@ * Optional **shwild** recognition (`--no-shwild` / `NO_SHWILD`) for **xTests** pattern-match assertions; * Applied `XTESTS_TEST_MULTIBYTE_STRING_MATCHES` / `DOES_NOT_MATCH` in **cstring_getStatusCodeString** and **cstring.2** `test_createN` (when **shwild** is available); * Clarified dependencies documentation in **README.md**; +* Completed **README.md** Components descriptions (removed T.B.C.; added status/capacity helpers and **Vector API** section); +* Filled **INSTALL.md** (CMake and bundled use); +* Expanded **FAQ.md** (build, tests, `--no-cpp`, examples); +* Normalised **AUTHORS.md** and **KNOWN_ISSUES.md** layout; +* Added Doxygen packaging: **Doxyfile**, **doc/mainpage.md**, **generate_doxygen.sh** (and allowed tracking **doc/** in **.gitignore**); +* Fixed `\file` path in **cstring.vector.h** for Doxygen; +* Corrected version Doxygen comments in **cstring.h** (**BDUT** → **cstring**); +* CMake custom definitions: consume `_BUILD_AS_UNIX` / `_BUILD_AS_WIN32` in **src**, **examples**, and **test**; +* Refreshed **TODO.md**; ## 4.0.12 - 2nd September 2025 diff --git a/NEWS.md b/NEWS.md index d34c890..1888380 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ | Date | News Item | | --------------------- | ------------------------------------------------------------- | -| 2nd August 2026 | Release of [cstring 4.0.13](https://github.com/synesissoftware/cstring/releases/tag/4.0.13) | +| 2nd August 2026 | Release of [cstring 4.0.13](https://github.com/synesissoftware/cstring/releases/tag/4.0.13) (modular CI, examples, Doxygen, documentation) | | 2nd September 2025 | Release of [cstring 4.0.12](https://github.com/synesissoftware/cstring/releases/tag/4.0.12) | | 23rd February 2025 | Release of cstring 4.0.11 | | 25th October 2024 | Release of cstring 4.0.10 | From 6e732cb6406fc83da2ba5256961dc8b8e8944737 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 2 Aug 2026 15:07:56 +1000 Subject: [PATCH 35/35] chore: minor CMake consistency --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbed7ef..d5d1448 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,7 +302,7 @@ set(EXPORT_NAME ${PROJECT_NAME_LOWER}) configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${EXPORT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/${EXPORT_NAME}-config.cmake - INSTALL_DESTINATION ${LIB_INSTALL_DIR}/${EXPORT_NAME}/cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/${EXPORT_NAME}/cmake ) write_basic_package_version_file(