diff --git a/.github/workflows/ci-cell.yml b/.github/workflows/ci-cell.yml index 2b33a7c9..7b4d3b19 100644 --- a/.github/workflows/ci-cell.yml +++ b/.github/workflows/ci-cell.yml @@ -19,6 +19,10 @@ on: required: false type: string default: Release + with-ace: + required: false + type: boolean + default: false jobs: build: @@ -32,6 +36,10 @@ jobs: if: runner.os == 'Linux' && inputs.c-compiler == 'clang' run: sudo apt-get update && sudo apt-get install -y clang + - name: Install ACE (Ubuntu) + if: inputs.with-ace && runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libace-dev + - name: Setup MSYS2 MinGW if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' uses: msys2/setup-msys2@v2 @@ -61,7 +69,8 @@ jobs: -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ -DCMAKE_INSTALL_PREFIX="$DEPS" \ -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF + -DBUILD_TESTING=OFF \ + -DNO_ACE=ON cmake --build "$STLINSTALL" --config "${{ inputs.build-type }}" --parallel cmake --install "$STLINSTALL" --config "${{ inputs.build-type }}" elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then @@ -70,7 +79,8 @@ jobs: -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ -DCMAKE_INSTALL_PREFIX="$DEPS" \ -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF + -DBUILD_TESTING=OFF \ + -DNO_ACE=ON cmake --build "$STLINSTALL" --parallel 2 cmake --install "$STLINSTALL" else @@ -80,7 +90,8 @@ jobs: -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ -DCMAKE_INSTALL_PREFIX="$DEPS" \ -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF + -DBUILD_TESTING=OFF \ + -DNO_ACE=ON cmake --build "$STLINSTALL" --parallel cmake --install "$STLINSTALL" fi @@ -129,13 +140,19 @@ jobs: shell: bash run: | set -euo pipefail + if [ "${{ inputs.with-ace }}" = "true" ]; then + ACE_FLAG="-DNO_ACE=OFF" + else + ACE_FLAG="-DNO_ACE=ON" + fi 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 \ - -DNO_SHWILD=TRUE + -DNO_SHWILD=TRUE \ + $ACE_FLAG elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake -B build -G "MinGW Makefiles" \ @@ -145,7 +162,8 @@ jobs: -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ -DBUILD_EXAMPLES=ON \ -DBUILD_TESTING=ON \ - -DNO_SHWILD=TRUE + -DNO_SHWILD=TRUE \ + $ACE_FLAG else cmake -B build -S . \ -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ @@ -154,9 +172,30 @@ jobs: -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ -DBUILD_EXAMPLES=ON \ -DBUILD_TESTING=ON \ - -DNO_SHWILD=TRUE + -DNO_SHWILD=TRUE \ + $ACE_FLAG fi + - name: Verify ACE discovered + if: inputs.with-ace + shell: bash + run: | + set -euo pipefail + ACE_LIB="$(grep -E '^ACE_LIBRARY:(FILEPATH|PATH)=' build/CMakeCache.txt | head -1 | cut -d= -f2-)" + ACE_INC="$(grep -E '^ACE_INCLUDE_DIR:(FILEPATH|PATH)=' build/CMakeCache.txt | head -1 | cut -d= -f2-)" + if [ -z "${ACE_LIB}" ] || [[ "${ACE_LIB}" == *NOTFOUND* ]]; then + echo "with-ace requested but ACE_LIBRARY was not found:" >&2 + grep -i '^ACE_' build/CMakeCache.txt || true + exit 1 + fi + if [ -z "${ACE_INC}" ] || [[ "${ACE_INC}" == *NOTFOUND* ]]; then + echo "with-ace requested but ACE_INCLUDE_DIR was not found:" >&2 + grep -i '^ACE_' build/CMakeCache.txt || true + exit 1 + fi + echo "ACE_LIBRARY=${ACE_LIB}" + echo "ACE_INCLUDE_DIR=${ACE_INC}" + - name: Build shell: bash run: | @@ -185,6 +224,10 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install ACE (Ubuntu) + if: inputs.with-ace && runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libace-dev + - name: Setup MSYS2 MinGW if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' uses: msys2/setup-msys2@v2 @@ -199,6 +242,34 @@ jobs: name: sis-build-${{ inputs.cell-id }} path: build + - name: Restore executable bits + shell: bash + run: | + set -euo pipefail + find build -type f \ + \( \ + \( -path '*/examples/*' \ + ! -name '*.cmake' \ + ! -name 'CMakeLists.txt' \ + ! -name 'CTestTestfile.cmake' \ + ! -name 'Makefile' \ + ! -name 'cmake_install.cmake' \ + \) \ + -o -name 'test.unit.*' -o -name 'test_unit*' \ + -o -name 'test.component.*' -o -name 'test_component*' \ + -o -name 'test.scratch.*' -o -name 'test_scratch*' \ + -o -name 'test.performance.*' -o -name 'test_performance*' \ + \) \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + -exec chmod +x {} + + - name: Run examples shell: bash run: | @@ -216,6 +287,10 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install ACE (Ubuntu) + if: inputs.with-ace && runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libace-dev + - name: Setup MSYS2 MinGW if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' uses: msys2/setup-msys2@v2 @@ -230,6 +305,34 @@ jobs: name: sis-build-${{ inputs.cell-id }} path: build + - name: Restore executable bits + shell: bash + run: | + set -euo pipefail + find build -type f \ + \( \ + \( -path '*/examples/*' \ + ! -name '*.cmake' \ + ! -name 'CMakeLists.txt' \ + ! -name 'CTestTestfile.cmake' \ + ! -name 'Makefile' \ + ! -name 'cmake_install.cmake' \ + \) \ + -o -name 'test.unit.*' -o -name 'test_unit*' \ + -o -name 'test.component.*' -o -name 'test_component*' \ + -o -name 'test.scratch.*' -o -name 'test_scratch*' \ + -o -name 'test.performance.*' -o -name 'test_performance*' \ + \) \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + -exec chmod +x {} + + - name: Run unit tests shell: bash run: | @@ -247,6 +350,10 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install ACE (Ubuntu) + if: inputs.with-ace && runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libace-dev + - name: Setup MSYS2 MinGW if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' uses: msys2/setup-msys2@v2 @@ -261,6 +368,34 @@ jobs: name: sis-build-${{ inputs.cell-id }} path: build + - name: Restore executable bits + shell: bash + run: | + set -euo pipefail + find build -type f \ + \( \ + \( -path '*/examples/*' \ + ! -name '*.cmake' \ + ! -name 'CMakeLists.txt' \ + ! -name 'CTestTestfile.cmake' \ + ! -name 'Makefile' \ + ! -name 'cmake_install.cmake' \ + \) \ + -o -name 'test.unit.*' -o -name 'test_unit*' \ + -o -name 'test.component.*' -o -name 'test_component*' \ + -o -name 'test.scratch.*' -o -name 'test_scratch*' \ + -o -name 'test.performance.*' -o -name 'test_performance*' \ + \) \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + -exec chmod +x {} + + - name: Run component tests shell: bash run: | @@ -279,6 +414,10 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install ACE (Ubuntu) + if: inputs.with-ace && runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libace-dev + - name: Setup MSYS2 MinGW if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' uses: msys2/setup-msys2@v2 @@ -293,6 +432,34 @@ jobs: name: sis-build-${{ inputs.cell-id }} path: build + - name: Restore executable bits + shell: bash + run: | + set -euo pipefail + find build -type f \ + \( \ + \( -path '*/examples/*' \ + ! -name '*.cmake' \ + ! -name 'CMakeLists.txt' \ + ! -name 'CTestTestfile.cmake' \ + ! -name 'Makefile' \ + ! -name 'cmake_install.cmake' \ + \) \ + -o -name 'test.unit.*' -o -name 'test_unit*' \ + -o -name 'test.component.*' -o -name 'test_component*' \ + -o -name 'test.scratch.*' -o -name 'test_scratch*' \ + -o -name 'test.performance.*' -o -name 'test_performance*' \ + \) \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + -exec chmod +x {} + + - name: Run scratch tests shell: bash run: | @@ -311,6 +478,10 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install ACE (Ubuntu) + if: inputs.with-ace && runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y libace-dev + - name: Setup MSYS2 MinGW if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' uses: msys2/setup-msys2@v2 @@ -325,6 +496,34 @@ jobs: name: sis-build-${{ inputs.cell-id }} path: build + - name: Restore executable bits + shell: bash + run: | + set -euo pipefail + find build -type f \ + \( \ + \( -path '*/examples/*' \ + ! -name '*.cmake' \ + ! -name 'CMakeLists.txt' \ + ! -name 'CTestTestfile.cmake' \ + ! -name 'Makefile' \ + ! -name 'cmake_install.cmake' \ + \) \ + -o -name 'test.unit.*' -o -name 'test_unit*' \ + -o -name 'test.component.*' -o -name 'test_component*' \ + -o -name 'test.scratch.*' -o -name 'test_scratch*' \ + -o -name 'test.performance.*' -o -name 'test_performance*' \ + \) \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + -exec chmod +x {} + + - name: Run performance tests shell: bash run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7967e49d..86b76b3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,7 @@ on: - idiomatic - update.3 - update.4 + - ace - rc1 - rc2 - rc3 @@ -61,6 +62,27 @@ jobs: c-compiler: ${{ matrix.c_compiler }} cpp-compiler: ${{ matrix.cpp_compiler }} build-type: Release + with-ace: false + secrets: inherit + + cell-ace: + name: CI ACE (${{ matrix.id }}) + strategy: + fail-fast: false + matrix: + include: + - id: linux-gcc-ace + os: ubuntu-latest + c_compiler: gcc + 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 + with-ace: true secrets: inherit install-smoke: diff --git a/CMakeLists.txt b/CMakeLists.txt index 71e9f794..51ee7adf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,11 +140,35 @@ option(BUILD_TESTING "Build tests" ON) # - xTests - required for testing; # # optional: +# - ACE - enables ACESTL examples/tests when found (NO_ACE / --no-ace suppresses); # - cstring - facilitates some C tests; # - shwild - enhances xTests for testing; # - UNIXem - required for examples/testing on Windows if USE_UNIXEM and WIN32 are defined; +# ############################ +# ACE +# +# Discovery (when NO_ACE is not set): find_package(ACE) via cmake/FindACE.cmake +# (system packages such as libace-dev, or ACE / ACE_ROOT hints). + +set(HAS_ACE OFF) + +if(NOT NO_ACE) + + find_package(ACE QUIET) + + if(ACE_FOUND) + + set(HAS_ACE ON) + + add_compile_definitions(STLSOFT_HAS_ACE) + + message("-- ACE found") + endif() +endif() + + # ############################ # STLSoft # diff --git a/INSTALL.md b/INSTALL.md index 05a3e629..e4f3793d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -76,6 +76,8 @@ $ ./prepare_cmake.sh -m -v > > Use the `'--help'` flag for the full usage of this script. > +> To exercise **ACESTL**, install **ACE** (for example `libace-dev` on Ubuntu, or set **`ACE`** / **`ACE_ROOT`**) before configuring; pass **`--no-ace`** to **prepare_cmake.sh** to skip **ACE** discovery. +> > To build and exercise the **STLSoft** unit-tests and you are installing **STLSoft** _for the first time_, then you must do the following steps: > 1. Configure and install **STLSoft** _without_ tests, by specifying flags `-E` and `-T`; > 2. Configure, build, and install **xTests**; diff --git a/README.md b/README.md index 5a8d8319..fbc21a9e 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ If you'd like to help out with the project, please raise an issue via [GitHub Is | Dependency | Role | Required? | | ---------- | ---- | --------- | | — | Installation and use of **STLSoft** (100% header-only) | ✅ None | +| **ACE** | **ACESTL** examples / tests | ⚪ Optional (`NO_ACE` / **`--no-ace`**; `ACE` / `ACE_ROOT` or system package) | | [**xTests**](https://github.com/synesissoftware/xTests) | Component- / unit-tests (`BUILD_TESTING`) | ⚪ Tests only | diff --git a/TODO.md b/TODO.md index 4cc3f9a1..6b929679 100644 --- a/TODO.md +++ b/TODO.md @@ -28,7 +28,9 @@ ### 1.11.1 * [ ] Remove **WTL**; -* [ ] ACESTL: implement `invoke_ACE_OS_snprintf` in terms of `stlsoft_C_snprintf()`; +* [x] ~~~ACESTL: implement `invoke_ACE_OS_snprintf` in terms of `stlsoft_C_snprintf()`~~~ - ✅; +* [ ] CI: exercise **MFCSTL** on a Windows cell (drop / gate `CMAKE_DISABLE_FIND_PACKAGE_MFC`; confirm MSVC+MFC on the runner); +* [ ] Resolve finally the structure and semantics of the top-level execution scripts (**run_all_unit_tests.sh**, **run_all_scratch_tests.sh**, **run_all_examples.sh**, **execute_performance_tests.sh**, and Windows `.cmd` counterparts) on all platforms — discovery globs, execute-bit / artifact restore, zero-match failure, verbosity, and CI wiring; ### 1.11.2 diff --git a/cmake/FindACE.cmake b/cmake/FindACE.cmake new file mode 100644 index 00000000..4da2a042 --- /dev/null +++ b/cmake/FindACE.cmake @@ -0,0 +1,92 @@ +# FindACE.cmake +# +# Locates the ACE (Adaptive Communication Environment) headers and library. +# +# Sets: +# ACE_FOUND +# ACE_INCLUDE_DIRS +# ACE_LIBRARIES +# +# Provides imported target: +# ACE::ACE +# +# Optional hints (directory containing `ace/ACE.h`, or `include/ace/ACE.h`): +# CMake/env ACE or ACE_ROOT + + +set(_ACE_INCLUDE_HINTS) +set(_ACE_LIBRARY_HINTS) + +foreach(_ace_root IN ITEMS + "${ACE}" + "${ACE_ROOT}" + "$ENV{ACE}" + "$ENV{ACE_ROOT}" +) + + if(_ace_root) + + get_filename_component(_ace_root_abs "${_ace_root}" ABSOLUTE) + + list(APPEND _ACE_INCLUDE_HINTS + "${_ace_root_abs}" + "${_ace_root_abs}/include" + ) + list(APPEND _ACE_LIBRARY_HINTS + "${_ace_root_abs}" + "${_ace_root_abs}/lib" + "${_ace_root_abs}/ace" + ) + endif() +endforeach() + +find_path(ACE_INCLUDE_DIR + NAMES + ace/ACE.h + HINTS + ${_ACE_INCLUDE_HINTS} + DOC + "Directory containing ace/ACE.h" +) + +find_library(ACE_LIBRARY + NAMES + ACE + ace + HINTS + ${_ACE_LIBRARY_HINTS} + DOC + "ACE library" +) + +unset(_ACE_INCLUDE_HINTS) +unset(_ACE_LIBRARY_HINTS) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(ACE + REQUIRED_VARS + ACE_LIBRARY + ACE_INCLUDE_DIR +) + +if(ACE_FOUND) + + set(ACE_INCLUDE_DIRS "${ACE_INCLUDE_DIR}") + set(ACE_LIBRARIES "${ACE_LIBRARY}") + + if(NOT TARGET ACE::ACE) + + add_library(ACE::ACE UNKNOWN IMPORTED) + set_target_properties(ACE::ACE + PROPERTIES + IMPORTED_LOCATION "${ACE_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${ACE_INCLUDE_DIR}" + ) + endif() +endif() + +mark_as_advanced(ACE_INCLUDE_DIR ACE_LIBRARY) + + +# ############################## end of file ############################# # diff --git a/include/acestl/shims/access/string/time_value.hpp b/include/acestl/shims/access/string/time_value.hpp index e83b50ee..21495ad5 100644 --- a/include/acestl/shims/access/string/time_value.hpp +++ b/include/acestl/shims/access/string/time_value.hpp @@ -4,11 +4,11 @@ * Purpose: Helper functions for the ACE_Time_Value class. * * Created: 2nd December 2004 - * Updated: 20th March 2025 + * Updated: 7th August 2026 * * Home: http://stlsoft.org/ * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2004-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -54,8 +54,8 @@ #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION # define ACESTL_VER_ACESTL_SHIMS_ACCESS_STRING_HPP_TIME_VALUE_MAJOR 2 # define ACESTL_VER_ACESTL_SHIMS_ACCESS_STRING_HPP_TIME_VALUE_MINOR 0 -# define ACESTL_VER_ACESTL_SHIMS_ACCESS_STRING_HPP_TIME_VALUE_REVISION 10 -# define ACESTL_VER_ACESTL_SHIMS_ACCESS_STRING_HPP_TIME_VALUE_EDIT 54 +# define ACESTL_VER_ACESTL_SHIMS_ACCESS_STRING_HPP_TIME_VALUE_REVISION 12 +# define ACESTL_VER_ACESTL_SHIMS_ACCESS_STRING_HPP_TIME_VALUE_EDIT 56 #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ @@ -79,6 +79,9 @@ #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER # include #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */ +#ifndef STLSOFT_INCL_STLSOFT_UTIL_STRING_H_SNPRINTF +# include +#endif /* !STLSOFT_INCL_STLSOFT_UTIL_STRING_H_SNPRINTF */ #ifndef STLSOFT_INCL_ACE_H_TIME_VALUE # define STLSOFT_INCL_ACE_H_TIME_VALUE @@ -127,35 +130,34 @@ namespace acestl_project #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION namespace acestl_time_access_string_util { - template - void stream_insert(S& s, ACE_Time_Value const& t) + inline int invoke_ACE_OS_snprintf(ACE_TCHAR s2[], as_size_t size, ACE_TCHAR const* fmt, as_char_a_t const* s1, long ms) { - char s1[20]; - ACE_TCHAR s2[24]; - - long const s = t.sec(); - long const us = t.usec(); - struct tm* const tm = ACE_OS::localtime(&static_cast(s)); - as_size_t len = ACE_OS::strftime(s1, STLSOFT_NUM_ELEMENTS(s1), "%Y-%m-%d %H:%M:%S", tm); +# ifndef ACE_USES_WCHAR + return stlsoft_C_snprintf(s2, size, fmt, s1, ms); +# else /* ? ACE_USES_WCHAR */ + stlsoft::auto_buffer buff(1 + size); + int res; - ACESTL_ASSERT(len == 1 + STLSOFT_NUM_ELEMENTS(s1)); + s2[0] = '\0'; - len = ACE_OS::snprintf(s2, STLSOFT_NUM_ELEMENTS(s2), ACE_TEXT("%s.%03ld"), ACE_TEXT_CHAR_TO_TCHAR(s1), us / 1000); + res = stlsoft_C_snprintf(&buff[0], buff.size(), ACE_TEXT_ALWAYS_CHAR(fmt), s1, ms); - ACESTL_ASSERT(len == 1 + STLSOFT_NUM_ELEMENTS(s2)); + if (0 < res) + { + ACESTL_ASSERT(static_cast(res) < buff.size()); - s.write(&s2[0], len); - } + ::mbstowcs(s2, buff.data(), res); + s2[res] = '\0'; + } - inline int invoke_ACE_OS_snprintf(ACE_TCHAR s2[], as_size_t size, ACE_TCHAR const* fmt, as_char_a_t const* s1, long ms) - { - return ACE_OS::snprintf(s2, size, fmt, ACE_TEXT_CHAR_TO_TCHAR(s1), ms); + return res; +# endif /* ACE_USES_WCHAR */ } # ifdef ACE_USES_WCHAR inline int invoke_ACE_OS_snprintf(as_char_a_t s2[], as_size_t size, as_char_w_t const* fmt, as_char_a_t const* s1, long ms) { - return ACE_OS::snprintf(s2, size, ACE_TEXT_ALWAYS_CHAR(fmt), s1, ms); + return stlsoft_C_snprintf(s2, size, ACE_TEXT_ALWAYS_CHAR(fmt), s1, ms); } # else /* ? ACE_USES_WCHAR */ inline int invoke_ACE_OS_snprintf(as_char_w_t s2[], as_size_t size, as_char_a_t const* fmt, as_char_a_t const* s1, long ms) @@ -165,7 +167,7 @@ namespace acestl_time_access_string_util s2[0] = '\0'; - res = ACE_OS::snprintf(&buff[0], buff.size(), ACE_TEXT_ALWAYS_CHAR(fmt), s1, ms); + res = stlsoft_C_snprintf(&buff[0], buff.size(), ACE_TEXT_ALWAYS_CHAR(fmt), s1, ms); if (0 < res) { @@ -179,6 +181,26 @@ namespace acestl_time_access_string_util } # endif /* ACE_USES_WCHAR */ + template + void stream_insert(S& s, ACE_Time_Value const& t) + { + char s1[20]; + ACE_TCHAR s2[24]; + + long const secs = t.sec(); + long const us = t.usec(); + struct tm* const tm = ACE_OS::localtime(&static_cast(secs)); + as_size_t len = ACE_OS::strftime(s1, STLSOFT_NUM_ELEMENTS(s1), "%Y-%m-%d %H:%M:%S", tm); + + ACESTL_ASSERT(1 + len == STLSOFT_NUM_ELEMENTS(s1)); + + len = invoke_ACE_OS_snprintf(s2, STLSOFT_NUM_ELEMENTS(s2), ACE_TEXT("%s.%03ld"), s1, us / 1000); + + ACESTL_ASSERT(1 + len == STLSOFT_NUM_ELEMENTS(s2)); + + s.write(&s2[0], len); + } + template inline ::stlsoft::basic_shim_string diff --git a/prepare_cmake.sh b/prepare_cmake.sh index 48f32a74..b1f2da31 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -21,6 +21,7 @@ Configuration=Release ExamplesDisabled=0 MSVC_MT=0 MinGW="${MinGW:=0}" +NO_ACE=0 NO_cstring=0 NO_shwild=0 RunMake=0 @@ -59,6 +60,10 @@ while [[ $# -gt 0 ]]; do MSVC_MT=1 ;; + --no-ace) + + NO_ACE=1 + ;; --no-cstring) NO_cstring=1 @@ -117,6 +122,12 @@ Flags/options: selected; the default is the dynamic runtime library. Has no effect when not using Visual C++ + --no-ace + suppresses discovery of ACE (ACESTL examples/tests will not be built) + + --no-cstring + suppresses discovery of cstring package + --no-shwild suppresses discovery of shwild package @@ -165,6 +176,7 @@ echo "Executing CMake for ${ProjectName} (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_ACE -eq 0 ]; then CMakeNoACE="OFF" ; else CMakeNoACE="ON" ; fi if [ $NO_cstring -eq 0 ]; then CMakeNoCstring="OFF" ; else CMakeNoCstring="ON" ; fi if [ $NO_shwild -eq 0 ]; then CMakeNoShwild="OFF" ; else CMakeNoShwild="ON" ; fi if [ $TestingDisabled -eq 0 ]; then CMakeBuildTestingFlag="ON" ; else CMakeBuildTestingFlag="OFF" ; fi @@ -177,6 +189,7 @@ if [ $MinGW -ne 0 ]; then -DBUILD_EXAMPLES:BOOL=$CMakeBuildExamplesFlag \ -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ + -DNO_ACE:BOOL=$CMakeNoACE \ -DNO_CSTRING:BOOL=$CMakeNoCstring \ -DNO_SHWILD:BOOL=$CMakeNoShwild \ -DUSE_UNIXEM:BOOL=$CMakeUSE_UNIXem \ @@ -192,6 +205,7 @@ else -DCMAKE_BUILD_TYPE=$Configuration \ -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ + -DNO_ACE:BOOL=$CMakeNoACE \ -DNO_CSTRING:BOOL=$CMakeNoCstring \ -DNO_SHWILD:BOOL=$CMakeNoShwild \ -DUSE_UNIXEM:BOOL=$CMakeUSE_UNIXem \ diff --git a/run_all_examples.sh b/run_all_examples.sh index d03e7dab..09362e68 100755 --- a/run_all_examples.sh +++ b/run_all_examples.sh @@ -206,7 +206,36 @@ if [ $status -eq 0 ]; then echo "Running all ${ProjectName} example programs" fi - for f in $(find "$CMakeDir/examples" -type f -exec test -x {} \; -print | sort) + # Exclude CMake / build artefacts that can become +x after artifact restore. + ExamplePrograms=( $(find "$CMakeDir/examples" -type f \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.cmake' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + ! -name 'CMakeLists.txt' \ + ! -name 'CTestTestfile.cmake' \ + ! -name 'Makefile' \ + ! -name 'cmake_install.cmake' \ + -exec test -x {} \; -print | sort) ) + + echo "discovered ${#ExamplePrograms[@]} example program(s)" + + if [ ${#ExamplePrograms[@]} -eq 0 ]; then + + >&2 echo "$ScriptPath: no matching executable example programs under '$CMakeDir/examples' (execute bits missing after artifact download?)" + + if [ $ListOnly -eq 0 ]; then + + status=1 + fi + fi + + for f in "${ExamplePrograms[@]}" do if is_skipped_interactive_example "$f"; then diff --git a/run_all_unit_tests.sh b/run_all_unit_tests.sh index 937dcc27..0d7e147d 100755 --- a/run_all_unit_tests.sh +++ b/run_all_unit_tests.sh @@ -181,7 +181,32 @@ if [ $status -eq 0 ]; then 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 "${find_name_expr[@]}" -exec test -x {} \; -print | sort) + # Exclude build artefacts that can match suite name globs (CMake object + # files under CMakeFiles/, etc.). + TestPrograms=( $(find "$CMakeDir" -type f "${find_name_expr[@]}" \ + ! -path '*/CMakeFiles/*' \ + ! -name '*.a' \ + ! -name '*.d' \ + ! -name '*.lib' \ + ! -name '*.log' \ + ! -name '*.o' \ + ! -name '*.obj' \ + ! -name '*.pdb' \ + -exec test -x {} \; -print | sort) ) + + echo "discovered ${#TestPrograms[@]} ${TestKindDescription} program(s)" + + if [ ${#TestPrograms[@]} -eq 0 ]; then + + >&2 echo "$ScriptPath: no matching executable ${TestKindDescription} programs under '$CMakeDir' (execute bits missing after artifact download?)" + + if [ $ListOnly -eq 0 ]; then + + status=1 + fi + fi + + for f in "${TestPrograms[@]}" do if [ $ListOnly -ne 0 ]; then diff --git a/test/scratch/versions/versions.iostreams/CMakeLists.txt b/test/scratch/versions/versions.iostreams/CMakeLists.txt index 8c336873..ae5ff223 100644 --- a/test/scratch/versions/versions.iostreams/CMakeLists.txt +++ b/test/scratch/versions/versions.iostreams/CMakeLists.txt @@ -1 +1,8 @@ define_example_program(test.scratch.versions.iostreams versions.cpp) + +if(HAS_ACE) + + target_link_libraries(test.scratch.versions.iostreams + ACE::ACE + ) +endif() diff --git a/test/scratch/versions/versions.iostreams/versions.cpp b/test/scratch/versions/versions.iostreams/versions.cpp index 759d6ea8..377a7e0c 100644 --- a/test/scratch/versions/versions.iostreams/versions.cpp +++ b/test/scratch/versions/versions.iostreams/versions.cpp @@ -9,6 +9,9 @@ # include # include #endif +#ifdef STLSOFT_HAS_ACE +# include +#endif #include #include @@ -57,6 +60,33 @@ int main(int /* argc */, char* /* argv */[]) std::cout << std::endl; } + #ifdef STLSOFT_HAS_ACE + + + // _ACESTL_VER + + { + std::cout + << "ACESTL = " + << ((_ACESTL_VER >> 24) & 0xff) + << "." + << ((_ACESTL_VER >> 16) & 0xff) + << "." + << ((_ACESTL_VER >> 8) & 0xff) + << "." + << ((_ACESTL_VER >> 0) & 0xff) + << std::endl + ; + std::cout + << "_ACESTL_VER = 0x" + << std::hex << std::setfill('0') << std::setw(8) << _ACESTL_VER + << std::dec + << std::endl + ; + + std::cout << std::endl; + } +#endif /* STLSOFT_HAS_ACE */ // _PLATFORMSTL_VER @@ -136,10 +166,6 @@ int main(int /* argc */, char* /* argv */[]) std::cout << std::endl; } #endif - - - - #if 0 #elif defined(PLATFORMSTL_OS_IS_UNIX) || \ defined(PLATFORMSTL_OS_IS_WINDOWS) diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index ab425b8d..efbe40c7 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,4 +1,8 @@ +if(HAS_ACE) + + add_subdirectory(acestl) +endif(HAS_ACE) if(_BUILD_AS_WIN32) add_subdirectory(comstl) diff --git a/test/unit/acestl/CMakeLists.txt b/test/unit/acestl/CMakeLists.txt new file mode 100644 index 00000000..a1bc6d7e --- /dev/null +++ b/test/unit/acestl/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(shims) + + +# ############################## end of file ############################# # diff --git a/test/unit/acestl/shims/CMakeLists.txt b/test/unit/acestl/shims/CMakeLists.txt new file mode 100644 index 00000000..f660029a --- /dev/null +++ b/test/unit/acestl/shims/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(access) + + +# ############################## end of file ############################# # diff --git a/test/unit/acestl/shims/access/CMakeLists.txt b/test/unit/acestl/shims/access/CMakeLists.txt new file mode 100644 index 00000000..c16d98e1 --- /dev/null +++ b/test/unit/acestl/shims/access/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(string) + + +# ############################## end of file ############################# # diff --git a/test/unit/acestl/shims/access/string/CMakeLists.txt b/test/unit/acestl/shims/access/string/CMakeLists.txt new file mode 100644 index 00000000..5418729f --- /dev/null +++ b/test/unit/acestl/shims/access/string/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(test.unit.acestl.shims.access.string.string_base) +add_subdirectory(test.unit.acestl.shims.access.string.time_value) + + +# ############################## end of file ############################# # diff --git a/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.string_base/CMakeLists.txt b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.string_base/CMakeLists.txt new file mode 100644 index 00000000..9816b5c1 --- /dev/null +++ b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.string_base/CMakeLists.txt @@ -0,0 +1,5 @@ +define_automated_test_program(test.unit.acestl.shims.access.string.string_base entry.cpp) + +target_link_libraries(test.unit.acestl.shims.access.string.string_base + ACE::ACE +) diff --git a/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.string_base/entry.cpp b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.string_base/entry.cpp new file mode 100644 index 00000000..48a8dd71 --- /dev/null +++ b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.string_base/entry.cpp @@ -0,0 +1,141 @@ +/* ///////////////////////////////////////////////////////////////////////// + * File: test.unit.acestl.shims.access.string.string_base/entry.cpp + * + * Purpose: Unit-tests for string-access-shims for `ACE_String_Base`. + * + * Created: 7th August 2026 + * Updated: 7th August 2026 + * + * ////////////////////////////////////////////////////////////////////// */ + + +#define STLSOFT_MINIMUM_SAS_INCLUDES + + +/* ///////////////////////////////////////////////////////////////////////// + * includes + */ + +/* ///////////////////////////////////// + * test component header file include(s) + */ + +#include + +/* ///////////////////////////////////// + * general includes + */ + +/* xTests header files */ +#include + +/* STLSoft header files */ +#include + +/* ACE header files */ +#include + +/* Standard C header files */ +#include +#include + + +/* ///////////////////////////////////////////////////////////////////////// + * forward declarations + */ + +namespace { + + static void TEST_calls_possible(); + static void TEST_empty_string(); + static void TEST_non_empty_string(); +} // anonymous namespace + + +/* ///////////////////////////////////////////////////////////////////////// + * main + */ + +int main(int argc, char* argv[]) +{ + int retCode = EXIT_SUCCESS; + int verbosity = 2; + + XTESTS_COMMANDLINE_PARSEVERBOSITY(argc, argv, &verbosity); + + if (XTESTS_START_RUNNER("test.unit.acestl.shims.access.string.string_base", verbosity)) + { + XTESTS_RUN_CASE(TEST_calls_possible); + XTESTS_RUN_CASE(TEST_empty_string); + XTESTS_RUN_CASE(TEST_non_empty_string); + + XTESTS_PRINT_RESULTS(); + + XTESTS_END_RUNNER_UPDATE_EXITCODE(&retCode); + } + + return retCode; +} + + +/* ///////////////////////////////////////////////////////////////////////// + * test function implementations + */ + +namespace { + +static void TEST_calls_possible() +{ + ACE_CString const s("acestl"); + + stlsoft::c_str_data_a(s); + stlsoft::c_str_data(s); + + stlsoft::c_str_len_a(s); + stlsoft::c_str_len(s); + + stlsoft::c_str_ptr_a(s); + stlsoft::c_str_ptr(s); + + stlsoft::c_str_ptr_null_a(s); + stlsoft::c_str_ptr_null(s); + + XTESTS_TEST_PASSED(); +} + +static void TEST_empty_string() +{ + ACE_CString const s; + + TEST_INT_EQ(0u, stlsoft::c_str_len_a(s)); + TEST_INT_EQ(0u, stlsoft::c_str_len(s)); + + TEST_PTR_EQ(NULL, stlsoft::c_str_ptr_null_a(s)); + TEST_PTR_EQ(NULL, stlsoft::c_str_ptr_null(s)); + + TEST_MS_EQ("", stlsoft::c_str_ptr_a(s)); + TEST_MS_EQ("", stlsoft::c_str_ptr(s)); +} + +static void TEST_non_empty_string() +{ + char const* const expected = "ACE STL"; + ACE_CString const s(expected); + + TEST_INT_EQ(::strlen(expected), stlsoft::c_str_len_a(s)); + TEST_INT_EQ(::strlen(expected), stlsoft::c_str_len(s)); + + TEST_MS_EQ(expected, stlsoft::c_str_ptr_a(s)); + TEST_MS_EQ(expected, stlsoft::c_str_ptr(s)); + + TEST_MS_EQ(expected, stlsoft::c_str_data_a(s)); + TEST_MS_EQ(expected, stlsoft::c_str_data(s)); + + TEST_PTR_NE(NULL, stlsoft::c_str_ptr_null_a(s)); + TEST_MS_EQ(expected, stlsoft::c_str_ptr_null_a(s)); +} + +} // anonymous namespace + + +/* ///////////////////////////// end of file //////////////////////////// */ diff --git a/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.time_value/CMakeLists.txt b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.time_value/CMakeLists.txt new file mode 100644 index 00000000..a3042fc2 --- /dev/null +++ b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.time_value/CMakeLists.txt @@ -0,0 +1,5 @@ +define_automated_test_program(test.unit.acestl.shims.access.string.time_value entry.cpp) + +target_link_libraries(test.unit.acestl.shims.access.string.time_value + ACE::ACE +) diff --git a/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.time_value/entry.cpp b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.time_value/entry.cpp new file mode 100644 index 00000000..9d38d457 --- /dev/null +++ b/test/unit/acestl/shims/access/string/test.unit.acestl.shims.access.string.time_value/entry.cpp @@ -0,0 +1,170 @@ +/* ///////////////////////////////////////////////////////////////////////// + * File: test.unit.acestl.shims.access.string.time_value/entry.cpp + * + * Purpose: Unit-tests for string-access-shims for `ACE_Time_Value`. + * + * Created: 7th August 2026 + * Updated: 7th August 2026 + * + * ////////////////////////////////////////////////////////////////////// */ + + +#define STLSOFT_MINIMUM_SAS_INCLUDES + + +/* ///////////////////////////////////////////////////////////////////////// + * includes + */ + +/* ///////////////////////////////////// + * test component header file include(s) + */ + +#include + +/* ///////////////////////////////////// + * general includes + */ + +/* xTests header files */ +#include + +/* STLSoft header files */ +#include + +/* Standard C header files */ +#include +#include +#include + + +/* ///////////////////////////////////////////////////////////////////////// + * forward declarations + */ + +namespace { + + static void TEST_calls_possible(); + static void TEST_c_str_len(); + static void TEST_c_str_ptr_format_and_milliseconds(); +} // anonymous namespace + + +/* ///////////////////////////////////////////////////////////////////////// + * main + */ + +int main(int argc, char* argv[]) +{ + int retCode = EXIT_SUCCESS; + int verbosity = 2; + + XTESTS_COMMANDLINE_PARSEVERBOSITY(argc, argv, &verbosity); + + if (XTESTS_START_RUNNER("test.unit.acestl.shims.access.string.time_value", verbosity)) + { + XTESTS_RUN_CASE(TEST_calls_possible); + XTESTS_RUN_CASE(TEST_c_str_len); + XTESTS_RUN_CASE(TEST_c_str_ptr_format_and_milliseconds); + + XTESTS_PRINT_RESULTS(); + + XTESTS_END_RUNNER_UPDATE_EXITCODE(&retCode); + } + + return retCode; +} + + +/* ///////////////////////////////////////////////////////////////////////// + * test function implementations + */ + +namespace { + +static void TEST_calls_possible() +{ + ACE_Time_Value const tv(1, 234567); + + stlsoft::c_str_data_a(tv); + stlsoft::c_str_data(tv); + + stlsoft::c_str_len_a(tv); + stlsoft::c_str_len(tv); + + stlsoft::c_str_ptr_a(tv); + stlsoft::c_str_ptr(tv); + + stlsoft::c_str_ptr_null_a(tv); + stlsoft::c_str_ptr_null(tv); + + XTESTS_TEST_PASSED(); +} + +static void TEST_c_str_len() +{ + ACE_Time_Value const tv(1, 234567); + + TEST_INT_EQ(23u, stlsoft::c_str_len_a(tv)); + TEST_INT_EQ(23u, stlsoft::c_str_len(tv)); +} + +static void TEST_c_str_ptr_format_and_milliseconds() +{ + /* Format is localtime("%Y-%m-%d %H:%M:%S") + ".%03ld" milliseconds + * (usec / 1000). Length is fixed at 23; avoid absolute wall-clock + * equality because localtime is timezone-dependent. + */ + long const sec = 1; + long const usec = 234567; + long const msec = usec / 1000; + + ACE_Time_Value const tv(sec, usec); + stlsoft::basic_shim_string const s = stlsoft::c_str_ptr_a(tv); + char const* const ptr = s.data(); + + TEST_INT_EQ(23u, s.size()); + TEST_INT_EQ(23, static_cast(::strlen(ptr))); + + int year = 0; + int month = 0; + int day = 0; + int hour = 0; + int minute = 0; + int second = 0; + int millis = -1; + + TEST_INT_EQ( + 7 + , ::sscanf( + ptr + , "%d-%d-%d %d:%d:%d.%d" + , &year + , &month + , &day + , &hour + , &minute + , &second + , &millis + ) + ); + + TEST_BOOLEAN_TRUE(year >= 1970); + TEST_BOOLEAN_TRUE(month >= 1 && month <= 12); + TEST_BOOLEAN_TRUE(day >= 1 && day <= 31); + TEST_BOOLEAN_TRUE(hour >= 0 && hour <= 23); + TEST_BOOLEAN_TRUE(minute >= 0 && minute <= 59); + TEST_BOOLEAN_TRUE(second >= 0 && second <= 60); + TEST_INT_EQ(msec, millis); + + char expected_suffix[8]; + + TEST_INT_EQ(4, ::snprintf(expected_suffix, sizeof(expected_suffix), ".%03ld", msec)); + + TEST_MS_EQ(expected_suffix, ptr + 19); +} + +} // anonymous namespace + + +/* ///////////////////////////// end of file //////////////////////////// */ diff --git a/test/unit/test.unit.versions/CMakeLists.txt b/test/unit/test.unit.versions/CMakeLists.txt index 0d887c37..9ee86a0b 100644 --- a/test/unit/test.unit.versions/CMakeLists.txt +++ b/test/unit/test.unit.versions/CMakeLists.txt @@ -1,2 +1,8 @@ -# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten define_automated_test_program(test.unit.versions entry.cpp) + +if(HAS_ACE) + + target_link_libraries(test.unit.versions + ACE::ACE + ) +endif() diff --git a/test/unit/test.unit.versions/entry.cpp b/test/unit/test.unit.versions/entry.cpp index 048bd9ed..fd615684 100644 --- a/test/unit/test.unit.versions/entry.cpp +++ b/test/unit/test.unit.versions/entry.cpp @@ -4,7 +4,7 @@ * Purpose: Unit-tests for versions * * Created: 23rd August 2025 - * Updated: 2nd August 2026 + * Updated: 7th August 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -28,6 +28,9 @@ # include # include #endif +#ifdef STLSOFT_HAS_ACE +# include +#endif #ifdef STLSOFT_HAS_MFC # include #endif @@ -53,6 +56,9 @@ namespace { static void TEST__STLSOFT_VER(); +#ifdef STLSOFT_HAS_ACE + static void TEST__ACESTL_VER(); +#endif static void TEST__PLATFORMSTL_VER(); #if 0 #elif defined(PLATFORMSTL_OS_IS_UNIX) @@ -83,6 +89,9 @@ int main(int argc, char **argv) if (XTESTS_START_RUNNER("test.unit.versions", verbosity)) { XTESTS_RUN_CASE(TEST__STLSOFT_VER); +#ifdef STLSOFT_HAS_ACE + XTESTS_RUN_CASE(TEST__ACESTL_VER); +#endif XTESTS_RUN_CASE(TEST__PLATFORMSTL_VER); #if 0 #elif defined(PLATFORMSTL_OS_IS_UNIX) @@ -116,6 +125,14 @@ static void TEST__STLSOFT_VER() { TEST_INT_EQ(_STLSOFT_VER_1_11_1_RC5, _STLSOFT_VER); } +#ifdef STLSOFT_HAS_ACE + +static void TEST__ACESTL_VER() +{ + TEST_INT_EQ(_ACESTL_VER_1_2_1, _ACESTL_VER); +} +#endif + static void TEST__PLATFORMSTL_VER() { TEST_INT_EQ(_PLATFORMSTL_VER_1_10_0_B01, _PLATFORMSTL_VER); @@ -128,7 +145,6 @@ static void TEST__UNIXSTL_VER() { TEST_INT_EQ(_UNIXSTL_VER_1_8_6_B06, _UNIXSTL_VER); } - #elif defined(PLATFORMSTL_OS_IS_WINDOWS) static void TEST__COMSTL_VER() @@ -141,8 +157,8 @@ static void TEST__WINSTL_VER() TEST_INT_EQ(_WINSTL_VER_1_13_0_B02, _WINSTL_VER); } #endif - #ifdef STLSOFT_HAS_MFC + static void TEST__MFCSTL_VER() { TEST_INT_EQ(_MFCSTL_VER_1_6_1, MFCSTL_VER);