Skip to content

1.11.4 - #87

Merged
synesissoftware merged 14 commits into
devfrom
1_11_4
Oct 29, 2026
Merged

synesissoftware merged 14 commits into
devfrom
1_11_4

Conversation

@synesissoftware

Copy link
Copy Markdown
Owner

No description provided.

@synesissoftware
synesissoftware requested a review from mwsis October 27, 2026 23:17
@synesissoftware synesissoftware self-assigned this Oct 27, 2026
Colour headings (magenta), names (blue), versions and VER values (green),
and macro names (cyan) in **test.scratch.versions.stdio**, matching
**test.scratch.versions.iostreams**, when **`--use-woad`** is set. Defer
**test.scratch.versions.format** to **1.11.6**.
…1) (#88)

* tidy

* test(stlsoft): cover extant multibyte and wide conversion call sites

Add unit tests for the components that still call `mbstowcs()` /
`wcstombs()` directly:
- `multibyte2wide` / `wide2multibyte`, wide `exception_string_creator`, and
  the `error_desc_w` fallback;
- `ACE_Time_Value` wide shims, writing the non-`ACE_USES_WCHAR` conversion
  at the start of the destination buffer;

* fix(stlsoft): stop the wide ACE overflow and the MSVC C4996 oracles

Write the non-`ACE_USES_WCHAR` `mbstowcs()` result at the start of the
destination, and call `mbstowcs_s()` / `wcstombs_s()` from the rejection
oracles when `STLSOFT_USING_SAFE_STR_FUNCTIONS` is set:
- **include/acestl/shims/access/string/time_value.hpp**;
- **test.unit.stlsoft.conversion.char_conversions**;
- **test.unit.stlsoft.util.exception_string_creator**;

* test(stlsoft): cover the std::type_info wide string shims

Add **test.unit.stlsoft.std.type_info**. Narrow shims are
`type_info::name()`, and the wide shims match an ASCII widening of that
name:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* test(stlsoft): cover the std::exception wide string shims

Add **test.unit.stlsoft.std.exception**. Narrow shims are
`exception::what()`, and the wide shims match an ASCII widening of that
message. An empty `what()` yields an empty wide string and a null
`c_str_ptr_null_w`:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;
…2: add four-argument `mbstowcs` and `wcstombs` wrappers) (#89)

* tidy

* test(stlsoft): cover extant multibyte and wide conversion call sites

Add unit tests for the components that still call `mbstowcs()` /
`wcstombs()` directly:
- `multibyte2wide` / `wide2multibyte`, wide `exception_string_creator`, and
  the `error_desc_w` fallback;
- `ACE_Time_Value` wide shims, writing the non-`ACE_USES_WCHAR` conversion
  at the start of the destination buffer;

* fix(stlsoft): stop the wide ACE overflow and the MSVC C4996 oracles

Write the non-`ACE_USES_WCHAR` `mbstowcs()` result at the start of the
destination, and call `mbstowcs_s()` / `wcstombs_s()` from the rejection
oracles when `STLSOFT_USING_SAFE_STR_FUNCTIONS` is set:
- **include/acestl/shims/access/string/time_value.hpp**;
- **test.unit.stlsoft.conversion.char_conversions**;
- **test.unit.stlsoft.util.exception_string_creator**;

* test(stlsoft): cover the std::type_info wide string shims

Add **test.unit.stlsoft.std.type_info**. Narrow shims are
`type_info::name()`, and the wide shims match an ASCII widening of that
name:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* test(stlsoft): cover the std::exception wide string shims

Add **test.unit.stlsoft.std.exception**. Narrow shims are
`exception::what()`, and the wide shims match an ASCII widening of that
message. An empty `what()` yields an empty wide string and a null
`c_str_ptr_null_w`:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* feat(stlsoft): add four-argument mbstowcs and wcstombs wrappers

Give `stlsoft_C_mbstowcs()` and `stlsoft_C_wcstombs()` a destination
capacity and a source limit, and hide `mbstowcs_s()` / `wcstombs_s()`
behind that contract. A null destination is the length probe, and the
returned count excludes the NUL. No call site uses them yet:
- **test.unit.stlsoft.string.encoding** covers ASCII, the length probe,
  exact fit, a counted source, zero capacity, a short buffer, and
  rejection;

* refactor(stlsoft): route two wide conversions through stlsoft_C_mbstowcs

The wide `error_desc` fallback and both wide `invoke_ACE_OS_snprintf()`
overloads call `stlsoft_C_mbstowcs()`. The destination capacity is the shim
length for `error_desc`, and one past the `snprintf` count for ACE. Those
ACE overloads still stamp the NUL at `[res]`:
- **include/stlsoft/error/error_desc.hpp**;
- **include/acestl/shims/access/string/time_value.hpp**;

* refactor(stlsoft): route multibyte2wide through the encoding functions

`multibyte2wide` and `wide2multibyte` call `stlsoft_C_mbstowcs()` and
`stlsoft_C_wcstombs()` with a destination of `size + 1` and a source limit
of `size`. Failure is still `(size_t)-1`, and the NUL is still stamped at
`[size]`:
- **include/stlsoft/conversion/char_conversions.hpp**;

* chore(stlsoft): bump revision on the encoding call-site headers

The wide `error_desc` and ACE time-value refactors incremented `_EDIT` and
left `_REVISION` unchanged. Both fields now move, and `Updated` is 29th
October 2026:
- **include/stlsoft/error/error_desc.hpp** revision 1 to 2, edit 54 to 55;
- **include/acestl/shims/access/string/time_value.hpp**
  revision 12 to 13, edit 58 to 59;

* refactor(stlsoft): route exception and type_info wide shims through stlsoft_C_mbstowcs

The wide shims for `std::exception` and `std::type_info` call
`stlsoft_C_mbstowcs()` for the length probe and the store. The private
`mbstowcs_()` and `mbstowcs_len()` helpers are removed:
- **include/stlsoft/shims/access/string/std/exception.hpp**;
- **include/stlsoft/shims/access/string/std/type_info.hpp**;

* refactor(stlsoft): route home and environment lookup through the encoding functions

`system_traits<wchar_t>::get_environment_variable()` and
`unixstl_C_get_home_directory_w()` call `stlsoft_C_wcstombs()` and
`stlsoft_C_mbstowcs()`. A short home-directory buffer still returns
`cchBuffer - 1`:
- **include/unixstl/system/system_traits.hpp**;
- **include/unixstl/system/directory_functions.h**;

* refactor(stlsoft): convert exception strings with stlsoft_C_wcstombs

`wide_to_multibyte_or_throw_()` calls `stlsoft_C_wcstombs()`. Failure is
still `(size_t)-1`, which throws `conversion_error` or returns 0. This was
the last call site outside the encoding headers:
- **include/stlsoft/util/exception_string_creator.hpp**;
…f()` (#91)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.
* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.
* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): declare deref_proxy copy constructors

Give each output-iterator deref_proxy an explicit copy constructor so
C++11 and C++14 no longer deprecate the implicit one when copy assignment
is deleted. FILE_iterator's constructor is now unguarded, matching the
others. Record the fix on the 1.11.4 line in CHANGES.md, NEWS.md, and
TODO.md:
- associative_eraser_iterator;
- c_str_inserter;
- cstring_concatenator_iterator;
- eraser_iterator;
- FILE_iterator;
- null_output_iterator;
- ostream_iterator;
- push_insert_iterator;
- string_concatenator_iterator;
- string_insert_iterator;
- unary_function_output_iterator_adaptor.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.
…application (#95)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): declare deref_proxy copy constructors

Give each output-iterator deref_proxy an explicit copy constructor so
C++11 and C++14 no longer deprecate the implicit one when copy assignment
is deleted. FILE_iterator's constructor is now unguarded, matching the
others. Record the fix on the 1.11.4 line in CHANGES.md, NEWS.md, and
TODO.md:
- associative_eraser_iterator;
- c_str_inserter;
- cstring_concatenator_iterator;
- eraser_iterator;
- FILE_iterator;
- null_output_iterator;
- ostream_iterator;
- push_insert_iterator;
- string_concatenator_iterator;
- string_insert_iterator;
- unary_function_output_iterator_adaptor.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* chore: moved **./dev/** => **./.dev/**

* chore: updated Ruby dependencies

* chore(.dev/bin/batch_compile_check): tidying

* fix(stlsoft): batch_compile_check exit status and failure attribution

Address the two trustworthiness defects identified in review of
.dev/bin/batch_compile_check:
- script now exits 1 when any compilation fails, instead of always exiting
  0 (previously unusable as a CI gate);
- failed compilations are recorded as (file, language, standard) triples
  and listed as FAIL: lines on stderr at end of run, regardless of --counts
  / verbose mode, so failures are attributable without a verbose re-run;

* chore(.dev/bin/batch_compile_check): adding valid C languages 20 and 23

* fix(stlsoft): batch_compile_check skip-state leak and platform guard

Fix two correctness defects and one quoting hazard in
.dev/bin/batch_compile_check identified in review:
- reset ShouldSkip/SkipCause at each language-version iteration, so a
  per-version FILE_EXCEPTED marker (e.g. C++98 on basic_string_view.hpp) no
  longer silently skips all later standards;
- apply UNIX_SKIP_SEQUENCES only when not on Windows, so
  STLSOFT:Windows:FILE_EXCEPTED markers are not honoured on Windows;
- quote the find -name pattern so it cannot be glob-expanded against the
  caller's working directory;

* fix(stlsoft): batch_compile_check eliminate file-system side effects

Address the artefact-pollution and dead-scratch-directory defects in
.dev/bin/batch_compile_check identified in review:
- compile with -fsyntax-only instead of -c, so no '-.o' object file is
  written into the caller's working directory (previously clobbered on
  repeated runs, collided between concurrent runs, and failed when the
  CWD was read-only), and no codegen cost is incurred;
- remove the created-but-never-used ScratchDir along with its
  mkdir/canonicalisation, so --help and --dry-run no longer mutate the
  tree; the script now has no file-system side effects;

* fix(stlsoft): batch_compile_check robustness, validation, warnings

Address the robustness batch of review findings in
.dev/bin/batch_compile_check:
- quote all array/pattern expansions and discover files via find -print0
  piped into while read -d '', eliminating word-splitting/globbing on
  paths, defines, and compiler names;
- fail fast on bad inputs: missing include directory, nonexistent
  -p subproject, absent C/C++ compiler (probed with command -v), and zero
  files found are now hard errors instead of silent exit 0;
- validate -l values against SUPPORTED_LANGUAGE_VERSIONS_Cxx with a clear
  error, so typos no longer produce every-file-fails runs;
- compile with -Wall -Wextra -pedantic and add -W / --werror to treat
  warnings as errors, documented in --help;
- reconcile counters: new NumCompilationsSkipped separates per-version
  compilation skips from per-file skips, and the --counts summary now
  states units (files vs compilation attempts) truthfully;

* feat(stlsoft): separate C and C++ language-version flags

Replace the single -l/--language-version flag in
.dev/bin/batch_compile_check with one flag per language, because a shared
list cannot name an independent C set and C++ set when version numbers
overlap:
- --c-language-version selects C standards (89 90 99 11 17 20 23) and
  replaces only the C default of 17;
- --cxx-language-version selects C++ standards (98 03 11 14 17 20 23) and
  replaces only the C++ default of 98 03 11 14 17 20;
- passing a version flag for a language excluded by -C or -C++ is an error,
  as is a version outside that language's supported list;

* fix(stlsoft): stable header order in batch_compile_check

Sort each subproject's find results with LC_ALL=C sort -z before the
compile loop in .dev/bin/batch_compile_check, so repeated runs list the
same header in the same place regardless of directory order or locale
collation;

* fix(stlsoft): share the Windows prelude and reject it off Windows

batch_compile_check now builds one prelude and feeds it to both the C and
C++ compilers, and refuses Windows-only subprojects before -v prints
anything:
- winstl is compiled after windows.h and ntsecapi.h, because
  LSA_UNICODE_STRING.hpp errors unless ntsecapi.h is already included;
- comstl and inetstl are compiled after windows.h on Windows; inetstl keeps
  its Unix compilations, with no Windows prelude;
- -p comstl and -p winstl off Windows exit 1, and that check runs before
  the -v configuration dump;

* chore(stlsoft): tidy batch_compile_check names and comments

Correct the housekeeping left in .dev/bin/batch_compile_check:
- name the script directory ScriptDir, and drop the unread Basename;
- point the file banner at .dev/bin/batch_compile_check;
- describe the defines pass as de-duplication, which is what it does;

* fix(stlsoft): reject a missing batch_compile_check option value

Treat an option value as missing when it is absent or when the next token
is another flag, for --c-compiler, --cxx-compiler, --c-language-version,
--cxx-language-version, and --subproject, so the error is
"missing argument" rather than a compiler, version, or subproject named
after that flag;

* fix(stlsoft): scan each header's skip markers once

Read the /* STLSOFT:… */ comments in a header once in
batch_compile_check and test them in the shell, instead of one grep per
sequence and per language version:
- common, Windows, and per-version FILE_DEPRECATED / FILE_EXCEPTED markers
  are matched as whole tokens, case-insensitively;
- a prose mention of the marker convention does not skip the file;

* fix(stlsoft): exit 130 when batch_compile_check is interrupted

Trap SIGINT with exit 130 in .dev/bin/batch_compile_check, so Ctrl-C
reports the interrupt instead of the status of whichever command had just
finished;

* feat(stlsoft): compile batch_compile_check headers in parallel

Add -j / --jobs to .dev/bin/batch_compile_check. The default remains 1,
which keeps today's live compiler output:
- a value above 1 runs that many compilations at once, in batches waited
  for in start order, so the FAIL list stays in header order;
- each failure's compiler output is kept with the header that produced it,
  and a missing, zero, or non-numeric --jobs is an error;

* docs(stlsoft): record batch_compile_check in 1.11.4

Record the syntax-only header sweep in the 29th October 2026 notes:
- **CHANGES.md** — separate C and C++ standards, `-j`, skip markers,
  Windows prelude, and the failing `FAIL:` status;
- **NEWS.md** — the same essence on the 1.11.4 Details cell;
- **TODO.md** — tick the 1.11.4 checklist item;
* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): declare deref_proxy copy constructors

Give each output-iterator deref_proxy an explicit copy constructor so
C++11 and C++14 no longer deprecate the implicit one when copy assignment
is deleted. FILE_iterator's constructor is now unguarded, matching the
others. Record the fix on the 1.11.4 line in CHANGES.md, NEWS.md, and
TODO.md:
- associative_eraser_iterator;
- c_str_inserter;
- cstring_concatenator_iterator;
- eraser_iterator;
- FILE_iterator;
- null_output_iterator;
- ostream_iterator;
- push_insert_iterator;
- string_concatenator_iterator;
- string_insert_iterator;
- unary_function_output_iterator_adaptor.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* chore: moved **./dev/** => **./.dev/**

* chore: updated Ruby dependencies

* chore(.dev/bin/batch_compile_check): tidying

* fix(stlsoft): batch_compile_check exit status and failure attribution

Address the two trustworthiness defects identified in review of
.dev/bin/batch_compile_check:
- script now exits 1 when any compilation fails, instead of always exiting
  0 (previously unusable as a CI gate);
- failed compilations are recorded as (file, language, standard) triples
  and listed as FAIL: lines on stderr at end of run, regardless of --counts
  / verbose mode, so failures are attributable without a verbose re-run;

* chore(.dev/bin/batch_compile_check): adding valid C languages 20 and 23

* fix(stlsoft): batch_compile_check skip-state leak and platform guard

Fix two correctness defects and one quoting hazard in
.dev/bin/batch_compile_check identified in review:
- reset ShouldSkip/SkipCause at each language-version iteration, so a
  per-version FILE_EXCEPTED marker (e.g. C++98 on basic_string_view.hpp) no
  longer silently skips all later standards;
- apply UNIX_SKIP_SEQUENCES only when not on Windows, so
  STLSOFT:Windows:FILE_EXCEPTED markers are not honoured on Windows;
- quote the find -name pattern so it cannot be glob-expanded against the
  caller's working directory;

* fix(stlsoft): batch_compile_check eliminate file-system side effects

Address the artefact-pollution and dead-scratch-directory defects in
.dev/bin/batch_compile_check identified in review:
- compile with -fsyntax-only instead of -c, so no '-.o' object file is
  written into the caller's working directory (previously clobbered on
  repeated runs, collided between concurrent runs, and failed when the
  CWD was read-only), and no codegen cost is incurred;
- remove the created-but-never-used ScratchDir along with its
  mkdir/canonicalisation, so --help and --dry-run no longer mutate the
  tree; the script now has no file-system side effects;

* fix(stlsoft): batch_compile_check robustness, validation, warnings

Address the robustness batch of review findings in
.dev/bin/batch_compile_check:
- quote all array/pattern expansions and discover files via find -print0
  piped into while read -d '', eliminating word-splitting/globbing on
  paths, defines, and compiler names;
- fail fast on bad inputs: missing include directory, nonexistent
  -p subproject, absent C/C++ compiler (probed with command -v), and zero
  files found are now hard errors instead of silent exit 0;
- validate -l values against SUPPORTED_LANGUAGE_VERSIONS_Cxx with a clear
  error, so typos no longer produce every-file-fails runs;
- compile with -Wall -Wextra -pedantic and add -W / --werror to treat
  warnings as errors, documented in --help;
- reconcile counters: new NumCompilationsSkipped separates per-version
  compilation skips from per-file skips, and the --counts summary now
  states units (files vs compilation attempts) truthfully;

* feat(stlsoft): separate C and C++ language-version flags

Replace the single -l/--language-version flag in
.dev/bin/batch_compile_check with one flag per language, because a shared
list cannot name an independent C set and C++ set when version numbers
overlap:
- --c-language-version selects C standards (89 90 99 11 17 20 23) and
  replaces only the C default of 17;
- --cxx-language-version selects C++ standards (98 03 11 14 17 20 23) and
  replaces only the C++ default of 98 03 11 14 17 20;
- passing a version flag for a language excluded by -C or -C++ is an error,
  as is a version outside that language's supported list;

* fix(stlsoft): stable header order in batch_compile_check

Sort each subproject's find results with LC_ALL=C sort -z before the
compile loop in .dev/bin/batch_compile_check, so repeated runs list the
same header in the same place regardless of directory order or locale
collation;

* fix(stlsoft): share the Windows prelude and reject it off Windows

batch_compile_check now builds one prelude and feeds it to both the C and
C++ compilers, and refuses Windows-only subprojects before -v prints
anything:
- winstl is compiled after windows.h and ntsecapi.h, because
  LSA_UNICODE_STRING.hpp errors unless ntsecapi.h is already included;
- comstl and inetstl are compiled after windows.h on Windows; inetstl keeps
  its Unix compilations, with no Windows prelude;
- -p comstl and -p winstl off Windows exit 1, and that check runs before
  the -v configuration dump;

* chore(stlsoft): tidy batch_compile_check names and comments

Correct the housekeeping left in .dev/bin/batch_compile_check:
- name the script directory ScriptDir, and drop the unread Basename;
- point the file banner at .dev/bin/batch_compile_check;
- describe the defines pass as de-duplication, which is what it does;

* fix(stlsoft): reject a missing batch_compile_check option value

Treat an option value as missing when it is absent or when the next token
is another flag, for --c-compiler, --cxx-compiler, --c-language-version,
--cxx-language-version, and --subproject, so the error is
"missing argument" rather than a compiler, version, or subproject named
after that flag;

* fix(stlsoft): scan each header's skip markers once

Read the /* STLSOFT:… */ comments in a header once in
batch_compile_check and test them in the shell, instead of one grep per
sequence and per language version:
- common, Windows, and per-version FILE_DEPRECATED / FILE_EXCEPTED markers
  are matched as whole tokens, case-insensitively;
- a prose mention of the marker convention does not skip the file;

* fix(stlsoft): exit 130 when batch_compile_check is interrupted

Trap SIGINT with exit 130 in .dev/bin/batch_compile_check, so Ctrl-C
reports the interrupt instead of the status of whichever command had just
finished;

* feat(stlsoft): compile batch_compile_check headers in parallel

Add -j / --jobs to .dev/bin/batch_compile_check. The default remains 1,
which keeps today's live compiler output:
- a value above 1 runs that many compilations at once, in batches waited
  for in start order, so the FAIL list stays in header order;
- each failure's compiler output is kept with the header that produced it,
  and a missing, zero, or non-numeric --jobs is an error;

* docs(stlsoft): record batch_compile_check in 1.11.4

Record the syntax-only header sweep in the 29th October 2026 notes:
- **CHANGES.md** — separate C and C++ standards, `-j`, skip markers,
  Windows prelude, and the failing `FAIL:` status;
- **NEWS.md** — the same essence on the 1.11.4 Details cell;
- **TODO.md** — tick the 1.11.4 checklist item;

* chore(.dev/bin/check_unit_test_names.rb): improved colour reporting

* feat(.dev/bin/check_unit_test_names.rb): add a mode for File: or runner checks

Add --mode (-m) with 'both', 'file', and 'runner'. The default remains
'both'. Reject a repeated or unrecognised mode.

* feat(.dev/bin/check_unit_test_names.rb): summarise mismatched label counts

Print how many files were seen and how many File: or START_RUNNER labels do
not match. A zero count is green; any other count is red.

* feat(.dev/bin/check_unit_test_names.rb): expect File: labels from the project root

Compare a File: label under test/, example/, or examples/ with the path
Recls derives from the project root, so a search of test/component still
expects test/component/.../entry.cpp.

* style(stlsoft): use project-root paths in test File: labels

Set each mismatched File: label under test/ to the path from the project
root. 126 translation units; no other lines changed.

* style(stlsoft): use project-root paths in example File: labels

Set each mismatched File: label under examples/ to the path from the
project root. 21 programs; no other lines changed.

* style(stlsoft): stamp Updated on the File: path edits

Set Updated: to 29th October 2026 on the test and example files whose File:
label was rewritten. One file already carried that date.

* CHANGES.md

* TODO.md

* feat(.dev/bin/check_unit_test_names.rb): check runner names against the test directory

Compare each XTESTS_START_RUNNER* argument in test/unit and test/component
entry.c / entry.cpp with that file's project-relative directory, '/'
replaced by '.'. __FILE__ is a pass. Directory components keep their own
'.' and '-'. Examples and main.* are not examined.

* ci(stlsoft): fail CI when test names do not match

Exit 1 from check_unit_test_names.rb when the File: mismatch count or the
START_RUNNER mismatch count is non-zero. Run that script once, on Ubuntu,
over examples and test; do not repeat it on each compiler cell.

* feat(.dev/bin/check_unit_test_names.rb): take the project root from an option

Add --project-root / -R so File: labels and runner names are measured from
the tree being scanned. The default remains the directory two levels above
this script.

* docs(stlsoft): record the test-name checker in 1.11.4

Record check_unit_test_names.rb, the project-relative File: labels, and the
single CI job in the existing 1.11.4 CHANGES, NEWS, and TODO entries. Set
Doxyfile PROJECT_NUMBER to 1.11.4. The version macro and INSTALL.md already
name 1.11.4.

* ci

* ci(stlsoft): quote the test-name step so CI can parse

The Check test names step name contained an unquoted "File:", which YAML
reads as a new key. GitHub rejected .github/workflows/ci.yml before any
job started.

* style(stlsoft): use project-root paths in the new unit File: labels

The six encoding-call-site unit tests still named the dotted directory.
check_unit_test_names.rb expects the path from the project root. Set
Updated to 29th October 2026 on the five headers that still said the
28th.
@synesissoftware
synesissoftware marked this pull request as ready for review October 29, 2026 05:40
@synesissoftware
synesissoftware merged commit 1dbb7a5 into dev Oct 29, 2026
138 checks passed
@synesissoftware
synesissoftware deleted the 1_11_4 branch October 29, 2026 06:23
synesissoftware added a commit that referenced this pull request Oct 29, 2026
* chore(comments): fixing commented version of `_UNIXSTL_VER_1_8_6*`

* squash-commit

* TODO.md

* 1.11.4

* fix

* test(stlsoft): colour test.scratch.versions.stdio with woad (#90)

Colour headings (magenta), names (blue), versions and VER values (green),
and macro names (cyan) in **test.scratch.versions.stdio**, matching
**test.scratch.versions.iostreams**, when **`--use-woad`** is set. Defer
**test.scratch.versions.format** to **1.11.6**.

* 1.11.4 : MBS <-> WCS correctness, refactoring, and performance (part 1) (#88)

* tidy

* test(stlsoft): cover extant multibyte and wide conversion call sites

Add unit tests for the components that still call `mbstowcs()` /
`wcstombs()` directly:
- `multibyte2wide` / `wide2multibyte`, wide `exception_string_creator`, and
  the `error_desc_w` fallback;
- `ACE_Time_Value` wide shims, writing the non-`ACE_USES_WCHAR` conversion
  at the start of the destination buffer;

* fix(stlsoft): stop the wide ACE overflow and the MSVC C4996 oracles

Write the non-`ACE_USES_WCHAR` `mbstowcs()` result at the start of the
destination, and call `mbstowcs_s()` / `wcstombs_s()` from the rejection
oracles when `STLSOFT_USING_SAFE_STR_FUNCTIONS` is set:
- **include/acestl/shims/access/string/time_value.hpp**;
- **test.unit.stlsoft.conversion.char_conversions**;
- **test.unit.stlsoft.util.exception_string_creator**;

* test(stlsoft): cover the std::type_info wide string shims

Add **test.unit.stlsoft.std.type_info**. Narrow shims are
`type_info::name()`, and the wide shims match an ASCII widening of that
name:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* test(stlsoft): cover the std::exception wide string shims

Add **test.unit.stlsoft.std.exception**. Narrow shims are
`exception::what()`, and the wide shims match an ASCII widening of that
message. An empty `what()` yields an empty wide string and a null
`c_str_ptr_null_w`:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* 1.11.4 : MBS <-> WCS correctness, refactoring, and performance (part 2: add four-argument `mbstowcs` and `wcstombs` wrappers) (#89)

* tidy

* test(stlsoft): cover extant multibyte and wide conversion call sites

Add unit tests for the components that still call `mbstowcs()` /
`wcstombs()` directly:
- `multibyte2wide` / `wide2multibyte`, wide `exception_string_creator`, and
  the `error_desc_w` fallback;
- `ACE_Time_Value` wide shims, writing the non-`ACE_USES_WCHAR` conversion
  at the start of the destination buffer;

* fix(stlsoft): stop the wide ACE overflow and the MSVC C4996 oracles

Write the non-`ACE_USES_WCHAR` `mbstowcs()` result at the start of the
destination, and call `mbstowcs_s()` / `wcstombs_s()` from the rejection
oracles when `STLSOFT_USING_SAFE_STR_FUNCTIONS` is set:
- **include/acestl/shims/access/string/time_value.hpp**;
- **test.unit.stlsoft.conversion.char_conversions**;
- **test.unit.stlsoft.util.exception_string_creator**;

* test(stlsoft): cover the std::type_info wide string shims

Add **test.unit.stlsoft.std.type_info**. Narrow shims are
`type_info::name()`, and the wide shims match an ASCII widening of that
name:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* test(stlsoft): cover the std::exception wide string shims

Add **test.unit.stlsoft.std.exception**. Narrow shims are
`exception::what()`, and the wide shims match an ASCII widening of that
message. An empty `what()` yields an empty wide string and a null
`c_str_ptr_null_w`:
- `c_str_data_w`, `c_str_len_w`, `c_str_ptr_w`, and `c_str_ptr_null_w`;

* feat(stlsoft): add four-argument mbstowcs and wcstombs wrappers

Give `stlsoft_C_mbstowcs()` and `stlsoft_C_wcstombs()` a destination
capacity and a source limit, and hide `mbstowcs_s()` / `wcstombs_s()`
behind that contract. A null destination is the length probe, and the
returned count excludes the NUL. No call site uses them yet:
- **test.unit.stlsoft.string.encoding** covers ASCII, the length probe,
  exact fit, a counted source, zero capacity, a short buffer, and
  rejection;

* refactor(stlsoft): route two wide conversions through stlsoft_C_mbstowcs

The wide `error_desc` fallback and both wide `invoke_ACE_OS_snprintf()`
overloads call `stlsoft_C_mbstowcs()`. The destination capacity is the shim
length for `error_desc`, and one past the `snprintf` count for ACE. Those
ACE overloads still stamp the NUL at `[res]`:
- **include/stlsoft/error/error_desc.hpp**;
- **include/acestl/shims/access/string/time_value.hpp**;

* refactor(stlsoft): route multibyte2wide through the encoding functions

`multibyte2wide` and `wide2multibyte` call `stlsoft_C_mbstowcs()` and
`stlsoft_C_wcstombs()` with a destination of `size + 1` and a source limit
of `size`. Failure is still `(size_t)-1`, and the NUL is still stamped at
`[size]`:
- **include/stlsoft/conversion/char_conversions.hpp**;

* chore(stlsoft): bump revision on the encoding call-site headers

The wide `error_desc` and ACE time-value refactors incremented `_EDIT` and
left `_REVISION` unchanged. Both fields now move, and `Updated` is 29th
October 2026:
- **include/stlsoft/error/error_desc.hpp** revision 1 to 2, edit 54 to 55;
- **include/acestl/shims/access/string/time_value.hpp**
  revision 12 to 13, edit 58 to 59;

* refactor(stlsoft): route exception and type_info wide shims through stlsoft_C_mbstowcs

The wide shims for `std::exception` and `std::type_info` call
`stlsoft_C_mbstowcs()` for the length probe and the store. The private
`mbstowcs_()` and `mbstowcs_len()` helpers are removed:
- **include/stlsoft/shims/access/string/std/exception.hpp**;
- **include/stlsoft/shims/access/string/std/type_info.hpp**;

* refactor(stlsoft): route home and environment lookup through the encoding functions

`system_traits<wchar_t>::get_environment_variable()` and
`unixstl_C_get_home_directory_w()` call `stlsoft_C_wcstombs()` and
`stlsoft_C_mbstowcs()`. A short home-directory buffer still returns
`cchBuffer - 1`:
- **include/unixstl/system/system_traits.hpp**;
- **include/unixstl/system/directory_functions.h**;

* refactor(stlsoft): convert exception strings with stlsoft_C_wcstombs

`wide_to_multibyte_or_throw_()` calls `stlsoft_C_wcstombs()`. Failure is
still `(size_t)-1`, which throws `conversion_error` or returns 0. This was
the last call site outside the encoding headers:
- **include/stlsoft/util/exception_string_creator.hpp**;

* 1.11.4 : `invalid_integral_range_policy` refactor away use of `sprintf()` (#91)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* 1.11.4: C++98 compatibility (#93)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* 1.11.4 : fix(stlsoft): declare deref_proxy copy constructors (#94)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): declare deref_proxy copy constructors

Give each output-iterator deref_proxy an explicit copy constructor so
C++11 and C++14 no longer deprecate the implicit one when copy assignment
is deleted. FILE_iterator's constructor is now unguarded, matching the
others. Record the fix on the 1.11.4 line in CHANGES.md, NEWS.md, and
TODO.md:
- associative_eraser_iterator;
- c_str_inserter;
- cstring_concatenator_iterator;
- eraser_iterator;
- FILE_iterator;
- null_output_iterator;
- ostream_iterator;
- push_insert_iterator;
- string_concatenator_iterator;
- string_insert_iterator;
- unary_function_output_iterator_adaptor.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* 1.11.4 : ** dev/bin/batch_compile_check** : fixes, improvements, and application (#95)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): declare deref_proxy copy constructors

Give each output-iterator deref_proxy an explicit copy constructor so
C++11 and C++14 no longer deprecate the implicit one when copy assignment
is deleted. FILE_iterator's constructor is now unguarded, matching the
others. Record the fix on the 1.11.4 line in CHANGES.md, NEWS.md, and
TODO.md:
- associative_eraser_iterator;
- c_str_inserter;
- cstring_concatenator_iterator;
- eraser_iterator;
- FILE_iterator;
- null_output_iterator;
- ostream_iterator;
- push_insert_iterator;
- string_concatenator_iterator;
- string_insert_iterator;
- unary_function_output_iterator_adaptor.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* chore: moved **./dev/** => **./.dev/**

* chore: updated Ruby dependencies

* chore(.dev/bin/batch_compile_check): tidying

* fix(stlsoft): batch_compile_check exit status and failure attribution

Address the two trustworthiness defects identified in review of
.dev/bin/batch_compile_check:
- script now exits 1 when any compilation fails, instead of always exiting
  0 (previously unusable as a CI gate);
- failed compilations are recorded as (file, language, standard) triples
  and listed as FAIL: lines on stderr at end of run, regardless of --counts
  / verbose mode, so failures are attributable without a verbose re-run;

* chore(.dev/bin/batch_compile_check): adding valid C languages 20 and 23

* fix(stlsoft): batch_compile_check skip-state leak and platform guard

Fix two correctness defects and one quoting hazard in
.dev/bin/batch_compile_check identified in review:
- reset ShouldSkip/SkipCause at each language-version iteration, so a
  per-version FILE_EXCEPTED marker (e.g. C++98 on basic_string_view.hpp) no
  longer silently skips all later standards;
- apply UNIX_SKIP_SEQUENCES only when not on Windows, so
  STLSOFT:Windows:FILE_EXCEPTED markers are not honoured on Windows;
- quote the find -name pattern so it cannot be glob-expanded against the
  caller's working directory;

* fix(stlsoft): batch_compile_check eliminate file-system side effects

Address the artefact-pollution and dead-scratch-directory defects in
.dev/bin/batch_compile_check identified in review:
- compile with -fsyntax-only instead of -c, so no '-.o' object file is
  written into the caller's working directory (previously clobbered on
  repeated runs, collided between concurrent runs, and failed when the
  CWD was read-only), and no codegen cost is incurred;
- remove the created-but-never-used ScratchDir along with its
  mkdir/canonicalisation, so --help and --dry-run no longer mutate the
  tree; the script now has no file-system side effects;

* fix(stlsoft): batch_compile_check robustness, validation, warnings

Address the robustness batch of review findings in
.dev/bin/batch_compile_check:
- quote all array/pattern expansions and discover files via find -print0
  piped into while read -d '', eliminating word-splitting/globbing on
  paths, defines, and compiler names;
- fail fast on bad inputs: missing include directory, nonexistent
  -p subproject, absent C/C++ compiler (probed with command -v), and zero
  files found are now hard errors instead of silent exit 0;
- validate -l values against SUPPORTED_LANGUAGE_VERSIONS_Cxx with a clear
  error, so typos no longer produce every-file-fails runs;
- compile with -Wall -Wextra -pedantic and add -W / --werror to treat
  warnings as errors, documented in --help;
- reconcile counters: new NumCompilationsSkipped separates per-version
  compilation skips from per-file skips, and the --counts summary now
  states units (files vs compilation attempts) truthfully;

* feat(stlsoft): separate C and C++ language-version flags

Replace the single -l/--language-version flag in
.dev/bin/batch_compile_check with one flag per language, because a shared
list cannot name an independent C set and C++ set when version numbers
overlap:
- --c-language-version selects C standards (89 90 99 11 17 20 23) and
  replaces only the C default of 17;
- --cxx-language-version selects C++ standards (98 03 11 14 17 20 23) and
  replaces only the C++ default of 98 03 11 14 17 20;
- passing a version flag for a language excluded by -C or -C++ is an error,
  as is a version outside that language's supported list;

* fix(stlsoft): stable header order in batch_compile_check

Sort each subproject's find results with LC_ALL=C sort -z before the
compile loop in .dev/bin/batch_compile_check, so repeated runs list the
same header in the same place regardless of directory order or locale
collation;

* fix(stlsoft): share the Windows prelude and reject it off Windows

batch_compile_check now builds one prelude and feeds it to both the C and
C++ compilers, and refuses Windows-only subprojects before -v prints
anything:
- winstl is compiled after windows.h and ntsecapi.h, because
  LSA_UNICODE_STRING.hpp errors unless ntsecapi.h is already included;
- comstl and inetstl are compiled after windows.h on Windows; inetstl keeps
  its Unix compilations, with no Windows prelude;
- -p comstl and -p winstl off Windows exit 1, and that check runs before
  the -v configuration dump;

* chore(stlsoft): tidy batch_compile_check names and comments

Correct the housekeeping left in .dev/bin/batch_compile_check:
- name the script directory ScriptDir, and drop the unread Basename;
- point the file banner at .dev/bin/batch_compile_check;
- describe the defines pass as de-duplication, which is what it does;

* fix(stlsoft): reject a missing batch_compile_check option value

Treat an option value as missing when it is absent or when the next token
is another flag, for --c-compiler, --cxx-compiler, --c-language-version,
--cxx-language-version, and --subproject, so the error is
"missing argument" rather than a compiler, version, or subproject named
after that flag;

* fix(stlsoft): scan each header's skip markers once

Read the /* STLSOFT:… */ comments in a header once in
batch_compile_check and test them in the shell, instead of one grep per
sequence and per language version:
- common, Windows, and per-version FILE_DEPRECATED / FILE_EXCEPTED markers
  are matched as whole tokens, case-insensitively;
- a prose mention of the marker convention does not skip the file;

* fix(stlsoft): exit 130 when batch_compile_check is interrupted

Trap SIGINT with exit 130 in .dev/bin/batch_compile_check, so Ctrl-C
reports the interrupt instead of the status of whichever command had just
finished;

* feat(stlsoft): compile batch_compile_check headers in parallel

Add -j / --jobs to .dev/bin/batch_compile_check. The default remains 1,
which keeps today's live compiler output:
- a value above 1 runs that many compilations at once, in batches waited
  for in start order, so the FAIL list stays in header order;
- each failure's compiler output is kept with the header that produced it,
  and a missing, zero, or non-numeric --jobs is an error;

* docs(stlsoft): record batch_compile_check in 1.11.4

Record the syntax-only header sweep in the 29th October 2026 notes:
- **CHANGES.md** — separate C and C++ standards, `-j`, skip markers,
  Windows prelude, and the failing `FAIL:` status;
- **NEWS.md** — the same essence on the 1.11.4 Details cell;
- **TODO.md** — tick the 1.11.4 checklist item;

* 1.11.4 : Check unit test names (#96)

* test(stlsoft): cover invalid_integral_range_policy messages

Add test.unit.rangelib.invalid_integral_range_policy so the exception text
from invalid_integral_range_policy, including the 32-bit and 64-bit
extremes, is fixed before ::sprintf is replaced.

* refactor(stlsoft): format integral-range errors with stlsoft_C_snprintf

Replace the six ::sprintf calls in invalid_integral_range_policy with
stlsoft_C_snprintf(), and add
test.unit.rangelib.invalid_integral_range_policy to lock the exception
text, including the 32-bit and 64-bit extremes. The unsigned 32-bit
overload now passes its s_format array.

* docs(STLSoft): note 1.11.4 string_concatenation_flags None

Record the attached 1.11.4 slice: string_concatenation_flags gained `None`
(0x0000), and INSTALL.md archive examples name STLSoft-1.11.4.

* fix(stlsoft): stop using deprecated printf_traits::format_a

Call decimal_format_a() from the 64-bit invalid_integral_range_policy
helpers so the new unit test builds with MSVC warnings-as-errors.

* fix(stlsoft): declare deref_proxy copy constructors

Give each output-iterator deref_proxy an explicit copy constructor so
C++11 and C++14 no longer deprecate the implicit one when copy assignment
is deleted. FILE_iterator's constructor is now unguarded, matching the
others. Record the fix on the 1.11.4 line in CHANGES.md, NEWS.md, and
TODO.md:
- associative_eraser_iterator;
- c_str_inserter;
- cstring_concatenator_iterator;
- eraser_iterator;
- FILE_iterator;
- null_output_iterator;
- ostream_iterator;
- push_insert_iterator;
- string_concatenator_iterator;
- string_insert_iterator;
- unary_function_output_iterator_adaptor.

* fix(stlsoft): avoid unreachable code after a throwing range policy

Record the caught out_of_range before asserting in
test.unit.rangelib.invalid_integral_range_policy, so MSVC does not treat
the following check as unreachable when the policy call does not return.

* chore: moved **./dev/** => **./.dev/**

* chore: updated Ruby dependencies

* chore(.dev/bin/batch_compile_check): tidying

* fix(stlsoft): batch_compile_check exit status and failure attribution

Address the two trustworthiness defects identified in review of
.dev/bin/batch_compile_check:
- script now exits 1 when any compilation fails, instead of always exiting
  0 (previously unusable as a CI gate);
- failed compilations are recorded as (file, language, standard) triples
  and listed as FAIL: lines on stderr at end of run, regardless of --counts
  / verbose mode, so failures are attributable without a verbose re-run;

* chore(.dev/bin/batch_compile_check): adding valid C languages 20 and 23

* fix(stlsoft): batch_compile_check skip-state leak and platform guard

Fix two correctness defects and one quoting hazard in
.dev/bin/batch_compile_check identified in review:
- reset ShouldSkip/SkipCause at each language-version iteration, so a
  per-version FILE_EXCEPTED marker (e.g. C++98 on basic_string_view.hpp) no
  longer silently skips all later standards;
- apply UNIX_SKIP_SEQUENCES only when not on Windows, so
  STLSOFT:Windows:FILE_EXCEPTED markers are not honoured on Windows;
- quote the find -name pattern so it cannot be glob-expanded against the
  caller's working directory;

* fix(stlsoft): batch_compile_check eliminate file-system side effects

Address the artefact-pollution and dead-scratch-directory defects in
.dev/bin/batch_compile_check identified in review:
- compile with -fsyntax-only instead of -c, so no '-.o' object file is
  written into the caller's working directory (previously clobbered on
  repeated runs, collided between concurrent runs, and failed when the
  CWD was read-only), and no codegen cost is incurred;
- remove the created-but-never-used ScratchDir along with its
  mkdir/canonicalisation, so --help and --dry-run no longer mutate the
  tree; the script now has no file-system side effects;

* fix(stlsoft): batch_compile_check robustness, validation, warnings

Address the robustness batch of review findings in
.dev/bin/batch_compile_check:
- quote all array/pattern expansions and discover files via find -print0
  piped into while read -d '', eliminating word-splitting/globbing on
  paths, defines, and compiler names;
- fail fast on bad inputs: missing include directory, nonexistent
  -p subproject, absent C/C++ compiler (probed with command -v), and zero
  files found are now hard errors instead of silent exit 0;
- validate -l values against SUPPORTED_LANGUAGE_VERSIONS_Cxx with a clear
  error, so typos no longer produce every-file-fails runs;
- compile with -Wall -Wextra -pedantic and add -W / --werror to treat
  warnings as errors, documented in --help;
- reconcile counters: new NumCompilationsSkipped separates per-version
  compilation skips from per-file skips, and the --counts summary now
  states units (files vs compilation attempts) truthfully;

* feat(stlsoft): separate C and C++ language-version flags

Replace the single -l/--language-version flag in
.dev/bin/batch_compile_check with one flag per language, because a shared
list cannot name an independent C set and C++ set when version numbers
overlap:
- --c-language-version selects C standards (89 90 99 11 17 20 23) and
  replaces only the C default of 17;
- --cxx-language-version selects C++ standards (98 03 11 14 17 20 23) and
  replaces only the C++ default of 98 03 11 14 17 20;
- passing a version flag for a language excluded by -C or -C++ is an error,
  as is a version outside that language's supported list;

* fix(stlsoft): stable header order in batch_compile_check

Sort each subproject's find results with LC_ALL=C sort -z before the
compile loop in .dev/bin/batch_compile_check, so repeated runs list the
same header in the same place regardless of directory order or locale
collation;

* fix(stlsoft): share the Windows prelude and reject it off Windows

batch_compile_check now builds one prelude and feeds it to both the C and
C++ compilers, and refuses Windows-only subprojects before -v prints
anything:
- winstl is compiled after windows.h and ntsecapi.h, because
  LSA_UNICODE_STRING.hpp errors unless ntsecapi.h is already included;
- comstl and inetstl are compiled after windows.h on Windows; inetstl keeps
  its Unix compilations, with no Windows prelude;
- -p comstl and -p winstl off Windows exit 1, and that check runs before
  the -v configuration dump;

* chore(stlsoft): tidy batch_compile_check names and comments

Correct the housekeeping left in .dev/bin/batch_compile_check:
- name the script directory ScriptDir, and drop the unread Basename;
- point the file banner at .dev/bin/batch_compile_check;
- describe the defines pass as de-duplication, which is what it does;

* fix(stlsoft): reject a missing batch_compile_check option value

Treat an option value as missing when it is absent or when the next token
is another flag, for --c-compiler, --cxx-compiler, --c-language-version,
--cxx-language-version, and --subproject, so the error is
"missing argument" rather than a compiler, version, or subproject named
after that flag;

* fix(stlsoft): scan each header's skip markers once

Read the /* STLSOFT:… */ comments in a header once in
batch_compile_check and test them in the shell, instead of one grep per
sequence and per language version:
- common, Windows, and per-version FILE_DEPRECATED / FILE_EXCEPTED markers
  are matched as whole tokens, case-insensitively;
- a prose mention of the marker convention does not skip the file;

* fix(stlsoft): exit 130 when batch_compile_check is interrupted

Trap SIGINT with exit 130 in .dev/bin/batch_compile_check, so Ctrl-C
reports the interrupt instead of the status of whichever command had just
finished;

* feat(stlsoft): compile batch_compile_check headers in parallel

Add -j / --jobs to .dev/bin/batch_compile_check. The default remains 1,
which keeps today's live compiler output:
- a value above 1 runs that many compilations at once, in batches waited
  for in start order, so the FAIL list stays in header order;
- each failure's compiler output is kept with the header that produced it,
  and a missing, zero, or non-numeric --jobs is an error;

* docs(stlsoft): record batch_compile_check in 1.11.4

Record the syntax-only header sweep in the 29th October 2026 notes:
- **CHANGES.md** — separate C and C++ standards, `-j`, skip markers,
  Windows prelude, and the failing `FAIL:` status;
- **NEWS.md** — the same essence on the 1.11.4 Details cell;
- **TODO.md** — tick the 1.11.4 checklist item;

* chore(.dev/bin/check_unit_test_names.rb): improved colour reporting

* feat(.dev/bin/check_unit_test_names.rb): add a mode for File: or runner checks

Add --mode (-m) with 'both', 'file', and 'runner'. The default remains
'both'. Reject a repeated or unrecognised mode.

* feat(.dev/bin/check_unit_test_names.rb): summarise mismatched label counts

Print how many files were seen and how many File: or START_RUNNER labels do
not match. A zero count is green; any other count is red.

* feat(.dev/bin/check_unit_test_names.rb): expect File: labels from the project root

Compare a File: label under test/, example/, or examples/ with the path
Recls derives from the project root, so a search of test/component still
expects test/component/.../entry.cpp.

* style(stlsoft): use project-root paths in test File: labels

Set each mismatched File: label under test/ to the path from the project
root. 126 translation units; no other lines changed.

* style(stlsoft): use project-root paths in example File: labels

Set each mismatched File: label under examples/ to the path from the
project root. 21 programs; no other lines changed.

* style(stlsoft): stamp Updated on the File: path edits

Set Updated: to 29th October 2026 on the test and example files whose File:
label was rewritten. One file already carried that date.

* CHANGES.md

* TODO.md

* feat(.dev/bin/check_unit_test_names.rb): check runner names against the test directory

Compare each XTESTS_START_RUNNER* argument in test/unit and test/component
entry.c / entry.cpp with that file's project-relative directory, '/'
replaced by '.'. __FILE__ is a pass. Directory components keep their own
'.' and '-'. Examples and main.* are not examined.

* ci(stlsoft): fail CI when test names do not match

Exit 1 from check_unit_test_names.rb when the File: mismatch count or the
START_RUNNER mismatch count is non-zero. Run that script once, on Ubuntu,
over examples and test; do not repeat it on each compiler cell.

* feat(.dev/bin/check_unit_test_names.rb): take the project root from an option

Add --project-root / -R so File: labels and runner names are measured from
the tree being scanned. The default remains the directory two levels above
this script.

* docs(stlsoft): record the test-name checker in 1.11.4

Record check_unit_test_names.rb, the project-relative File: labels, and the
single CI job in the existing 1.11.4 CHANGES, NEWS, and TODO entries. Set
Doxyfile PROJECT_NUMBER to 1.11.4. The version macro and INSTALL.md already
name 1.11.4.

* ci

* ci(stlsoft): quote the test-name step so CI can parse

The Check test names step name contained an unquoted "File:", which YAML
reads as a new key. GitHub rejected .github/workflows/ci.yml before any
job started.

* style(stlsoft): use project-root paths in the new unit File: labels

The six encoding-call-site unit tests still named the dotted directory.
check_unit_test_names.rb expects the path from the project root. Set
Updated to 29th October 2026 on the five headers that still said the
28th.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants