diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b409470 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,50 @@ +root = true + +# Language indent/EOL/charset overlap with .vscode/settings.json. +# Rulers, renderWhitespace, detectIndentation, mergeEditor, and +# language-server settings cannot be expressed here — they stay in +# settings.json. + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +# [bat] +[*.{bat,cmd}] +end_of_line = crlf +indent_size = 4 +indent_style = space + +# [c] +[*.{c,h}] +indent_size = 4 +indent_style = space + +# [cmake] +[{CMakeLists.txt,*.cmake}] +indent_size = 4 +indent_style = tab + +# [json] +[*.json] +indent_size = 2 +indent_style = space + +# [markdown] +[*.md] +indent_size = 2 +indent_style = space + +# [shellscript] +[*.{bash,sh,zsh}] +indent_size = 2 +indent_style = space + +# [yaml] +[*.{yaml,yml}] +indent_size = 2 +indent_style = space diff --git a/.gitattributes b/.gitattributes index e6605d1..1ad0590 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,17 +1,126 @@ +# .gitattributes — C / C++ (GitHub-hosted) +# +# Sources: GitHub Docs (line endings), git-scm gitattributes (diff=cpp), +# gitattributes/gitattributes C++.gitattributes + Common.gitattributes, +# github-linguist overrides. +# +# Linguist language-bar policy (Synesis): classify public C API headers as C +# and *.cmake as CMake scripts; keep helper scripts, IDE project files, and +# CMakeLists.txt config out of the advertised language mix. Prefer +# -linguist-detectable over linguist-detectable=false. + +# Default: detect text, normalize to LF in the repository +* text=auto + +# --- Source --- +*.c text diff=cpp +*.c++ text diff=cpp +*.cc text diff=cpp +*.cpp text diff=cpp +*.cxx text diff=cpp +*.h text diff=cpp +*.h++ text diff=cpp +*.hh text diff=cpp +*.hpp text diff=cpp +*.hxx text diff=cpp +*.inc text +*.inl text +*.ipp text +*.tcc text +*.tpp text + +# --- Build / config --- +*.am text +*.cmake text +*.m4 text +*.mak text +*.mk text +*akefile text +CMakeLists.txt text +configure text eol=lf +configure.ac text + +# --- Scripts --- +*.bash text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf +*.sh text eol=lf +*.zsh text eol=lf + +# --- Docs / meta --- +*.adoc text +*.markdown text diff=markdown +*.md text diff=markdown +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +LICENSE text +NEWS text +README text +TODO text +.gitattributes text +.gitignore text + +# --- Serialisation --- +*.json text +*.toml text +*.xml text +*.yaml text +*.yml text + +# --- Compiled / binary artefacts --- +*.a binary +*.dll binary +*.dylib binary +*.exe binary +*.gch binary +*.la binary +*.lai binary +*.lib binary +*.lo binary +*.o binary +*.obj binary +*.out binary +*.pch binary +*.slo binary +*.so binary + +# --- Archives / images (common) --- +*.gif binary +*.gz binary +*.ico binary +*.jpeg binary +*.jpg binary +*.png binary +*.tar binary +*.zip binary + +# --- GitHub Linguist --- +**/build/** linguist-generated +**/cmake-build-*/** linguist-generated + +# Classification (C-primary / C API with C++ tests; *.cmake as CMake scripts) *.c linguist-language=C *.cmake linguist-language=CMake -*.cmd linguist-detectable=false *.cpp linguist-language=C++ *.cxx linguist-language=C++ -*.dsp linguist-detectable=false -*.dsw linguist-detectable=false *.h linguist-language=C *.hpp linguist-language=C++ -*.html linguist-detectable=false *.hxx linguist-language=C++ -*.sh linguist-detectable=false -*.sln linguist-detectable=false -*.vcxproj linguist-detectable=false -*.vimrc linguist-detectable=false -CMakeLists.txt linguist-language=CMake -makefile linguist-detectable=false + +# Keep the bar on library languages (helpers / legacy IDE / docs / +# CMakeLists.txt config; leave *.cmake detectable as CMake) +*.cmd -linguist-detectable +*.dsp -linguist-detectable +*.dsw -linguist-detectable +*.html -linguist-detectable +*.sh -linguist-detectable +*.sln -linguist-detectable +*.vcxproj -linguist-detectable +*.vimrc -linguist-detectable +CMakeLists.txt -linguist-detectable +makefile -linguist-detectable diff --git a/.github/actions/install-sis-deps/action.yml b/.github/actions/install-sis-deps/action.yml new file mode 100644 index 0000000..73209b7 --- /dev/null +++ b/.github/actions/install-sis-deps/action.yml @@ -0,0 +1,109 @@ +name: Install Synesis dependencies +description: >- + Clones, builds, and installs the named Synesis Information Systems + dependencies into a single CMake prefix, and exports that prefix both as + the SIS_DEPS environment variable and as the `prefix` output. + +inputs: + build-type: + description: CMake build type, for single-configuration generators + required: false + default: Release + c-compiler: + description: C compiler name, or the selector `cl` + required: true + cpp-compiler: + description: C++ compiler name; unused for the `cl` selector + required: true + dependencies: + description: >- + Whitespace-separated synesissoftware repository names, in dependency + order. Each is configured against those already installed, so this + list is deliberately NOT in lexicographic order. + required: true + install-prefix: + description: Directory into which every dependency is installed + required: false + default: '' + toolchain: + description: >- + Toolchain selector, for a toolchain that is not implied by the compiler + names and needs its own generator; presently only `mingw`. Empty + otherwise, in which case the compiler names alone select the toolchain. + required: false + default: '' + +outputs: + prefix: + description: Directory into which every dependency was installed + value: ${{ steps.install.outputs.prefix }} + +runs: + using: composite + + steps: + - id: install + shell: bash + run: | + set -euo pipefail + + PREFIX="${{ inputs.install-prefix }}" + [ -n "$PREFIX" ] || PREFIX="${RUNNER_TEMP}/sis-deps" + + mkdir -p "$PREFIX" + + if [ "${{ inputs.toolchain }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + + for dep in ${{ inputs.dependencies }}; do + + echo "::group::Installing $dep" + + SRC="${RUNNER_TEMP}/${dep}-src" + BUILD="${RUNNER_TEMP}/${dep}-build" + + git clone --depth 1 "https://github.com/synesissoftware/${dep}" "$SRC" + + # NOTE: the generator and the build-type/compiler options are the + # *only* things that may differ between these paths; every other + # -D option is passed in all cases, so that no branch can silently + # ignore one. + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -S "$SRC" -B "$BUILD" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_PREFIX_PATH="$PREFIX" + cmake --build "$BUILD" --config "${{ inputs.build-type }}" --parallel + cmake --install "$BUILD" --config "${{ inputs.build-type }}" + elif [ "${{ inputs.toolchain }}" = "mingw" ]; then + cmake -S "$SRC" -B "$BUILD" -G "MinGW Makefiles" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_PREFIX_PATH="$PREFIX" + cmake --build "$BUILD" --parallel 2 + cmake --install "$BUILD" + else + cmake -S "$SRC" -B "$BUILD" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_PREFIX_PATH="$PREFIX" + cmake --build "$BUILD" --parallel + cmake --install "$BUILD" + fi + + echo "::endgroup::" + done + + echo "prefix=$PREFIX" >> "$GITHUB_OUTPUT" + echo "SIS_DEPS=$PREFIX" >> "$GITHUB_ENV" diff --git a/.github/workflows/ci-cell.yml b/.github/workflows/ci-cell.yml index 5331b72..0dddb1a 100644 --- a/.github/workflows/ci-cell.yml +++ b/.github/workflows/ci-cell.yml @@ -19,17 +19,29 @@ on: required: false type: string default: Release + toolchain: + required: false + type: string + default: '' + +permissions: + contents: read jobs: - build: - name: Build (${{ inputs.cell-id }}) + # One job per cell. Sequential steps keep each kind visible in the log + # without a second checkout, a second MinGW setup, or an artifact + # round-trip. Windows runs native .cmd runners: they do not build, so they + # do not take the shell -M/--no-make or -v flags. + build-and-test: + name: Build and test (${{ inputs.cell-id }}) runs-on: ${{ inputs.os }} steps: - uses: actions/checkout@v4 - name: Setup MSYS2 MinGW - if: inputs.c-compiler == 'mingw' + id: msys2 + if: inputs.toolchain == 'mingw' uses: msys2/setup-msys2@v2 with: msystem: MINGW64 @@ -40,86 +52,13 @@ jobs: mingw-w64-x86_64-make - name: Install test dependencies (STLSoft + shwild + xTests) - shell: bash - run: | - set -euxo pipefail - - DEPS="${RUNNER_TEMP}/sis-deps" - STLSRC="${RUNNER_TEMP}/stlsoft-src" - STLBUILD="${RUNNER_TEMP}/stlsoft-build" - SHWSRC="${RUNNER_TEMP}/shwild-src" - SHWBUILD="${RUNNER_TEMP}/shwild-build" - XTSRC="${RUNNER_TEMP}/xtests-src" - XTBUILD="${RUNNER_TEMP}/xtests-build" - - mkdir -p "$DEPS" - - # 1. STLSoft - git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$STLSRC" -B "$STLBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$STLBUILD" --config "${{ inputs.build-type }}" - else - export PATH="/mingw64/bin:$PATH" - cmake -S "$STLSRC" -B "$STLBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --parallel 2 - cmake --install "$STLBUILD" - fi - - # 2. shwild - git clone --depth 1 https://github.com/synesissoftware/shwild "$SHWSRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$SHWSRC" -B "$SHWBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$SHWBUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$SHWBUILD" --config "${{ inputs.build-type }}" - else - export PATH="/mingw64/bin:$PATH" - cmake -S "$SHWSRC" -B "$SHWBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$SHWBUILD" --parallel 2 - cmake --install "$SHWBUILD" - fi - - # 3. xTests - git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$XTSRC" -B "$XTBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$XTBUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$XTBUILD" --config "${{ inputs.build-type }}" - else - export PATH="/mingw64/bin:$PATH" - cmake -S "$XTSRC" -B "$XTBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$XTBUILD" --parallel 2 - cmake --install "$XTBUILD" - fi + uses: ./.github/actions/install-sis-deps + with: + build-type: ${{ inputs.build-type }} + c-compiler: ${{ inputs.c-compiler }} + cpp-compiler: ${{ inputs.cpp-compiler }} + dependencies: STLSoft shwild xTests + toolchain: ${{ inputs.toolchain }} - name: Configure shell: bash @@ -128,16 +67,24 @@ jobs: if [ "${{ inputs.c-compiler }}" = "cl" ]; then cmake -B build -S . \ -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=ON \ -DBUILD_TESTING=ON - else + elif [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" - cmake -B build -G "MinGW Makefiles" \ + cmake -B build -S . -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=ON + else + cmake -B build -S . \ -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_C_COMPILER=gcc \ - -DCMAKE_CXX_COMPILER=g++ \ - -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=ON \ -DBUILD_TESTING=ON fi @@ -148,142 +95,50 @@ jobs: set -euo pipefail if [ "${{ inputs.c-compiler }}" = "cl" ]; then cmake --build build --config "${{ inputs.build-type }}" --parallel - else + elif [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake --build build --parallel 2 + else + cmake --build build --parallel fi - - name: Upload build tree - uses: actions/upload-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build - retention-days: 1 - - run-examples: - name: Examples (${{ inputs.cell-id }}) - needs: build - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build - - name: Run examples - shell: bash + shell: cmd + env: + MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }} + SIS_CMAKE_BUILD_DIR: ${{ github.workspace }}\build run: | - set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - fi - SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_examples.sh -M - - test-unit: - name: Unit tests (${{ inputs.cell-id }}) - needs: build - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build + if /I "${{ inputs.toolchain }}"=="mingw" set "PATH=%MSYS2_LOCATION%\mingw64\bin;%PATH%" + call run_all_examples.cmd + if errorlevel 1 exit /b 1 - name: Run unit tests - shell: bash + shell: cmd + env: + MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }} + SIS_CMAKE_BUILD_DIR: ${{ github.workspace }}\build run: | - set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - fi - export SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" - # Prefer .cmd on Windows (MSVC/MinGW) for reliable .exe discovery — see sistools/realpath - cmd.exe //c "run_all_unit_tests.cmd -M -v --unit-only" - - test-component: - name: Component tests (${{ inputs.cell-id }}) - needs: build - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build + if /I "${{ inputs.toolchain }}"=="mingw" set "PATH=%MSYS2_LOCATION%\mingw64\bin;%PATH%" + call run_all_unit_tests.cmd + if errorlevel 1 exit /b 1 - name: Run component tests - shell: bash + shell: cmd + env: + MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }} + SIS_CMAKE_BUILD_DIR: ${{ github.workspace }}\build run: | - set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - fi - export SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" - cmd.exe //c "run_all_unit_tests.cmd -M -v --component-only" - - test-scratch: - name: Scratch tests (${{ inputs.cell-id }}) - needs: build - continue-on-error: true - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build + if /I "${{ inputs.toolchain }}"=="mingw" set "PATH=%MSYS2_LOCATION%\mingw64\bin;%PATH%" + call run_all_component_tests.cmd + if errorlevel 1 exit /b 1 - name: Run scratch tests - shell: bash + continue-on-error: true + shell: cmd + env: + MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }} + SIS_CMAKE_BUILD_DIR: ${{ github.workspace }}\build run: | - set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - fi - SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_scratch_tests.sh -M + if /I "${{ inputs.toolchain }}"=="mingw" set "PATH=%MSYS2_LOCATION%\mingw64\bin;%PATH%" + call run_all_scratch_tests.cmd + if errorlevel 1 exit /b 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8bbcf0e..ca1003e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,9 @@ on: - rc3 pull_request: +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true @@ -30,10 +33,13 @@ jobs: os: windows-latest c_compiler: cl cpp_compiler: cl + # `toolchain` carries what is not a compiler: MinGW needs its own + # generator and PATH, but the compilers it drives are gcc and g++ - id: windows-mingw os: windows-latest - c_compiler: mingw + c_compiler: gcc cpp_compiler: g++ + toolchain: mingw uses: ./.github/workflows/ci-cell.yml with: cell-id: ${{ matrix.id }} @@ -41,9 +47,10 @@ jobs: c-compiler: ${{ matrix.c_compiler }} cpp-compiler: ${{ matrix.cpp_compiler }} build-type: Release + toolchain: ${{ matrix.toolchain }} install-smoke: - name: Install smoke (${{ matrix.os }}, ${{ matrix.c_compiler }}) + name: Install smoke (${{ matrix.os }}, ${{ matrix.toolchain || matrix.c_compiler }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -53,14 +60,15 @@ jobs: c_compiler: cl cpp_compiler: cl - os: windows-latest - c_compiler: mingw + c_compiler: gcc cpp_compiler: g++ + toolchain: mingw steps: - uses: actions/checkout@v4 - name: Setup MSYS2 MinGW - if: matrix.c_compiler == 'mingw' + if: matrix.toolchain == 'mingw' uses: msys2/setup-msys2@v2 with: msystem: MINGW64 @@ -79,12 +87,12 @@ jobs: -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ -DBUILD_EXAMPLES=OFF \ -DBUILD_TESTING=OFF - else + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake -B build -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ - -DCMAKE_C_COMPILER=gcc \ - -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ -DBUILD_EXAMPLES=OFF \ -DBUILD_TESTING=OFF fi @@ -95,7 +103,7 @@ jobs: set -euo pipefail if [ "${{ matrix.c_compiler }}" = "cl" ]; then cmake --build build --config "${{ env.BUILD_TYPE }}" --parallel - else + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake --build build --parallel 2 fi @@ -108,7 +116,7 @@ jobs: echo "INSTALL_PREFIX=$PREFIX" >> "$GITHUB_ENV" if [ "${{ matrix.c_compiler }}" = "cl" ]; then cmake --install build --config "${{ env.BUILD_TYPE }}" --prefix "$PREFIX" - else + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake --install build --prefix "$PREFIX" fi @@ -142,7 +150,7 @@ jobs: -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" cmake --build consumer-build --config "${{ env.BUILD_TYPE }}" --parallel consumer-build/${{ env.BUILD_TYPE }}/consumer.exe - else + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake -S "$CONSUMER" -B consumer-build -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ diff --git a/.gitignore b/.gitignore index b94cc68..226c160 100644 --- a/.gitignore +++ b/.gitignore @@ -1,131 +1,95 @@ -# Synesis Information Systems .gitignore for C/C++ libraries +# Synesis Information Systems .gitignore for C / C++ libraries # directories (by name) -/.git-old/ -/.vs/ +bin/ +ideas/ +ipch/ +lib/ +scripts/internal/ +Win32/ +x64/ +.idea/ .svn/ +.vs/ -.classpath -/.idea/ -/__pycache__ -/node_modules +__pycache__/ -/_build/ +/_analyses/ /_build-ci/ +/_build/ /_internal/ -/_analyses/ - -/bin/ -/ipch/ -/lib/ -bin/ -ipch/ -lib/ -/doc/ /docs/ /dox/ -/dox /ideas/ -ideas/ +/include/xcontract/ +/include/xcover/ /included/ +/node_modules/ /releases/ /scratch/ -/temp/ - -/--include -/--src -/-include -/-src - -/examples/bin -/examples/c/bin -/examples/cpp/bin - -/examples/lib -/examples/c/lib -/examples/cpp/lib - -projects/util/vc10-generated/ - -perf_test/ - -scripts/internal/ - -/include/b64/ -/include/shwild/ -/include/xcontract/ -/include/xcover/ -/include/xtests/ -/src/b64/ -/src/shwild/ /src/xcontract/ /src/xcover/ -/src/xtests/ +/target/ +/temp/ + +/examples/bin/ +/examples/c/bin/ +/examples/c/lib/ +/examples/cpp/bin/ +/examples/cpp/lib/ +/examples/lib/ -Debug Multithreaded DLL/ Debug Multithreaded Dll/ -Debug Multithreaded pseudoUNIX/ +Debug Multithreaded DLL/ Debug Multithreaded pseudoUnix/ +Debug Multithreaded pseudoUNIX/ Debug Multithreaded/ Debug/ +DebugDll/ DebugDLL/ DebugDLLUNIX/ -DebugDll/ -DebugMTDLL/ +DebugMt/ DebugMTDll/ +DebugMTDLL/ DebugMTUnix/ -DebugMt/ DebugNox/ -DebugUNIX/ DebugUnix/ -Release Multithreaded DLL/ +DebugUNIX/ Release Multithreaded Dll/ -Release Multithreaded pseudoUNIX/ +Release Multithreaded DLL/ Release Multithreaded pseudoUnix/ +Release Multithreaded pseudoUNIX/ Release Multithreaded/ Release/ +ReleaseDll/ ReleaseDLL/ ReleaseDLLUNIX/ -ReleaseDll/ -ReleaseMTDLL/ +ReleaseMt/ ReleaseMTDll/ +ReleaseMTDLL/ ReleaseMTUnix/ -ReleaseMt/ ReleaseNox/ ReleaseUnix/ UDebug/ UDebugMt/ -URelease/ -UReleaseMt/ -Unicode Debug Multithreaded DLL/ Unicode Debug Multithreaded Dll/ +Unicode Debug Multithreaded DLL/ Unicode Debug Multithreaded/ Unicode Debug/ -Unicode Release Multithreaded DLL/ Unicode Release Multithreaded Dll/ +Unicode Release Multithreaded DLL/ Unicode Release Multithreaded/ Unicode Release/ - -Win32/ -x64/ +URelease/ +UReleaseMt/ # directories (by pattern) -/build/ar* -/build/bc5* -/build/como* -/build/cw* -/build/gcc3* -/build/gcc4* -/build/icl* -/build/vc5* -/build/*.zip - /include-*/ @@ -133,25 +97,31 @@ x64/ .DS_Store -list_changes.cmd -logging-bailout.txt -prepare.cmd -sh.exe.stackdump -tidydir.cmd -update_deps.cmd +.classpath +.env.development.local +.env.local +.env.production.local +.env.test.local +.ruby-version +.svnignore +.svnignore-at-root +.update_deps +build/CMakeCache.txt build/makefile.tmpl build/makefile.tools.xml build/shwild.tmplgen -build/CMakeCache.txt - -include/fastformat/internal/dos2unix.has.been.performed include/pantheios/internal/dos2unix.has.been.performed include/stlsoft/dos2unix.has.been.performed include/stlsoft/internal/dos2unix.has.been.performed - +list_changes.cmd +logging-bailout.txt +prepare.cmd +sh.exe.stackdump test/testpatterns.orj test/tests-plan.txt +tidydir.cmd +update_deps.cmd # files (by pattern) @@ -159,8 +129,6 @@ test/tests-plan.txt *~ *.*~ *.???_obj -*.VC.db -*.VC.opendb *.a *.app *.aps @@ -168,6 +136,7 @@ test/tests-plan.txt *.bak *.chm *.class +*.csproj*user *.d *.diff *.dll @@ -204,32 +173,42 @@ test/tests-plan.txt *.slo *.so *.suo -*.swp *.sw[ponm] +*.swp *.test *.tlog *.tmp *.unsuccessfulbuild -*.vcproj*.user -*.vcxproj*.user -*.csproj*user -*.vcproj*user -*.vcxproj*user +*.VC.db +*.VC.opendb *.xcuserstate *.zip -*.vc71.sln -*.vc8.sln -*.vc9.sln +/build/*.tmpl +/build/*.tmplgen +/build/*.tools.xml +/build/*.zip +/build/ar* +/build/bc5* +/build/como* +/build/cw* +/build/gcc3* +/build/gcc4* +/build/icl* +/build/vc5* RCa0* RCb0* -build/*.tmplgen -build/*.tmpl -build/*.tools.xml - npm-debug.log* yarn-debug.log* yarn-error.log* +*.vc71.sln +*.vc8.sln +*.vc9.sln +*.vcproj*.user +*.vcproj*user +*.vcxproj*.user +*.vcxproj*user + diff --git a/.vimrc b/.vimrc index 1bf33a0..cebe6af 100644 --- a/.vimrc +++ b/.vimrc @@ -42,29 +42,29 @@ autocmd BufWritePre * %s/\s\+$//e augroup sis_c_cxx autocmd! + " [bat] + autocmd FileType bat,dosbatch setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,76 " [c] / [cpp] autocmd FileType c,cpp setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,64,68,72,76 - " [rust] - autocmd FileType rs setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=76 - " [cmake] autocmd FileType cmake setlocal noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 - " [shellscript] - autocmd FileType sh,bash,zsh setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 colorcolumn=60,76 - - " [bat] - autocmd FileType bat,dosbatch setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,76 - - " [json] / [markdown] / [yaml] / [ruby] - autocmd FileType json,markdown,yaml,ruby setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 + " [json] / [markdown] / [ruby] / [yaml] + autocmd FileType json,markdown,ruby,yaml setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 " [python] autocmd FileType python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=60,76 + " [rust] + autocmd FileType rs setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 colorcolumn=76 + + " [shellscript] + autocmd FileType bash,sh,zsh setlocal expandtab tabstop=2 shiftwidth=2 softtabstop=2 colorcolumn=60,76 + " [toml] autocmd FileType toml setlocal noexpandtab tabstop=2 shiftwidth=2 softtabstop=2 + augroup END diff --git a/.vscode/settings.json b/.vscode/settings.json index 7e91279..6aa78f6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,8 +5,10 @@ "editor.tabSize": 4, }, "[c]": { + "editor.defaultFormatter": "ms-vscode.cpptools", + "editor.formatOnSave": true, "editor.insertSpaces": true, - "editor.rulers": [ 60, 64, 68, 72, 76 ], + "editor.rulers": [ 60, 64, 68, 72, 76, 120 ], "editor.tabSize": 4, }, "[cmake]": { @@ -14,8 +16,10 @@ "editor.tabSize": 4, }, "[cpp]": { + "editor.defaultFormatter": "ms-vscode.cpptools", + "editor.formatOnSave": true, "editor.insertSpaces": true, - "editor.rulers": [ 60, 64, 68, 72, 76 ], + "editor.rulers": [ 60, 64, 68, 72, 76, 120 ], "editor.tabSize": 4, }, "[json]": { @@ -34,6 +38,7 @@ }, "[ruby]": { "editor.insertSpaces": true, + "editor.rulers": [ 60, 76 ], "editor.tabSize": 2, }, "[shellscript]": { @@ -49,13 +54,28 @@ "editor.insertSpaces": true, "editor.tabSize": 2, }, + "C_Cpp.autocompleteAddParentheses": true, + "C_Cpp.clang_format_fallbackStyle": "none", + "C_Cpp.clang_format_style": "file", + "C_Cpp.default.cStandard": "c17", + "C_Cpp.default.cppStandard": "c++17", + "C_Cpp.enhancedColorization": "enabled", + "C_Cpp.errorSquiggles": "enabled", + "C_Cpp.formatting": "clangFormat", + "C_Cpp.intelliSenseEngine": "default", "cmake.configureOnOpen": false, + "debug.allowBreakpointsEverywhere": true, "editor.detectIndentation": false, "editor.insertSpaces": false, "editor.renderWhitespace": "all", "editor.rulers": [ 76 ], "editor.tabSize": 2, "files.associations": { + "*.gemspec": "ruby", + "*.mdoc": "troff", + "*.roff": "troff", + "Gemfile": "ruby", + "Rakefile": "ruby", "__bit_reference": "cpp", "__bits": "cpp", "__config": "cpp", @@ -76,13 +96,17 @@ "__tuple": "cpp", "__verbose_abort": "cpp", "algorithm": "cpp", + "api.h": "c", "array": "cpp", "atomic": "cpp", + "auto_buffer.h": "c", "bit": "cpp", "bitset": "cpp", "cctype": "cpp", "charconv": "cpp", "chrono": "cpp", + "clasp.h": "c", + "cli_helpers.h": "c", "clocale": "cpp", "cmath": "cpp", "compare": "cpp", @@ -109,6 +133,7 @@ "functional": "cpp", "implicit_link.h": "c", "initializer_list": "cpp", + "invoke.h": "c", "io.h": "c", "iomanip": "cpp", "ios": "cpp", @@ -119,36 +144,48 @@ "limits": "cpp", "list": "cpp", "locale": "cpp", + "main.h": "c", "map": "cpp", - "memory_resource": "cpp", "memory": "cpp", + "memory_resource": "cpp", "mutex": "cpp", + "net_helpers.h": "c", "new": "cpp", "numbers": "cpp", "numeric": "cpp", "optional": "cpp", "ostream": "cpp", + "path_functions.h": "c", + "print": "cpp", "queue": "cpp", "random": "cpp", "ranges": "cpp", "ratio": "cpp", + "rc.h": "c", + "recls.h": "c", + "result_codes_.h": "c", "semaphore": "cpp", "set": "cpp", "setenv.h": "c", "shwild.h": "c", + "sleep_functions.h": "c", "span": "cpp", "sstream": "cpp", "stack": "cpp", + "stdatomic.h": "c", + "stdbool.h": "c", "stdexcept": "cpp", "stdio.h": "c", + "stock.h": "c", "stop_token": "cpp", "streambuf": "cpp", - "string_view": "cpp", "string": "cpp", + "string_view": "cpp", "system_error": "cpp", "terse-api.h": "c", "text_encoding": "cpp", "thread": "cpp", + "trace.h": "c", "tuple": "cpp", "type_traits": "cpp", "typeinfo": "cpp", @@ -159,6 +196,7 @@ "utility": "cpp", "variant": "cpp", "vector": "cpp", + "williamscrc.h": "c", "xfacet": "cpp", "xhash": "cpp", "xiosbase": "cpp", @@ -180,4 +218,3 @@ "files.trimTrailingWhitespace": true, "git.mergeEditor": false, } - diff --git a/CHANGES.md b/CHANGES.md index f776316..74426bb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,14 +1,26 @@ # UNIXem - Changes -## 1.14.0-rc1 - 10th September 2026 +## 1.14.0-rc1 - 21st September 2026 * Canonicalised CMake exclusion variable from reserved `CMAKE_NO_SHWILD` to canonical `NO_SHWILD` in **CMakeLists.txt** and **prepare_cmake.sh**; * Added backwards-compatibility mapping with obsolete-variable warning for legacy `CMAKE_NO_SHWILD` in **CMakeLists.txt**; -* Updated `UNIXEM_VER_MINOR` to 14, `UNIXEM_VER_AB` to `0xC1`, wired `UNIXEM_VER` to `UNIXEM_VER_AB` directly, and provided legacy `UNIXEM_VER_ALPHABETA` and `UNIXEM_VER_REVISION` compatibility aliases in **include/unixem/unixem.h**; +* Updated `UNIXEM_VER_MINOR` to 14 and `UNIXEM_VER_ALPHABETA` to `0xC1`, computed `UNIXEM_VER` from `UNIXEM_VER_ALPHABETA`, and provided `UNIXEM_VER_AB` and `UNIXEM_VER_REVISION` compatibility aliases in **include/unixem/unixem.h**; * Added third **Details** column to **NEWS.md** table; * Updated installation instructions in **INSTALL.md**; * Documented `stpcpy`, `stpncpy`, `wcpcpy`, and `wcpncpy` in **README.md**; +* Applied **misc-dev-scripts** **0.6.0** editor/Git/`.sis` drop-in templates on **boilerplate**; +* Restored historical **.gitignore** patterns as a sorted union with **misc-dev-scripts** gold section layout; +* Synchronised **run_all_examples.sh**, **run_all_examples.cmd**, **run_all_scratch_tests.sh**, and **run_all_scratch_tests.cmd** with **misc-dev-scripts** gold (optional **.sis/ci_examples_allowed_to_fail.txt** and **.sis/ci_scratch_tests_allowed_to_fail.txt** lists); +* Corrected `INSTALL_DESTINATION` of the package configuration in **CMakeLists.txt** (formerly the undefined `LIB_INSTALL_DIR`) and removed a duplicate `BUILD_TESTING` option; +* Corrected the implicit-link suppression definition in **examples/CMakeLists.txt** (which carried the **cstring** name); +* Canonicalised the `SIS:AUTO_GENERATED` eyecatcher of stock **CMakeLists.txt** files, renamed the scratch-program sources to **main.c**, and shortened the scratch, unit, and component test directories (e.g. **test/scratch/dlfcn/**, **test/component/unistd/mkdtemp/**) while retaining the `test..*` executable names; +* Windows steps of **ci-cell.yml** now pass `SIS_CMAKE_BUILD_DIR` and the MSYS2 location via `env:`, and propagate the `.cmd` runners' exit status; +* Documented the `mmap()` return value in Doxygen as `\return` rather than as a `\retval` with a prose value; +* Documented **MinGW** selection (`--mingw`) and the native `.cmd` runners in **INSTALL.md**; +* Corrected completed-item form in **TODO.md**; +* Removed the empty (and therefore vacuously passing) `test_1_14()` to `test_1_19()` cases from **test.component.glob**; +* Added the blank line after the end-of-file marker of source files, wrapped over-length comments in scratch programs, and used the `char* argv[]` form of `main()` in the unit and component tests; ## 1.14.0-beta1 - 9th August 2026 diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a3a856..ac1b61b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # Purpose: Top-level CMake lists file for UNIXem # # Created: 10th July 2024 -# Updated: 10th September 2026 +# Updated: 9th October 2026 # # ######################################################################## # @@ -113,8 +113,6 @@ if(NOT WIN32) message(FATAL_ERROR "${PROJECT_NAME} targets Windows only") endif() -option(BUILD_TESTING "Build tests" ON) - # ###################################### # dependencies @@ -259,7 +257,7 @@ set(EXPORT_NAME ${PROJECT_NAME_LOWER}) configure_package_config_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${EXPORT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/cmake/${EXPORT_NAME}-config.cmake - INSTALL_DESTINATION ${LIB_INSTALL_DIR}/${EXPORT_NAME}/cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${EXPORT_NAME} ) write_basic_package_version_file( diff --git a/INSTALL.md b/INSTALL.md index ae11ca5..27af88c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -51,6 +51,11 @@ The primary choice for installation is by use of **CMake**. or **xTests**; otherwise, you will need those test-only dependencies to be discoverable by **CMake**. + **NOTE**: **CMake** selects the generator. To build with **MinGW** + rather than **MSVC**, provide the flag `--mingw`, which selects the + "MinGW Makefiles" generator (and is the only means by which **MinGW** is + selected). + 3. Run a build of the generated **CMake**-derived build files via the **build_cmake.sh** script, as in: @@ -68,6 +73,14 @@ The primary choice for installation is by use of **CMake**. $ ./run_all_unit_tests.sh ``` + From a native Windows command prompt, use **run_all_unit_tests.cmd** + (and, likewise, **run_all_component_tests.cmd**, + **run_all_examples.cmd**, and **run_all_scratch_tests.cmd**), as in: + + ```cmd + > run_all_unit_tests.cmd + ``` + 5. Install the library on the host, via `cmake`, as in: ```bash diff --git a/NEWS.md b/NEWS.md index 314b39b..eb3e2f1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,47 +1,47 @@ # UNIXem - News -| Date | News Item | Details | -| ------------------- | ---------------------- | ------- | -| 10th September 2026 | Release of [UNIXem 1.14.0-rc1](https://github.com/synesissoftware/UNIXem/releases/tag/1.14.0-rc1) | | -| 9th August 2026 | Release of [UNIXem 1.14.0-beta1](https://github.com/synesissoftware/UNIXem/releases/tag/1.14.0-beta1) | | -| 4th August 2026 | Release of [UNIXem 1.13.0-beta1](https://github.com/synesissoftware/UNIXem/releases/tag/1.13.0-beta1) | | -| 7th September 2025 | Release of [UNIXem 1.13.0-alpha1](https://github.com/synesissoftware/UNIXem/releases/tag/1.13.0-alpha1) | | -| 19th May 2025 | UNIXem 1.12.8 released | | -| 1st May 2025 | UNIXem 1.12.7 released | | -| 17th December 2020 | UNIXem 1.12.6 released | | -| 19th July 2020 | UNIXem 1.12.5 released | | -| 19th July 2020 | UNIXem 1.12.4 released | | -| 14th October 2019 | UNIXem 1.12.3 released | | -| 14th October 2019 | UNIXem 1.12.2 released | | -| 9th October 2019 | UNIXem 1.11.4 released | | -| 2nd January 2017 | UNIXem 1.11.2 released | | -| 7th October 2015 | UNIXem 1.11.1 released | | -| 25th September 2015 | UNIXem 1.10.2 released | | -| 30th July 2015 | UNIXem 1.10.1 released | | -| 16th June 2012 | UNIXem 1.9.3 released | | -| 4th February 2011 | UNIXem 1.9.2 released | | -| 13th August 2010 | UNIXem 1.9.1 released | | -| 13th August 2010 | UNIXem 1.8.5 released | | -| 4th April 2010 | UNIXem 1.8.4 released | | -| 6th February 2010 | UNIXem 1.8.3 released | | -| 13th May 2008 | UNIXem 1.8.2 released | | -| 22nd April 2008 | UNIXem 1.8.1 released | | -| 20th April 2008 | UNIXem 1.7.5 released | | -| 24th February 2008 | UNIXem 1.7.4 released | | -| 12th March 2007 | UNIXem 1.7.3 released | | -| 12th September 2006 | UNIXem 1.7.2 released | | -| 3rd September 2006 | UNIXem 1.7.1 released | | -| 12th August 2006 | UNIXem 1.5.2 released | | -| 21st September 2005 | UNIXem 1.5.1 released | | -| 19th June 2005 | UNIXem 1.5.3 released | | -| 23rd May 2005 | UNIXem 1.5.2 released | | -| 17th February 2005 | UNIXem 1.5.1 released | | -| 29th June 2004 | UNIXem 1.4 released | | -| 16th June 2004 | UNIXem 1.3 released | | -| 3rd January 2004 | UNIXem 1.2 released | | -| 2nd November 2003 | UNIXem 1.1 released | | -| 2nd February 2003 | UNIXem 1.0 released | | +| Date | News Item | Details | +| ------------------- | ------------------------- | ----------------------------------------------------------------- | +| 21st September 2026 | Release of [**UNIXem** 1.14.0-rc1](https://github.com/synesissoftware/UNIXem/releases/tag/1.14.0-rc1) | `NO_SHWILD`; computed `UNIXEM_VER`; **misc-dev-scripts** drop-ins | +| 9th August 2026 | Release of [**UNIXem** 1.14.0-beta1](https://github.com/synesissoftware/UNIXem/releases/tag/1.14.0-beta1) | `stpcpy()` | +| 4th August 2026 | Release of [**UNIXem** 1.13.0-beta1](https://github.com/synesissoftware/UNIXem/releases/tag/1.13.0-beta1) | modular CI; **CHANGES.md**; Windows-only CMake guard | +| 7th September 2025 | Release of [**UNIXem** 1.13.0-alpha1](https://github.com/synesissoftware/UNIXem/releases/tag/1.13.0-alpha1) | boilerplate canonicalisation begun | +| 19th May 2025 | UNIXem 1.12.8 released | `GLOB_NOSORT` order; **UNIXem.Util.FS**; **UNIXem.Util.Str** | +| 1st May 2025 | UNIXem 1.12.7 released | CMake and MinGW support; `usleep()` minimum sleep | +| 17th December 2020 | UNIXem 1.12.6 released | Visual Studio 2019 (16.8.2) compatibility | +| 19th July 2020 | UNIXem 1.12.5 released | Visual C++ 15 and 16 support | +| 19th July 2020 | UNIXem 1.12.4 released | makefile auto-generation refactor | +| 14th October 2019 | UNIXem 1.12.3 released | GCC 4.9 (MinGW) compatibility | +| 14th October 2019 | UNIXem 1.12.2 released | GCC 8.1 (MinGW) compatibility; implicit-link library names | +| 9th October 2019 | UNIXem 1.11.4 released | `setenv()` / `unsetenv()` fixes | +| 2nd January 2017 | UNIXem 1.11.2 released | library prefix naming fix; VC++ 10 files | +| 7th October 2015 | UNIXem 1.11.1 released | `mkdtemp()`; `mkstemp()`; VC++ 14 | +| 25th September 2015 | UNIXem 1.10.2 released | `unixem_gettimeofday()` fix | +| 30th July 2015 | UNIXem 1.10.1 released | `unixem_timegm()` / `timegm()`; VC++ 11 and 12 | +| 16th June 2012 | UNIXem 1.9.3 released | `GLOB_ONLYREG`; `glob()` preserves dots directories | +| 4th February 2011 | UNIXem 1.9.2 released | removed **sys/select.h**; Win32 error mappings | +| 13th August 2010 | UNIXem 1.9.1 released | `unixem_`-prefixed API via macros; 64-bit fixes | +| 13th August 2010 | UNIXem 1.8.5 released | `gettimeofday()` returns `int`; VC++ 10 implicit link | +| 4th April 2010 | UNIXem 1.8.4 released | implicit-link library name fix; VC++ 10 | +| 6th February 2010 | UNIXem 1.8.3 released | **unistd.h** / **winsock2.h** conflict; placeholder headers | +| 13th May 2008 | UNIXem 1.8.2 released | Win64 compatibility | +| 22nd April 2008 | UNIXem 1.8.1 released | `gethostname()`; `getpid()` | +| 20th April 2008 | UNIXem 1.7.5 released | versioned distribution root; VC++ 8 and 9 makefiles | +| 24th February 2008 | UNIXem 1.7.4 released | **safestr.h**; `gettimeofday()` system-time fix | +| 12th March 2007 | UNIXem 1.7.3 released | `gettimeofday()` system time; Secure Library compatibility | +| 12th September 2006 | UNIXem 1.7.2 released | | +| 3rd September 2006 | UNIXem 1.7.1 released | | +| 12th August 2006 | UNIXem 1.5.2 released | | +| 21st September 2005 | UNIXem 1.5.1 released | | +| 19th June 2005 | UNIXem 1.5.3 released | | +| 23rd May 2005 | UNIXem 1.5.2 released | | +| 17th February 2005 | UNIXem 1.5.1 released | | +| 29th June 2004 | UNIXem 1.4 released | | +| 16th June 2004 | UNIXem 1.3 released | | +| 3rd January 2004 | UNIXem 1.2 released | | +| 2nd November 2003 | UNIXem 1.1 released | | +| 2nd February 2003 | UNIXem 1.0 released | | diff --git a/TODO.md b/TODO.md index ca54e85..144fa61 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # UNIXem - TODO -Updated: 10th September 2026 +Updated: 9th October 2026 ## Functional improvements @@ -29,11 +29,11 @@ Updated: 10th September 2026 ## Packaging improvements -* [x] ~~~Badges~~~; -* [x] ~~~CMake~~~; -* [x] ~~~Standardise project boilerplate files (to .md)~~~; -* [x] ~~~Remove Visual Studio project/solution/workspace files~~~; -* [ ] ~~~Remove custom makefiles under **build/** (retained for now)~~~; +* [x] ~~~Badges~~~ - ✅; +* [x] ~~~CMake~~~ - ✅; +* [x] ~~~Standardise project boilerplate files (to .md)~~~ - ✅; +* [x] ~~~Remove Visual Studio project/solution/workspace files~~~ - ✅; +* [x] ~~~Remove custom makefiles under **build/**~~~ - ✅; * [ ] CMake optional dependencies all marked OFF in **CMakeLists.txt**; * [ ] Add example programs under **examples/**; * [ ] Add to Windows-capable package managers: diff --git a/build_cmake.sh b/build_cmake.sh index f39fca8..a675a9d 100755 --- a/build_cmake.sh +++ b/build_cmake.sh @@ -1,22 +1,119 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -[[ -n "$MSYSTEM" ]] && DefaultMakeCmd=mingw32-make.exe || DefaultMakeCmd=make -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} IgnoreRemainingFlagsAndOptions=0 +SisUseColours=0 Targets=() # ########################################################## -# functions +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { -function join_by { local IFS="$1"; shift; echo "$*"; } + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} # ########################################################## @@ -26,21 +123,16 @@ while [[ $# -gt 0 ]]; do if [ $IgnoreRemainingFlagsAndOptions -ne 0 ]; then - Targets+=($1) - + Targets+=("$1") shift - continue - else - - if [ ! ${1:0:1} = '-' ]; then - - Targets+=($1) + fi - shift + if [ "${1:0:1}" != '-' ]; then - continue - fi + Targets+=("$1") + shift + continue fi case $1 in @@ -48,18 +140,33 @@ while [[ $# -gt 0 ]]; do IgnoreRemainingFlagsAndOptions=1 ;; + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --help) [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF Executes CMake-generated artefacts to (re)build project -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + (no arguments) + builds all default targets + + ... + builds one or more specific targets + + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + standard flags: @@ -72,7 +179,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -85,41 +192,26 @@ done # ########################################################## # main() -if [ ! -d "$CMakeDir" ]; then +if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - >&2 echo "$ScriptPath: CMake build directory '$CMakeDir' not found so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" + >&2 echo "${ScriptPathClr}: CMake build directory '${CMakeDirClr}' not found or not configured; use script 'prepare_cmake.sh' first" exit 1 -else - - cd $CMakeDir - - if [ ! -f "$CMakeDir/Makefile" ]; then - - >&2 echo "$ScriptPath: CMake build directory '$CMakeDir' does not contain expected file 'Makefile', so a build cannot be performed. It is recommended that you remove all CMake artefacts using script 'remove_cmake_artefacts.sh' followed by regeneration via 'prepare_cmake.sh'" - - cd ->/dev/null - - exit 1 - else - - if [ -z "$Targets" ]; then - - echo "Executing build of ${ProjectName} (via command \`$MakeCmd\`)" - else - - echo "Executing build of ${ProjectName} (via command \`$MakeCmd\`) with specific target(s) $(join_by , "${Targets[@]}")" - fi +fi - $MakeCmd ${Targets[*]} - status=$? +if [ ${#Targets[@]} -eq 0 ]; then - cd ->/dev/null + echo "Executing build of ${ProjectNameClr} (via cmake --build)" + sis_cmake_build + status=$? +else - exit $status - fi + echo "Executing build of ${ProjectNameClr} (via cmake --build) with specific target(s): ${Targets[*]}" + sis_cmake_build "${Targets[@]}" + status=$? fi +exit $status -# ############################## end of file ############################# # +# ############################## end of file ############################# # diff --git a/clean_cmake.sh b/clean_cmake.sh index 5d14956..733afbd 100755 --- a/clean_cmake.sh +++ b/clean_cmake.sh @@ -1,13 +1,117 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -[[ -n "$MSYSTEM" ]] && DefaultMakeCmd=mingw32-make.exe || DefaultMakeCmd=make -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 + +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} +SisUseColours=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} # ########################################################## @@ -16,18 +120,27 @@ ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --help) [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF -Executes CMake-generated artefacts to clean project +Cleans CMake-generated build artefacts via cmake --build --target clean -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + standard flags: @@ -40,7 +153,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -53,35 +166,16 @@ done # ########################################################## # main() -if [ ! -d "$CMakeDir" ]; then +if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - >&2 echo "$ScriptPath: CMake build directory '$CMakeDir' not found so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" + >&2 echo "${ScriptPathClr}: CMake build directory '${CMakeDirClr}' not found or not configured; nothing to clean" exit 1 -else - - cd $CMakeDir - - if [ ! -f "$CMakeDir/Makefile" ]; then - - >&2 echo "$ScriptPath: CMake build directory '$CMakeDir' does not contain expected file 'Makefile', so a clean cannot be performed. It is recommended that you remove all CMake artefacts using script 'remove_cmake_artefacts.sh' followed by regeneration via 'prepare_cmake.sh'" - - cd ->/dev/null - - exit 1 - else - - echo "Cleaning build of ${ProjectName} (via command \`$MakeCmd clean\`)" - - $MakeCmd clean - status=$? - - cd ->/dev/null - - exit $status - fi fi +echo "Executing clean of ${ProjectNameClr} (via cmake --build --target clean)" +sis_cmake_build clean +exit $? -# ############################## end of file ############################# # +# ############################## end of file ############################# # diff --git a/ctest_cmake.sh b/ctest_cmake.sh index 517462e..4e09ee2 100755 --- a/ctest_cmake.sh +++ b/ctest_cmake.sh @@ -1,16 +1,119 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -[[ -n "$MSYSTEM" ]] && DefaultMakeCmd=mingw32-make.exe || DefaultMakeCmd=make -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 -CMakeVerbose= +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} +CTestVerbose= RunMake=1 +SisUseColours=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} # ########################################################## @@ -19,13 +122,17 @@ RunMake=1 while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --no-make|-M) RunMake=0 ;; --verbose|-V) - CMakeVerbose=--verbose + CTestVerbose=--verbose ;; --help) @@ -33,15 +140,20 @@ while [[ $# -gt 0 ]]; do cat << EOF Runs CMake's CTest test program(s) -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + -M --no-make - does not execute CMake and make before running tests + does not execute a build before running tests -V --verbose @@ -59,7 +171,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -76,29 +188,48 @@ status=0 if [ $RunMake -ne 0 ]; then - echo "Executing build of ${ProjectName} (via command \`$MakeCmd\`) and then running all component and unit test programs" + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build) and then running CTest" - mkdir -p $CMakeDir || exit 1 + mkdir -p "$CMakeDir" || exit 1 - cd $CMakeDir + if [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - $MakeCmd - status=$? + >&2 echo "${ScriptPathClr}: '${CMakeDirClr}' is not configured; use prepare_cmake.sh first" - cd ->/dev/null + exit 1 + fi + + sis_cmake_build + status=$? else - if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ] || [ ! -d "$CMakeDir/CMakeFiles" ]; then + if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - >&2 echo "$ScriptPath: cannot run in '--no-make' mode without a previous successful build step" + >&2 echo "${ScriptPathClr}: cannot run in '--no-make' mode without a previous successful configure/build" + + exit 1 fi fi if [ $status -eq 0 ]; then - echo "Running CMake tests" + echo + echo "Running ${ProjectNameClr} CMake tests" + + # Multi-config generators (e.g. Visual Studio) need -C ; + # mirror sis_cmake_build's CMAKE_CONFIGURATION_TYPES detection. + ctest_args=(--test-dir "$CMakeDir" --output-on-failure) + if [ -n "$CTestVerbose" ]; then + + ctest_args+=("$CTestVerbose") + fi + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then - ctest --test-dir $CMakeDir $CMakeVerbose + ctest_args+=(-C "${SIS_CMAKE_CONFIG:-Release}") + fi + + ctest "${ctest_args[@]}" status=$? fi @@ -106,4 +237,3 @@ exit $status # ############################## end of file ############################# # - diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 32eeb75..42c836e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -22,7 +22,7 @@ if(WIN32) endif() # suppress implicit-link file - add_definitions(-DCSTRING_INCL_CSTRING_H_IMPLICIT_LINK) + add_definitions(-DUNIXEM_INCL_UNIXEM_H_IMPLICIT_LINK) endif(WIN32) if((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914)) diff --git a/include/asm/atomic.h b/include/asm/atomic.h index ef9c4b8..7e46227 100644 --- a/include/asm/atomic.h +++ b/include/asm/atomic.h @@ -5,11 +5,11 @@ * Windows platform. * * Created: 21st November 2003 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2003-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -47,7 +47,7 @@ # define SYNSOFT_UNIXEM_VER_SYS_H_ATOMIC_MAJOR 3 # define SYNSOFT_UNIXEM_VER_SYS_H_ATOMIC_MINOR 0 # define SYNSOFT_UNIXEM_VER_SYS_H_ATOMIC_REVISION 1 -# define SYNSOFT_UNIXEM_VER_SYS_H_ATOMIC_EDIT 23 +# define SYNSOFT_UNIXEM_VER_SYS_H_ATOMIC_EDIT 24 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -110,3 +110,4 @@ extern "C" { #endif /* SYNSOFT_UNIXEM_INCL_SYS_H_ATOMIC */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/dirent.h b/include/dirent.h index af76437..e6517a7 100644 --- a/include/dirent.h +++ b/include/dirent.h @@ -5,11 +5,11 @@ * Windows platform. * * Created: 19th October 2002 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2002-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_H_DIRENT_MAJOR 4 # define SYNSOFT_UNIXEM_VER_H_DIRENT_MINOR 0 # define SYNSOFT_UNIXEM_VER_H_DIRENT_REVISION 1 -# define SYNSOFT_UNIXEM_VER_H_DIRENT_EDIT 39 +# define SYNSOFT_UNIXEM_VER_H_DIRENT_EDIT 40 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -221,3 +221,4 @@ struct dirent* readdir(DIR* dir); #endif /* SYNSOFT_UNIXEM_INCL_H_DIRENT */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/dlfcn.h b/include/dlfcn.h index 4037d18..7222d5a 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -5,11 +5,11 @@ * functions. * * Created: 1st January 2004 - * Updated: 18th May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * 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. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_H_DLFCN_MAJOR 3 # define SYNSOFT_UNIXEM_VER_H_DLFCN_MINOR 0 # define SYNSOFT_UNIXEM_VER_H_DLFCN_REVISION 1 -# define SYNSOFT_UNIXEM_VER_H_DLFCN_EDIT 23 +# define SYNSOFT_UNIXEM_VER_H_DLFCN_EDIT 24 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -186,3 +186,4 @@ char const* dlerror(void); #endif /* SYNSOFT_UNIXEM_INCL_H_DLFCN */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/glob.h b/include/glob.h index c29ae3d..2c62992 100644 --- a/include/glob.h +++ b/include/glob.h @@ -5,11 +5,11 @@ * Windows platform. * * Created: 13th November 2002 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2002-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_H_GLOB_MAJOR 3 # define SYNSOFT_UNIXEM_VER_H_GLOB_MINOR 0 # define SYNSOFT_UNIXEM_VER_H_GLOB_REVISION 4 -# define SYNSOFT_UNIXEM_VER_H_GLOB_EDIT 43 +# define SYNSOFT_UNIXEM_VER_H_GLOB_EDIT 44 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -190,3 +190,4 @@ void globfree(glob_t* pglob); #endif /* SYNSOFT_UNIXEM_INCL_H_GLOB */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/sys/mman.h b/include/sys/mman.h index a383c99..91bea8b 100644 --- a/include/sys/mman.h +++ b/include/sys/mman.h @@ -4,11 +4,11 @@ * Purpose: Declaration of the mmap() and munmap() API functions. * * Created: 18th December 2003 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2003-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_SYS_H_MMAP_MAJOR 3 # define SYNSOFT_UNIXEM_VER_SYS_H_MMAP_MINOR 0 # define SYNSOFT_UNIXEM_VER_SYS_H_MMAP_REVISION 1 -# define SYNSOFT_UNIXEM_VER_SYS_H_MMAP_EDIT 29 +# define SYNSOFT_UNIXEM_VER_SYS_H_MMAP_EDIT 30 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -121,8 +121,8 @@ extern "C" * anonymous map * \param offset The offset within the file to start the mapped region * - * \retval pointer to mapped region if successful - * \retval MAP_FAILED if failed + * \return A pointer to the mapped region if successful; otherwise + * \c MAP_FAILED * * \note The current implementation supports the following three modes: * 1. Read-only file; 2. Read-write file; 3. Anonymous Read-write block of @@ -200,3 +200,4 @@ int msync( #endif /* SYNSOFT_UNIXEM_INCL_SYS_H_MMAP */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/sys/resource.h b/include/sys/resource.h index cd3e2fd..a00cacd 100644 --- a/include/sys/resource.h +++ b/include/sys/resource.h @@ -5,11 +5,11 @@ * types for the Windows platform. * * Created: 9th June 2006 - * Updated: 28th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2006-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_SYS_H_RESOURCE_MAJOR 2 # define SYNSOFT_UNIXEM_VER_SYS_H_RESOURCE_MINOR 0 # define SYNSOFT_UNIXEM_VER_SYS_H_RESOURCE_REVISION 1 -# define SYNSOFT_UNIXEM_VER_SYS_H_RESOURCE_EDIT 12 +# define SYNSOFT_UNIXEM_VER_SYS_H_RESOURCE_EDIT 13 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -140,3 +140,4 @@ int getrusage( #endif /* SYNSOFT_UNIXEM_INCL_SYS_H_RESOURCE */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/sys/time.h b/include/sys/time.h index a3233b5..79688ee 100644 --- a/include/sys/time.h +++ b/include/sys/time.h @@ -5,11 +5,11 @@ * types for the Windows platform. * * Created: 8th December 2002 - * Updated: 18th May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2002-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_SYS_H_TIME_MAJOR 3 # define SYNSOFT_UNIXEM_VER_SYS_H_TIME_MINOR 0 # define SYNSOFT_UNIXEM_VER_SYS_H_TIME_REVISION 1 -# define SYNSOFT_UNIXEM_VER_SYS_H_TIME_EDIT 30 +# define SYNSOFT_UNIXEM_VER_SYS_H_TIME_EDIT 31 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -138,3 +138,4 @@ int gettimeofday( #endif /* SYNSOFT_UNIXEM_INCL_SYS_H_TIME */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/sys/uio.h b/include/sys/uio.h index 291e9cf..4c2f5fe 100644 --- a/include/sys/uio.h +++ b/include/sys/uio.h @@ -4,11 +4,11 @@ * Purpose: Vector file read/write. * * Created: 19th September 2005 - * Updated: 28th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2005-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -51,7 +51,7 @@ # define SYNSOFT_UNIXEM_VER_SYS_H_UIO_MAJOR 2 # define SYNSOFT_UNIXEM_VER_SYS_H_UIO_MINOR 0 # define SYNSOFT_UNIXEM_VER_SYS_H_UIO_REVISION 1 -# define SYNSOFT_UNIXEM_VER_SYS_H_UIO_EDIT 15 +# define SYNSOFT_UNIXEM_VER_SYS_H_UIO_EDIT 16 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -157,3 +157,4 @@ ssize_t writev( #endif /* SYNSOFT_UNIXEM_INCL_SYS_H_UIO */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unistd.h b/include/unistd.h index 8ad639e..451f314 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -4,11 +4,11 @@ * Purpose: Declaration of various UNIX standard functions. * * Created: 1st November 2003 - * Updated: 18th May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2003-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_H_UNISTD_MAJOR 3 # define SYNSOFT_UNIXEM_VER_H_UNISTD_MINOR 1 # define SYNSOFT_UNIXEM_VER_H_UNISTD_REVISION 1 -# define SYNSOFT_UNIXEM_VER_H_UNISTD_EDIT 48 +# define SYNSOFT_UNIXEM_VER_H_UNISTD_EDIT 49 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -556,3 +556,4 @@ extern "C++" #endif /* SYNSOFT_UNIXEM_INCL_H_UNISTD */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/asm/atomic.h b/include/unixem/asm/atomic.h index ceac6bb..01a0c9d 100644 --- a/include/unixem/asm/atomic.h +++ b/include/unixem/asm/atomic.h @@ -5,11 +5,11 @@ * Windows platform. * * Created: 21st November 2003 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2003-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -48,7 +48,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_ASM_H_ATOMIC_MAJOR 3 # define SYNSOFT_UNIXEM_VER_UNIXEM_ASM_H_ATOMIC_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_ASM_H_ATOMIC_REVISION 1 -# define SYNSOFT_UNIXEM_VER_UNIXEM_ASM_H_ATOMIC_EDIT 22 +# define SYNSOFT_UNIXEM_VER_UNIXEM_ASM_H_ATOMIC_EDIT 23 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -113,3 +113,4 @@ int unixem_atomic_sub_and_test(int i, unixem_atomic_t volatile* v); #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_ASM_H_ATOMIC */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/dirent.h b/include/unixem/dirent.h index 2b731fe..e3a4202 100644 --- a/include/unixem/dirent.h +++ b/include/unixem/dirent.h @@ -5,11 +5,11 @@ * Windows platform. * * Created: 19th October 2002 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2002-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -53,7 +53,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_H_DIRENT_MAJOR 4 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_DIRENT_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_DIRENT_REVISION 1 -# define SYNSOFT_UNIXEM_VER_UNIXEM_H_DIRENT_EDIT 38 +# define SYNSOFT_UNIXEM_VER_UNIXEM_H_DIRENT_EDIT 39 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -196,3 +196,4 @@ struct unixem_wdirent* unixem_wreaddir(unixem_wDIR* dir); #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_H_DIRENT */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/glob.h b/include/unixem/glob.h index fbde9af..8ee3073 100644 --- a/include/unixem/glob.h +++ b/include/unixem/glob.h @@ -5,11 +5,11 @@ * Windows platform. * * Created: 13th November 2002 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2002-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -53,7 +53,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_GLOB_MAJOR 3 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_GLOB_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_GLOB_REVISION 3 -# define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_GLOB_EDIT 43 +# define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_GLOB_EDIT 44 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -188,3 +188,4 @@ void unixem_globfree(unixem_glob_t* pglob); #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_H_GLOB */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/internal/safestr.h b/include/unixem/internal/safestr.h index 000ba77..b4c97e5 100644 --- a/include/unixem/internal/safestr.h +++ b/include/unixem/internal/safestr.h @@ -4,11 +4,11 @@ * Purpose: Internal utility header for the UNIXem API. * * Created: 28th December 2007 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2007-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -55,7 +55,7 @@ # define UNIXEM_VER_UNIXEM_INTERNAL_H_SAFESTR_MAJOR 1 # define UNIXEM_VER_UNIXEM_INTERNAL_H_SAFESTR_MINOR 0 # define UNIXEM_VER_UNIXEM_INTERNAL_H_SAFESTR_REVISION 1 -# define UNIXEM_VER_UNIXEM_INTERNAL_H_SAFESTR_EDIT 8 +# define UNIXEM_VER_UNIXEM_INTERNAL_H_SAFESTR_EDIT 9 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -110,3 +110,4 @@ #endif /* UNIXEM_INCL_UNIXEM_INTERNAL_H_SAFESTR */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/internal/stdint.h b/include/unixem/internal/stdint.h index 316cc9d..359d9d8 100644 --- a/include/unixem/internal/stdint.h +++ b/include/unixem/internal/stdint.h @@ -4,7 +4,7 @@ * Purpose: Discrimination of integers. * * Created: 29th November 2024 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * @@ -54,7 +54,7 @@ # define UNIXEM_VER_UNIXEM_internal_h_stdint_MAJOR 1 # define UNIXEM_VER_UNIXEM_internal_h_stdint_MINOR 0 # define UNIXEM_VER_UNIXEM_internal_h_stdint_REVISION 0 -# define UNIXEM_VER_UNIXEM_internal_h_stdint_EDIT 1 +# define UNIXEM_VER_UNIXEM_internal_h_stdint_EDIT 2 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -138,3 +138,4 @@ typedef signed long unixem_ssize_t; #endif /* UNIXEM_INCL_UNIXEM_internal_h_stdint */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/internal/util.h b/include/unixem/internal/util.h index 70a0e7c..c3acd52 100644 --- a/include/unixem/internal/util.h +++ b/include/unixem/internal/util.h @@ -4,11 +4,11 @@ * Purpose: Internal utility header for the UNIXem API. * * Created: 2nd September 2005 - * Updated: 17th May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2005-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -55,7 +55,7 @@ # define UNIXEM_VER_UNIXEM_INTERNAL_H_UTIL_MAJOR 1 # define UNIXEM_VER_UNIXEM_INTERNAL_H_UTIL_MINOR 4 # define UNIXEM_VER_UNIXEM_INTERNAL_H_UTIL_REVISION 2 -# define UNIXEM_VER_UNIXEM_INTERNAL_H_UTIL_EDIT 15 +# define UNIXEM_VER_UNIXEM_INTERNAL_H_UTIL_EDIT 16 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -174,3 +174,4 @@ unixem_internal_yearIsLeap( #endif /* UNIXEM_INCL_UNIXEM_INTERNAL_H_UTIL */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/internal/winsock.h b/include/unixem/internal/winsock.h index dcee69c..9dd6b60 100644 --- a/include/unixem/internal/winsock.h +++ b/include/unixem/internal/winsock.h @@ -5,11 +5,11 @@ * support timeval and gethostname()). * * Created: 28th December 2007 - * Updated: 10th July 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2007-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -57,7 +57,7 @@ # define UNIXEM_VER_UNIXEM_INTERNAL_H_WINSOCK_MAJOR 1 # define UNIXEM_VER_UNIXEM_INTERNAL_H_WINSOCK_MINOR 0 # define UNIXEM_VER_UNIXEM_INTERNAL_H_WINSOCK_REVISION 3 -# define UNIXEM_VER_UNIXEM_INTERNAL_H_WINSOCK_EDIT 8 +# define UNIXEM_VER_UNIXEM_INTERNAL_H_WINSOCK_EDIT 9 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -111,3 +111,4 @@ #endif /* UNIXEM_INCL_UNIXEM_INTERNAL_H_WINSOCK */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/sys/mman.h b/include/unixem/sys/mman.h index e55a955..ab87e53 100644 --- a/include/unixem/sys/mman.h +++ b/include/unixem/sys/mman.h @@ -4,11 +4,11 @@ * Purpose: Declaration of the mmap() and munmap() API functions. * * Created: 18th December 2003 - * Updated: 28th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2003-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_MMAP_MAJOR 3 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_MMAP_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_MMAP_REVISION 1 -# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_MMAP_EDIT 27 +# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_MMAP_EDIT 28 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -131,8 +131,8 @@ extern "C" * anonymous map * \param offset The offset within the file to start the mapped region * - * \retval pointer to mapped region if successful - * \retval MAP_FAILED if failed + * \return A pointer to the mapped region if successful; otherwise + * \c MAP_FAILED * * \note The current implementation supports the following three modes: * 1. Read-only file; 2. Read-write file; 3. Anonymous Read-write block of @@ -195,3 +195,4 @@ int unixem_msync( #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_SYS_H_MMAP */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/sys/resource.h b/include/unixem/sys/resource.h index ee2372e..60aaffb 100644 --- a/include/unixem/sys/resource.h +++ b/include/unixem/sys/resource.h @@ -5,11 +5,11 @@ * types for the Windows platform. * * Created: 9th June 2006 - * Updated: 28th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2006-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -53,7 +53,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_RESOURCE_MAJOR 2 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_RESOURCE_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_RESOURCE_REVISION 1 -# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_RESOURCE_EDIT 11 +# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_RESOURCE_EDIT 12 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -139,3 +139,4 @@ extern int unixem_getrusage( #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_SYS_H_RESOURCE */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/sys/time.h b/include/unixem/sys/time.h index b0577fd..5402089 100644 --- a/include/unixem/sys/time.h +++ b/include/unixem/sys/time.h @@ -5,11 +5,11 @@ * types for the Windows platform. * * Created: 8th December 2002 - * Updated: 28th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2002-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -53,7 +53,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_TIME_MAJOR 3 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_TIME_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_TIME_REVISION 2 -# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_TIME_EDIT 29 +# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_TIME_EDIT 30 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -134,3 +134,4 @@ extern int unixem_gettimeofday( #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_SYS_H_TIME */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/sys/uio.h b/include/unixem/sys/uio.h index f6d22f6..12859f7 100644 --- a/include/unixem/sys/uio.h +++ b/include/unixem/sys/uio.h @@ -4,11 +4,11 @@ * Purpose: Vector file read/write. * * Created: 19th September 2005 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2005-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_UIO_MAJOR 2 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_UIO_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_UIO_REVISION 2 -# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_UIO_EDIT 16 +# define SYNSOFT_UNIXEM_VER_UNIXEM_SYS_H_UIO_EDIT 17 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -146,3 +146,4 @@ unixem_writev( #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_SYS_H_UIO */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/time.h b/include/unixem/time.h index 80ce6db..b1413a4 100644 --- a/include/unixem/time.h +++ b/include/unixem/time.h @@ -4,11 +4,11 @@ * Purpose: Time functions and types for the Windows platform. * * Created: 5th May 2014 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2014-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_TIME_MAJOR 1 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_TIME_MINOR 0 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_TIME_REVISION 1 -# define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_TIME_EDIT 5 +# define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNIXEM_TIME_EDIT 6 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -131,3 +131,4 @@ timegm( #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_H_TIME */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/unistd.h b/include/unixem/unistd.h index 5a9baed..2b4d435 100644 --- a/include/unixem/unistd.h +++ b/include/unixem/unistd.h @@ -4,11 +4,11 @@ * Purpose: Declaration of various UNIX standard functions. * * Created: 1st November 2003 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * - * Copyright (c) 2019-2025, Matthew Wilson and Synesis Information Systems + * Copyright (c) 2019-2026, Matthew Wilson and Synesis Information Systems * Copyright (c) 2003-2019, Matthew Wilson and Synesis Software * All rights reserved. * @@ -52,7 +52,7 @@ # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNISTD_MAJOR 3 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNISTD_MINOR 1 # define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNISTD_REVISION 1 -# define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNISTD_EDIT 50 +# define SYNSOFT_UNIXEM_VER_UNIXEM_H_UNISTD_EDIT 51 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ @@ -337,3 +337,4 @@ int __stdcall unixem_gethostname( #endif /* SYNSOFT_UNIXEM_INCL_UNIXEM_H_UNISTD */ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/include/unixem/unixem.h b/include/unixem/unixem.h index 4d36d28..f2ad144 100644 --- a/include/unixem/unixem.h +++ b/include/unixem/unixem.h @@ -4,7 +4,7 @@ * Purpose: Version header for the UNIXem API. * * Created: 29th August 2005 - * Updated: 10th September 2026 + * Updated: 9th October 2026 * * Home: https://github.com/synesissoftware/UNIXem * @@ -56,7 +56,7 @@ # define UNIXEM_VER_UNIXEM_H_UNIXEM_MAJOR 1 # define UNIXEM_VER_UNIXEM_H_UNIXEM_MINOR 7 # define UNIXEM_VER_UNIXEM_H_UNIXEM_REVISION 9 -# define UNIXEM_VER_UNIXEM_H_UNIXEM_EDIT 34 +# define UNIXEM_VER_UNIXEM_H_UNIXEM_EDIT 35 #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ /** \def UNIXEM_VER_MAJOR @@ -71,7 +71,7 @@ * The patch (aka revision) version number of UNIXem */ -/** \def UNIXEM_VER_AB +/** \def UNIXEM_VER_ALPHABETA * The alpha/beta/rc number of UNIXem */ @@ -82,19 +82,19 @@ #define UNIXEM_VER_MAJOR 1 #define UNIXEM_VER_MINOR 14 #define UNIXEM_VER_PATCH 0 -#define UNIXEM_VER_AB 0xC1 +#define UNIXEM_VER_ALPHABETA 0xC1 #define UNIXEM_VER \ (0\ | ( UNIXEM_VER_MAJOR << 24 ) \ | ( UNIXEM_VER_MINOR << 16 ) \ | ( UNIXEM_VER_PATCH << 8 ) \ - | ( UNIXEM_VER_AB << 0 ) \ + | ( UNIXEM_VER_ALPHABETA << 0 ) \ ) #ifndef UNIXEM_DOCUMENTATION_SKIP_SECTION -# define UNIXEM_VER_ALPHABETA UNIXEM_VER_AB -# define UNIXEM_VER_REVISION UNIXEM_VER_PATCH +# define UNIXEM_VER_AB UNIXEM_VER_ALPHABETA +# define UNIXEM_VER_REVISION UNIXEM_VER_PATCH #endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */ diff --git a/prepare_cmake.sh b/prepare_cmake.sh index 352ab04..d2502a7 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -1,32 +1,136 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") -CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -if [[ -n "$MSYSTEM" ]]; then +# ########################################################## +# functions - 1 - DefaultMakeCmd=mingw32-make.exe - MinGW=1 -else +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in - DefaultMakeCmd=make -fi -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 - +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} +BuildSharedLibs=0 Configuration=Release ExamplesDisabled=0 +MinGW=$(sis_cmake_is_truey "${SIS_CMAKE_MINGW:-}" && echo 1 || echo 0) MSVC_MT=0 -MinGW="${MinGW:=0}" -NO_shwild=0 RunMake=0 -STLSoftDirGiven= +SisUseColours=0 TestingDisabled=0 VerboseMakefile=0 +# ########################################################## +# PROJECT-SPECIFIC FLAGS (customise per library; keep marker) +# +# Add project-only options here (e.g. --no-cpp, --stlsoft-root-dir, +# --no-shwild). The common body below must stay aligned with +# misc-dev-scripts/shell-scripts/cmake-helpers/prepare_cmake.sh. + + +NO_shwild=0 +STLSoftDirGiven= + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} + # ########################################################## # command-line handling @@ -34,6 +138,14 @@ VerboseMakefile=0 while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; + --build-shared-libs) + + BuildSharedLibs=1 + ;; --cmake-verbose-makefile|-v) VerboseMakefile=1 @@ -77,46 +189,49 @@ while [[ $# -gt 0 ]]; do cat << EOF Creates/reinitialises the CMake build script(s) -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + + --build-shared-libs + builds ${ProjectName} as a shared library (BUILD_SHARED_LIBS=ON) + -v --cmake-verbose-makefile - configures CMake to run verbosely (by setting CMAKE_VERBOSE_MAKEFILE - to be ON) + configures CMake to run verbosely (CMAKE_VERBOSE_MAKEFILE=ON) -d --debug-configuration - use Debug configuration (by setting CMAKE_BUILD_TYPE=Debug). Default - is to use Release + use Debug configuration (CMAKE_BUILD_TYPE=Debug). Default is Release -E --disable-examples - disables building of examples (by setting BUILD_EXAMPLES=OFF) + disables building of examples (BUILD_EXAMPLES=OFF) -T --disable-testing - disables building of tests (by setting BUILD_TESTING=OFF). Unless - testing is disabled the STLSoft and xTests libraries will be - required to be available to CMake + disables building of tests (BUILD_TESTING=OFF) --mingw - uses explicitly the "MinGW Makefiles" generator, and defaults the - make-command to "mingw32-make.exe" + uses explicitly the "MinGW Makefiles" generator --msvc-mt - when using Visual C++ (MSVC), the static runtime library will be - selected; the default is the dynamic runtime library + when using Visual C++ (MSVC), select the static runtime library --no-shwild prevents recognising shwild library -m --run-make - executes make after a successful running of CMake + executes a build via cmake --build after a successful configure + -s --stlsoft-root-dir @@ -124,7 +239,6 @@ Flags/options: as the variable STLSOFT, and which will override the environment variable STLSOFT (if present) - standard flags: --help @@ -136,7 +250,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -149,68 +263,68 @@ done # ########################################################## # main() -mkdir -p $CMakeDir || exit 1 +mkdir -p "$CMakeDir" || exit 1 -cd $CMakeDir - -echo "Executing CMake for ${ProjectName} (in ${CMakeDir})" +echo +echo "Executing CMake for ${ProjectNameClr} (in ${CMakeDirClr})" +if [ $BuildSharedLibs -eq 0 ]; then CMakeBuildSharedLibsFlag="OFF" ; else CMakeBuildSharedLibsFlag="ON" ; fi 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_shwild -eq 0 ]; then CMakeNoShwild="OFF" ; else CMakeNoShwild="ON" ; fi -if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi +if [ -z "$STLSoftDirGiven" ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi if [ $TestingDisabled -eq 0 ]; then CMakeBuildTestingFlag="ON" ; else CMakeBuildTestingFlag="OFF" ; fi if [ $VerboseMakefile -eq 0 ]; then CMakeVerboseMakefileFlag="OFF" ; else CMakeVerboseMakefileFlag="ON" ; fi +# NOTE: the generator is the *only* thing that may differ between the MinGW +# and the default paths; every -D option is passed in both cases, so that no +# flag can be silently ignored according to the generator selected. + +CMakeGeneratorArgs=() + +if [ -n "${SIS_CMAKE_GENERATOR:-}" ] && [ $MinGW -eq 0 ]; then + + CMakeGeneratorArgs=(-G "$SIS_CMAKE_GENERATOR") +fi + if [ $MinGW -ne 0 ]; then - cmake \ - $CMakeSTLSoftVariable \ - -DBUILD_EXAMPLES:BOOL=$CMakeBuildExamplesFlag \ - -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ - -DCMAKE_BUILD_TYPE=$Configuration \ - -DNO_SHWILD:BOOL=$CMakeNoShwild \ - -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ - -G "MinGW Makefiles" \ - -S $Dir \ - -B $CMakeDir \ - || (cd ->/dev/null ; exit 1) -else - - cmake \ - $CMakeSTLSoftVariable \ - -DBUILD_EXAMPLES:BOOL=$CMakeBuildExamplesFlag \ - -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ - -DCMAKE_BUILD_TYPE=$Configuration \ - -DNO_SHWILD:BOOL=$CMakeNoShwild \ - -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ - -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ - -S $Dir \ - -B $CMakeDir \ - || (cd ->/dev/null ; exit 1) + CMakeGeneratorArgs=(-G "MinGW Makefiles") fi +cmake \ + -DBUILD_EXAMPLES:BOOL=$CMakeBuildExamplesFlag \ + -DBUILD_SHARED_LIBS:BOOL=$CMakeBuildSharedLibsFlag \ + -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ + -DCMAKE_BUILD_TYPE=$Configuration \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ + -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ + -DNO_SHWILD:BOOL=$CMakeNoShwild \ + $CMakeSTLSoftVariable \ + "${CMakeGeneratorArgs[@]}" \ + -B "$CMakeDir" \ + -S "$Dir" \ + || exit 1 status=0 if [ $RunMake -ne 0 ]; then - echo "Executing build (via command \`$MakeCmd\`)" + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build)" - $MakeCmd + sis_cmake_build status=$? fi -cd ->/dev/null - if [ $VerboseMakefile -ne 0 ]; then - echo -e "contents of $CMakeDir:" - ls -al $CMakeDir + echo + echo -e "contents of ${CMakeDirClr}:" + ls -al "$CMakeDir" fi exit $status # ############################## end of file ############################# # - diff --git a/remove_cmake_artefacts.sh b/remove_cmake_artefacts.sh index e09e895..377d3ab 100755 --- a/remove_cmake_artefacts.sh +++ b/remove_cmake_artefacts.sh @@ -1,12 +1,16 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} Directories=( CMakeFiles Testing @@ -24,14 +28,73 @@ Files=( cmake_install.cmake install_manifest.txt ) +SisUseColours=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" # ########################################################## # operating environment detection -OsName="$(uname -s)" +OsName="$(uname -s 2>/dev/null || echo Unknown)" case "${OsName}" in - CYGWIN*|MINGW*|MSYS_NT*) + CYGWIN*|MINGW*|MSYS_NT*|Windows_NT) Directories+=( ARM64 @@ -43,9 +106,6 @@ case "${OsName}" in "*.sln" "*.vcxproj" ) - ;; - *) - ;; esac @@ -56,18 +116,27 @@ esac while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --help) [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF Removes all known CMake artefacts -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + standard flags: @@ -80,7 +149,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -95,59 +164,50 @@ done if [ ! -d "$CMakeDir" ]; then - echo "$ScriptPath: CMake build directory '$CMakeDir' not found so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" + echo "${ScriptPathClr}: CMake build directory '${CMakeDirClr}' not found so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" exit 0 -else - - echo "Removing all ${ProjectName} cmake artefacts in '$CMakeDir'" +fi - num_dirs_removed=0 - num_files_removed=0 +echo "Removing all ${ProjectNameClr} cmake artefacts in '${CMakeDirClr}'" - for d in ${Directories[@]} - do +num_dirs_removed=0 +num_files_removed=0 - fq_dir_path="$CMakeDir/$d" +for d in "${Directories[@]}"; do - [ -d "$fq_dir_path" ] || continue + fq_dir_path="$CMakeDir/$d" - echo "removing directory '$d'" + [ -d "$fq_dir_path" ] || continue - rm -dfr "$fq_dir_path" + echo "removing directory '$d'" - num_dirs_removed=$((num_dirs_removed+1)) - done + rm -dfr "$fq_dir_path" - cd "$CMakeDir" + num_dirs_removed=$((num_dirs_removed+1)) +done - for f in ${Files[@]} - do +for f in "${Files[@]}"; do - for fq_file_path in $f - do + for fq_file_path in "$CMakeDir"/$f; do - [ -f "$fq_file_path" ] || continue + [ -f "$fq_file_path" ] || continue - echo "removing file '$fq_file_path'" + echo "removing file '$fq_file_path'" - rm -f "$fq_file_path" + rm -f "$fq_file_path" - num_files_removed=$((num_files_removed+1)) - done + num_files_removed=$((num_files_removed+1)) done +done - cd ->/dev/null - - if [ 0 -eq $num_dirs_removed ] && [ 0 -eq $num_files_removed ]; then +if [ 0 -eq $num_dirs_removed ] && [ 0 -eq $num_files_removed ]; then - echo "nothing to do" - else + echo "nothing to do" +else - echo "removed $num_dirs_removed directories and $num_files_removed files" - fi + echo "removed $num_dirs_removed directories and $num_files_removed files" fi # ############################## end of file ############################# # - diff --git a/run_all_automated_tests.cmd b/run_all_automated_tests.cmd new file mode 100644 index 0000000..b6dd937 --- /dev/null +++ b/run_all_automated_tests.cmd @@ -0,0 +1,106 @@ +@echo off + +SETLOCAL + +SET SCRIPT_DIRECTORY=%~dp0 +SET SCRIPT_PATH_DOC=%~n0[%~x0] + +SET UnitOnly=0 +SET ComponentOnly=0 + +FOR %%a IN (%*) DO ( + + IF /I {--help}=={%%a} ( + + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ + +Runs all ^(matching^) automated test programs ^(unit and component^) ^ + +^ + +%SCRIPT_PATH_DOC% [ ... flags/options ... ] ^ + +^ + +Flags/options: ^ + + behaviour: ^ + +^ + + --unit-only ^ + + runs only unit-test programs ^ + +^ + + --component-only ^ + + runs only component-test programs ^ + +^ + + standard flags: ^ + +^ + + --help ^ + + displays this help and terminates ^ + + + EXIT /B 0 + ) ELSE IF /I {--unit-only}=={%%a} ( + + SET UnitOnly=1 + ) ELSE IF /I {--component-only}=={%%a} ( + + SET ComponentOnly=1 + ) ELSE ( + + ECHO "%SCRIPT_DIRECTORY%: unrecognised argument '%%a'; use --help for usage" 1>&2 + + EXIT /B 1 + ) +) + +IF %UnitOnly% NEQ 0 IF %ComponentOnly% NEQ 0 ( + + ECHO %SCRIPT_PATH_DOC%: --unit-only and --component-only are mutually exclusive 1>&2 + + EXIT /B 1 +) + +IF %UnitOnly% NEQ 0 ( + CALL "%SCRIPT_DIRECTORY%run_all_unit_tests.cmd" + EXIT /B %ERRORLEVEL% +) + +IF %ComponentOnly% NEQ 0 ( + CALL "%SCRIPT_DIRECTORY%run_all_component_tests.cmd" + EXIT /B %ERRORLEVEL% +) + +SET "ProjectName=" +FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO SET "ProjectName=%%p" + +IF NOT DEFINED ProjectName ( + + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 + + EXIT /B 1 +) + +ECHO Running all %ProjectName% automated test programs ^(unit and component^) + +CALL "%SCRIPT_DIRECTORY%run_all_unit_tests.cmd" +IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL% + +CALL "%SCRIPT_DIRECTORY%run_all_component_tests.cmd" +EXIT /B %ERRORLEVEL% + +ENDLOCAL diff --git a/run_all_automated_tests.sh b/run_all_automated_tests.sh new file mode 100755 index 0000000..2c13b16 --- /dev/null +++ b/run_all_automated_tests.sh @@ -0,0 +1,180 @@ +#! /bin/bash + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 + +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} +ComponentOnly=0 +ForwardedArgs=() +SisUseColours=0 +UnitOnly=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - handled above; forward so category runners see it + ForwardedArgs+=("$1") + ;; + --unit-only) + + UnitOnly=1 + ;; + --component-only) + + ComponentOnly=1 + ;; + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Runs all (matching) automated test programs (unit and component) + +${ScriptPath} [ ... flags/options ... ] + +Flags/options: + + behaviour: + + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + + --component-only + runs only component-test programs + + --unit-only + runs only unit-test programs + + (all other flags are forwarded to the category runner script) + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + ForwardedArgs+=("$1") + ;; + esac + + shift +done + +if [ $UnitOnly -ne 0 ] && [ $ComponentOnly -ne 0 ]; then + + >&2 echo "${ScriptPathClr}: ${SisClr_Red}${SisClr_Bold}--unit-only${SisClr_None} and ${SisClr_Red}${SisClr_Bold}--component-only${SisClr_None} are mutually exclusive" + + exit 1 +fi + + +# ########################################################## +# main() + +status=0 + +if [ $UnitOnly -ne 0 ]; then + + "$Dir/run_all_unit_tests.sh" "${ForwardedArgs[@]}" + exit $? +fi + +if [ $ComponentOnly -ne 0 ]; then + + "$Dir/run_all_component_tests.sh" "${ForwardedArgs[@]}" + exit $? +fi + +echo +echo "Running all ${ProjectNameClr} automated test programs (unit and component)" + +"$Dir/run_all_unit_tests.sh" "${ForwardedArgs[@]}" +status=$? + +if [ $status -eq 0 ]; then + + "$Dir/run_all_component_tests.sh" "${ForwardedArgs[@]}" + status=$? +fi + +exit $status + + +# ############################## end of file ############################# # diff --git a/run_all_component_tests.cmd b/run_all_component_tests.cmd new file mode 100644 index 0000000..970c9ba --- /dev/null +++ b/run_all_component_tests.cmd @@ -0,0 +1,94 @@ +@echo off + +SETLOCAL + +SET SCRIPT_DIRECTORY=%~dp0 +SET SCRIPT_PATH_DOC=%~n0[%~x0] + +IF DEFINED SIS_CMAKE_BUILD_DIR ( + + SET CMAKE_DIR=%SIS_CMAKE_BUILD_DIR% +) ELSE ( + + SET CMAKE_DIR=%SCRIPT_DIRECTORY%_build +) + +FOR %%a IN (%*) DO ( + + IF /I {--help}=={%%a} ( + + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ + +Runs all ^(matching^) component-test programs ^ + +^ + +%SCRIPT_PATH_DOC% [ ... flags/options ... ] ^ + +^ + +Flags/options: ^ + + behaviour: ^ + +^ + + --component-only ^ + + accepted for compatibility; this script always runs component tests only ^ + +^ + + standard flags: ^ + +^ + + --help ^ + + displays this help and terminates ^ + + + EXIT /B 0 + ) ELSE IF /I {--component-only}=={%%a} ( + + REM Benign: this script is already component-only + ) ELSE ( + + ECHO "%SCRIPT_DIRECTORY%: unrecognised argument '%%a'; use --help for usage" 1>&2 + + EXIT /B 1 + ) +) + +if NOT EXIST "%CMAKE_DIR%" ( + + ECHO "CMake build directory '%CMAKE_DIR%' does not exist" + + EXIT /B 1 +) + +SET "ProjectName=" +FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO SET "ProjectName=%%p" + +IF NOT DEFINED ProjectName ( + + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 + + EXIT /B 1 +) + +ECHO Running all %ProjectName% component-test programs + +FOR /F "usebackq" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%" ^| FINDSTR /I test.*component.*\.exe$`) DO ( + + ECHO . + ECHO executing %%f + %%f + IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL% +) + +ENDLOCAL diff --git a/run_all_component_tests.sh b/run_all_component_tests.sh new file mode 100755 index 0000000..c0bd27e --- /dev/null +++ b/run_all_component_tests.sh @@ -0,0 +1,300 @@ +#! /bin/bash + +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 + +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} +ListOnly=0 +RunMake=1 +SisUseColours=0 +Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}} + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; + --component-only) + + # Benign: this script is already component-only (aggregate / CI may + # pass it) + ;; + --list-only|-l) + + ListOnly=1 + ;; + --no-make|-M) + + RunMake=0 + ;; + --verbosity) + + shift + Verbosity=$1 + ;; + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Runs all (matching) component-test programs + +${ScriptPath} [ ... flags/options ... ] + +Flags/options: + + behaviour: + + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + + --component-only + accepted for compatibility; this script always runs component tests + only + + -l + --list-only + lists the target programs but does not execute them + + -M + --no-make + does not execute a build before running programs + + --verbosity + specifies an explicit verbosity, forwarded to each program + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +status=0 + +if [ $RunMake -ne 0 ]; then + + if [ $ListOnly -eq 0 ]; then + + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build) and then running all component-test programs" + + mkdir -p "$CMakeDir" || exit 1 + + if [ ! -f "$CMakeDir/CMakeCache.txt" ]; then + + >&2 echo "${ScriptPathClr}: '${CMakeDirClr}' is not configured; use prepare_cmake.sh first" + + exit 1 + fi + + sis_cmake_build + status=$? + fi +else + + if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then + + >&2 echo "${ScriptPathClr}: cannot run in '--no-make' mode without a previous successful configure/build" + + exit 1 + fi +fi + +if [ $status -eq 0 ]; then + + if [ $ListOnly -ne 0 ]; then + + echo + echo "Listing all ${ProjectNameClr} component-test programs" + else + + echo + echo "Running all ${ProjectNameClr} component-test programs" + fi + + NumPrograms=0 + + while IFS= read -r -d '' f; do + + case "$f" in + *.pdb|*.ilk|*.log|*.obj|*.o) + continue + ;; + esac + + NumPrograms=$((NumPrograms + 1)) + + fClr="${SisClr_Blue}${SisClr_Bold}${f}${SisClr_None}" + + if [ $ListOnly -ne 0 ]; then + + echo "would execute ${fClr}:" + + continue + fi + + if [ $Verbosity -ge 3 ]; then + + echo + fi + if [ $Verbosity -ge 2 ]; then + + echo "executing ${fClr}:" + fi + + if "$f" --verbosity="$Verbosity"; then + + : + else + + status=$? + + break 1 + fi + done < <(find "$CMakeDir" -type f \( -name 'test_component*' -o -name 'test.component.*' \) \( -perm -100 -o -name '*.exe' \) -print0 2>/dev/null | sort -z) + + if [ $NumPrograms -eq 0 ]; then + + echo "${ScriptPathClr}: found no component-test programs under '${CMakeDirClr}' (none found)" + + exit 0 + fi +fi + +exit $status + + +# ############################## end of file ############################# # diff --git a/run_all_examples.cmd b/run_all_examples.cmd new file mode 100644 index 0000000..b10e3d2 --- /dev/null +++ b/run_all_examples.cmd @@ -0,0 +1,131 @@ +@echo off + +SETLOCAL + +SET SCRIPT_DIRECTORY=%~dp0 +SET SCRIPT_PATH_DOC=%~n0[%~x0] +SET "ALLOWED_TO_FAIL_FILE=%SCRIPT_DIRECTORY%.sis\ci_examples_allowed_to_fail.txt" +SET "PROGRAM_STATUS=0" + +IF DEFINED SIS_CMAKE_BUILD_DIR ( + + SET CMAKE_DIR=%SIS_CMAKE_BUILD_DIR% +) ELSE ( + + SET CMAKE_DIR=%SCRIPT_DIRECTORY%_build +) + +FOR %%a IN (%*) DO ( + + IF /I {--help}=={%%a} ( + + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ + +Runs all ^(matching^) example programs ^ + +^ + +%SCRIPT_PATH_DOC% [ ... flags/options ... ] ^ + +^ + +Flags/options: ^ + + behaviour: ^ + +^ + + standard flags: ^ + +^ + + --help ^ + + displays this help and terminates ^ + +^ + + files: ^ + +^ + + .sis\ci_examples_allowed_to_fail.txt ^ + + optional list of example programs ^(one name per line; ^ + + lines beginning with '#' are ignored^) that are allowed to fail; ^ + + such a program is still executed, but a non-zero exit is ^ + + reported as anticipated and does not stop the run ^ + + + EXIT /B 0 + ) ELSE ( + + ECHO "%SCRIPT_DIRECTORY%: unrecognised argument '%%a'; use --help for usage" 1>&2 + + EXIT /B 1 + ) +) + +if NOT EXIST "%CMAKE_DIR%" ( + + ECHO "CMake build directory '%CMAKE_DIR%' does not exist" + + EXIT /B 1 +) + +SET "ProjectName=" +FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO SET "ProjectName=%%p" + +IF NOT DEFINED ProjectName ( + + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 + + EXIT /B 1 +) + +REM Examples that require human input may honour SIS_EXAMPLE_SMOKE for a +REM no-arg built-in tmpfile demo (see example.c.cstring_vector). +SET SIS_EXAMPLE_SMOKE=1 + +ECHO Running all %ProjectName% example programs + +FOR /F "usebackq" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%" ^| FINDSTR /I example.*\.exe$`) DO CALL :run_program "%%f" + +ENDLOCAL & EXIT /B %PROGRAM_STATUS% + + +REM ########################################################## +REM subroutines + +:run_program +IF %PROGRAM_STATUS% NEQ 0 EXIT /B 0 +ECHO . +ECHO executing %~1 +"%~1" +SET "FAILURE_STATUS=%ERRORLEVEL%" +IF %FAILURE_STATUS% EQU 0 EXIT /B 0 +CALL :is_allowed_to_fail "%~1" +IF NOT DEFINED ALLOWED_TO_FAIL GOTO run_program_failed +ECHO anticipated failure: %~1 exited with status %FAILURE_STATUS%; it is listed in .sis\ci_examples_allowed_to_fail.txt +EXIT /B 0 +:run_program_failed +SET "PROGRAM_STATUS=%FAILURE_STATUS%" +EXIT /B 0 + +:is_allowed_to_fail +SET "ALLOWED_TO_FAIL=" +IF NOT EXIST "%ALLOWED_TO_FAIL_FILE%" EXIT /B 0 +FOR /F "usebackq eol=# tokens=1" %%n IN ("%ALLOWED_TO_FAIL_FILE%") DO CALL :match_allowed "%%n" "%~n1" "%~nx1" +EXIT /B 0 + +:match_allowed +IF /I "%~1"=="%~2" SET "ALLOWED_TO_FAIL=1" +IF /I "%~1"=="%~3" SET "ALLOWED_TO_FAIL=1" +EXIT /B 0 diff --git a/run_all_examples.sh b/run_all_examples.sh index 27ab112..722326a 100755 --- a/run_all_examples.sh +++ b/run_all_examples.sh @@ -1,16 +1,163 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -[[ -n "$MSYSTEM" ]] && DefaultMakeCmd=mingw32-make.exe || DefaultMakeCmd=make -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 +AllowedToFailFile="$Dir/.sis/ci_examples_allowed_to_fail.txt" +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} ListOnly=0 RunMake=1 +SisUseColours=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} + +# Reduces a program path to its (lowercase) name, without any directory or +# .exe suffix. +sis_program_stem() { + + local p="${1//\\//}" + + p="${p##*/}" + + case "$p" in + *.exe|*.EXE) p="${p%.*}" ;; + esac + + printf '%s' "$p" | tr '[:upper:]' '[:lower:]' +} + +# Succeeds if the program is named (by name or stem, case-insensitively) in +# the optional .sis/ci_examples_allowed_to_fail.txt file; blank lines and +# lines beginning with '#' are ignored. +sis_is_allowed_to_fail() { + + local name line + + [ -f "$AllowedToFailFile" ] || return 1 + + name=$(sis_program_stem "$1") + + while IFS= read -r line || [ -n "$line" ]; do + + line="${line//$'\r'/}" + + case "$line" in + ''|\#*) continue ;; + esac + + if [ "$name" = "$(sis_program_stem "$line")" ]; then + + return 0 + fi + done < "$AllowedToFailFile" + + return 1 +} # ########################################################## @@ -19,6 +166,10 @@ RunMake=1 while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --list-only|-l) ListOnly=1 @@ -31,21 +182,35 @@ while [[ $# -gt 0 ]]; do [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF -Runs all example programs +Runs all (matching) example programs -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + -l --list-only lists the target programs but does not execute them -M --no-make - does not execute CMake and make before running tests + does not execute a build before running programs + + + files: + + .sis/ci_examples_allowed_to_fail.txt + optional list of example programs (one name per line; blank lines + and lines beginning with '#' are ignored) that are allowed to fail; + such a program is still executed, but a non-zero exit is reported as + anticipated and neither stops the run nor affects the exit status standard flags: @@ -59,7 +224,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -78,22 +243,28 @@ if [ $RunMake -ne 0 ]; then if [ $ListOnly -eq 0 ]; then - echo "Executing build of ${ProjectName} (via command \`$MakeCmd\`) and then running all example programs" + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build) and then running all example programs" - mkdir -p $CMakeDir || exit 1 + mkdir -p "$CMakeDir" || exit 1 - cd $CMakeDir + if [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - $MakeCmd - status=$? + >&2 echo "${ScriptPathClr}: '${CMakeDirClr}' is not configured; use prepare_cmake.sh first" + + exit 1 + fi - cd ->/dev/null + sis_cmake_build + status=$? fi else - if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ] || [ ! -d "$CMakeDir/CMakeFiles" ]; then + if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then + + >&2 echo "${ScriptPathClr}: cannot run in '--no-make' mode without a previous successful configure/build" - >&2 echo "$ScriptPath: cannot run in '--no-make' mode without a previous successful build step" + exit 1 fi fi @@ -101,29 +272,73 @@ if [ $status -eq 0 ]; then if [ $ListOnly -ne 0 ]; then - echo "Listing all ${ProjectName} example programs" + echo + echo "Listing all ${ProjectNameClr} example programs" else - echo "Running all ${ProjectName} example programs" + echo + echo "Running all ${ProjectNameClr} example programs" fi - if [ -d "$CMakeDir/examples" ]; then + # Examples that require human input may honour SIS_EXAMPLE_SMOKE for a + # no-arg built-in tmpfile demo (see example.c.cstring_vector). + export SIS_EXAMPLE_SMOKE=1 + + NumPrograms=0 + + while IFS= read -r -d '' f; do + + case "$f" in + *.pdb|*.ilk|*.log|*.obj|*.o) + continue + ;; + esac + + NumPrograms=$((NumPrograms + 1)) + + fClr="${SisClr_Blue}${SisClr_Bold}${f}${SisClr_None}" + + if [ $ListOnly -ne 0 ]; then + + if sis_is_allowed_to_fail "$f"; then + + echo "would execute ${fClr} (allowed to fail):" + else - for f in $(find "$CMakeDir/examples" -type f -exec test -x {} \; -print | sort) - do + echo "would execute ${fClr}:" + fi + + continue + fi + + echo + echo "executing ${fClr}:" + + if "$f"; then + + : + else + + fStatus=$? - if [ $ListOnly -ne 0 ]; then + if sis_is_allowed_to_fail "$f"; then - echo "would execute $f:" + echo "${SisClr_Yellow}${SisClr_Bold}anticipated failure${SisClr_None}: ${fClr} exited with status ${fStatus}; it is listed in .sis/ci_examples_allowed_to_fail.txt" continue fi - echo - echo "executing $f:" + status=$fStatus - $f - done + break 1 + fi + done < <(find "$CMakeDir" -type f \( -name 'example*' ! -name '*.md' \) \( -perm -100 -o -name '*.exe' \) -print0 2>/dev/null | sort -z) + + if [ $NumPrograms -eq 0 ]; then + + echo "${ScriptPathClr}: found no example programs under '${CMakeDirClr}' (none found)" + + exit 0 fi fi @@ -131,4 +346,3 @@ exit $status # ############################## end of file ############################# # - diff --git a/run_all_performance_tests.cmd b/run_all_performance_tests.cmd new file mode 100644 index 0000000..ae97766 --- /dev/null +++ b/run_all_performance_tests.cmd @@ -0,0 +1,85 @@ +@echo off + +SETLOCAL + +SET SCRIPT_DIRECTORY=%~dp0 +SET SCRIPT_PATH_DOC=%~n0[%~x0] + +IF DEFINED SIS_CMAKE_BUILD_DIR ( + + SET CMAKE_DIR=%SIS_CMAKE_BUILD_DIR% +) ELSE ( + + SET CMAKE_DIR=%SCRIPT_DIRECTORY%_build +) + +FOR %%a IN (%*) DO ( + + IF /I {--help}=={%%a} ( + + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ + +Runs all ^(matching^) performance-test programs ^ + +^ + +%SCRIPT_PATH_DOC% [ ... flags/options ... ] ^ + +^ + +Flags/options: ^ + + behaviour: ^ + +^ + + standard flags: ^ + +^ + + --help ^ + + displays this help and terminates ^ + + + EXIT /B 0 + ) ELSE ( + + ECHO "%SCRIPT_DIRECTORY%: unrecognised argument '%%a'; use --help for usage" 1>&2 + + EXIT /B 1 + ) +) + +if NOT EXIST "%CMAKE_DIR%" ( + + ECHO "CMake build directory '%CMAKE_DIR%' does not exist" + + EXIT /B 1 +) + +SET "ProjectName=" +FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO SET "ProjectName=%%p" + +IF NOT DEFINED ProjectName ( + + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 + + EXIT /B 1 +) + +ECHO Running all %ProjectName% performance-test programs + +FOR /F "usebackq" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%" ^| FINDSTR /I test.*performance.*\.exe$`) DO ( + + ECHO . + ECHO executing %%f + %%f + IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL% +) + +ENDLOCAL diff --git a/run_all_performance_tests.sh b/run_all_performance_tests.sh new file mode 100755 index 0000000..3feaaff --- /dev/null +++ b/run_all_performance_tests.sh @@ -0,0 +1,276 @@ +#! /bin/bash + +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 + +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} +ListOnly=0 +RunMake=1 +SisUseColours=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; + --list-only|-l) + + ListOnly=1 + ;; + --no-make|-M) + + RunMake=0 + ;; + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Runs all (matching) performance-test programs + +${ScriptPath} [ ... flags/options ... ] + +Flags/options: + + behaviour: + + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + + -l + --list-only + lists the target programs but does not execute them + + -M + --no-make + does not execute a build before running programs + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +status=0 + +if [ $RunMake -ne 0 ]; then + + if [ $ListOnly -eq 0 ]; then + + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build) and then running all performance-test programs" + + mkdir -p "$CMakeDir" || exit 1 + + if [ ! -f "$CMakeDir/CMakeCache.txt" ]; then + + >&2 echo "${ScriptPathClr}: '${CMakeDirClr}' is not configured; use prepare_cmake.sh first" + + exit 1 + fi + + sis_cmake_build + status=$? + fi +else + + if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then + + >&2 echo "${ScriptPathClr}: cannot run in '--no-make' mode without a previous successful configure/build" + + exit 1 + fi +fi + +if [ $status -eq 0 ]; then + + if [ $ListOnly -ne 0 ]; then + + echo + echo "Listing all ${ProjectNameClr} performance-test programs" + else + + echo + echo "Running all ${ProjectNameClr} performance-test programs" + fi + + NumPrograms=0 + + while IFS= read -r -d '' f; do + + case "$f" in + *.pdb|*.ilk|*.log|*.obj|*.o) + continue + ;; + esac + + NumPrograms=$((NumPrograms + 1)) + + fClr="${SisClr_Blue}${SisClr_Bold}${f}${SisClr_None}" + + if [ $ListOnly -ne 0 ]; then + + echo "would execute ${fClr}:" + + continue + fi + + echo + echo "executing ${fClr}:" + + if "$f"; then + + : + else + + status=$? + + break 1 + fi + done < <(find "$CMakeDir" -type f \( -name 'test_performance*' -o -name 'test.performance.*' \) \( -perm -100 -o -name '*.exe' \) -print0 2>/dev/null | sort -z) + + if [ $NumPrograms -eq 0 ]; then + + echo "${ScriptPathClr}: found no performance-test programs under '${CMakeDirClr}' (none found)" + + exit 0 + fi +fi + +exit $status + + +# ############################## end of file ############################# # diff --git a/run_all_scratch_tests.cmd b/run_all_scratch_tests.cmd new file mode 100644 index 0000000..0402fb1 --- /dev/null +++ b/run_all_scratch_tests.cmd @@ -0,0 +1,127 @@ +@echo off + +SETLOCAL + +SET SCRIPT_DIRECTORY=%~dp0 +SET SCRIPT_PATH_DOC=%~n0[%~x0] +SET "ALLOWED_TO_FAIL_FILE=%SCRIPT_DIRECTORY%.sis\ci_scratch_tests_allowed_to_fail.txt" +SET "PROGRAM_STATUS=0" + +IF DEFINED SIS_CMAKE_BUILD_DIR ( + + SET CMAKE_DIR=%SIS_CMAKE_BUILD_DIR% +) ELSE ( + + SET CMAKE_DIR=%SCRIPT_DIRECTORY%_build +) + +FOR %%a IN (%*) DO ( + + IF /I {--help}=={%%a} ( + + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ + +Runs all ^(matching^) scratch-test programs ^ + +^ + +%SCRIPT_PATH_DOC% [ ... flags/options ... ] ^ + +^ + +Flags/options: ^ + + behaviour: ^ + +^ + + standard flags: ^ + +^ + + --help ^ + + displays this help and terminates ^ + +^ + + files: ^ + +^ + + .sis\ci_scratch_tests_allowed_to_fail.txt ^ + + optional list of scratch-test programs ^(one name per line; ^ + + lines beginning with '#' are ignored^) that are allowed to fail; ^ + + such a program is still executed, but a non-zero exit is ^ + + reported as anticipated and does not stop the run ^ + + + EXIT /B 0 + ) ELSE ( + + ECHO "%SCRIPT_DIRECTORY%: unrecognised argument '%%a'; use --help for usage" 1>&2 + + EXIT /B 1 + ) +) + +if NOT EXIST "%CMAKE_DIR%" ( + + ECHO "CMake build directory '%CMAKE_DIR%' does not exist" + + EXIT /B 1 +) + +SET "ProjectName=" +FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO SET "ProjectName=%%p" + +IF NOT DEFINED ProjectName ( + + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 + + EXIT /B 1 +) + +ECHO Running all %ProjectName% scratch-test programs + +FOR /F "usebackq" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%" ^| FINDSTR /I test.*scratch.*\.exe$`) DO CALL :run_program "%%f" + +ENDLOCAL & EXIT /B %PROGRAM_STATUS% + + +REM ########################################################## +REM subroutines + +:run_program +IF %PROGRAM_STATUS% NEQ 0 EXIT /B 0 +ECHO . +ECHO executing %~1 +"%~1" +SET "FAILURE_STATUS=%ERRORLEVEL%" +IF %FAILURE_STATUS% EQU 0 EXIT /B 0 +CALL :is_allowed_to_fail "%~1" +IF NOT DEFINED ALLOWED_TO_FAIL GOTO run_program_failed +ECHO anticipated failure: %~1 exited with status %FAILURE_STATUS%; it is listed in .sis\ci_scratch_tests_allowed_to_fail.txt +EXIT /B 0 +:run_program_failed +SET "PROGRAM_STATUS=%FAILURE_STATUS%" +EXIT /B 0 + +:is_allowed_to_fail +SET "ALLOWED_TO_FAIL=" +IF NOT EXIST "%ALLOWED_TO_FAIL_FILE%" EXIT /B 0 +FOR /F "usebackq eol=# tokens=1" %%n IN ("%ALLOWED_TO_FAIL_FILE%") DO CALL :match_allowed "%%n" "%~n1" "%~nx1" +EXIT /B 0 + +:match_allowed +IF /I "%~1"=="%~2" SET "ALLOWED_TO_FAIL=1" +IF /I "%~1"=="%~3" SET "ALLOWED_TO_FAIL=1" +EXIT /B 0 diff --git a/run_all_scratch_tests.sh b/run_all_scratch_tests.sh index c976a35..6e06f13 100755 --- a/run_all_scratch_tests.sh +++ b/run_all_scratch_tests.sh @@ -1,17 +1,163 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -[[ -n "$MSYSTEM" ]] && DefaultMakeCmd=mingw32-make.exe || DefaultMakeCmd=make -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 +AllowedToFailFile="$Dir/.sis/ci_scratch_tests_allowed_to_fail.txt" +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} ListOnly=0 RunMake=1 -Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}} +SisUseColours=0 + + +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} + +# Reduces a program path to its (lowercase) name, without any directory or +# .exe suffix. +sis_program_stem() { + + local p="${1//\\//}" + + p="${p##*/}" + + case "$p" in + *.exe|*.EXE) p="${p%.*}" ;; + esac + + printf '%s' "$p" | tr '[:upper:]' '[:lower:]' +} + +# Succeeds if the program is named (by name or stem, case-insensitively) in +# the optional .sis/ci_scratch_tests_allowed_to_fail.txt file; blank lines +# and lines beginning with '#' are ignored. +sis_is_allowed_to_fail() { + + local name line + + [ -f "$AllowedToFailFile" ] || return 1 + + name=$(sis_program_stem "$1") + + while IFS= read -r line || [ -n "$line" ]; do + + line="${line//$'\r'/}" + + case "$line" in + ''|\#*) continue ;; + esac + + if [ "$name" = "$(sis_program_stem "$line")" ]; then + + return 0 + fi + done < "$AllowedToFailFile" + + return 1 +} # ########################################################## @@ -20,6 +166,10 @@ Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}} while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --list-only|-l) ListOnly=1 @@ -28,33 +178,40 @@ while [[ $# -gt 0 ]]; do RunMake=0 ;; - --verbosity) - - shift - Verbosity=$1 - ;; --help) [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF -Runs all (matching) performance-test and scratch-test programs +Runs all (matching) scratch-test programs -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + -l --list-only lists the target programs but does not execute them -M --no-make - does not execute CMake and make before running tests + does not execute a build before running programs + - --verbosity - specifies an explicit verbosity for the unit-test(s) + files: + + .sis/ci_scratch_tests_allowed_to_fail.txt + optional list of scratch-test programs (one name per line; blank + lines and lines beginning with '#' are ignored) that are allowed to + fail; such a program is still executed, but a non-zero exit is + reported as anticipated and neither stops the run nor affects the + exit status standard flags: @@ -68,7 +225,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -87,22 +244,28 @@ if [ $RunMake -ne 0 ]; then if [ $ListOnly -eq 0 ]; then - echo "Executing build of ${ProjectName} (via command \`$MakeCmd\`) and then running all scratch (and performance) test programs" + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build) and then running all scratch-test programs" - mkdir -p $CMakeDir || exit 1 + mkdir -p "$CMakeDir" || exit 1 - cd $CMakeDir + if [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - $MakeCmd - status=$? + >&2 echo "${ScriptPathClr}: '${CMakeDirClr}' is not configured; use prepare_cmake.sh first" - cd ->/dev/null + exit 1 + fi + + sis_cmake_build + status=$? fi else - if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ] || [ ! -d "$CMakeDir/CMakeFiles" ]; then + if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then + + >&2 echo "${ScriptPathClr}: cannot run in '--no-make' mode without a previous successful configure/build" - >&2 echo "$ScriptPath: cannot run in '--no-make' mode without a previous successful build step" + exit 1 fi fi @@ -110,43 +273,73 @@ if [ $status -eq 0 ]; then if [ $ListOnly -ne 0 ]; then - echo "Listing all ${ProjectName} scratch (and performance) test programs" + echo + echo "Listing all ${ProjectNameClr} scratch-test programs" else - echo "Running all ${ProjectName} scratch (and performance) test programs" + echo + echo "Running all ${ProjectNameClr} scratch-test programs" fi - for f in $(find $CMakeDir -type f '(' -name 'test_scratch*' -o -name 'test.scratch.*' -o -name 'test_performance*' -o -name 'test.performance.*' ')' -exec test -x {} \; -print) - do + NumPrograms=0 + + while IFS= read -r -d '' f; do + + case "$f" in + *.pdb|*.ilk|*.log|*.obj|*.o) + continue + ;; + esac + + NumPrograms=$((NumPrograms + 1)) + + fClr="${SisClr_Blue}${SisClr_Bold}${f}${SisClr_None}" if [ $ListOnly -ne 0 ]; then - echo "would execute $f:" + if sis_is_allowed_to_fail "$f"; then - continue - fi + echo "would execute ${fClr} (allowed to fail):" + else - if [ $Verbosity -ge 3 ]; then + echo "would execute ${fClr}:" + fi - echo + continue fi - if [ $Verbosity -ge 2 ]; then - echo "executing $f:" - fi + echo + echo "executing ${fClr}:" - if $f; then + if "$f"; then : else - status=$? + fStatus=$? + + if sis_is_allowed_to_fail "$f"; then + + echo "${SisClr_Yellow}${SisClr_Bold}anticipated failure${SisClr_None}: ${fClr} exited with status ${fStatus}; it is listed in .sis/ci_scratch_tests_allowed_to_fail.txt" + + continue + fi + + status=$fStatus + + break 1 fi - done + done < <(find "$CMakeDir" -type f \( -name 'test_scratch*' -o -name 'test.scratch.*' \) \( -perm -100 -o -name '*.exe' \) -print0 2>/dev/null | sort -z) + + if [ $NumPrograms -eq 0 ]; then + + echo "${ScriptPathClr}: found no scratch-test programs under '${CMakeDirClr}' (none found)" + + exit 0 + fi fi exit $status # ############################## end of file ############################# # - diff --git a/run_all_unit_tests.cmd b/run_all_unit_tests.cmd index b68c97e..18b040a 100644 --- a/run_all_unit_tests.cmd +++ b/run_all_unit_tests.cmd @@ -1,32 +1,29 @@ @echo off -SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION +SETLOCAL SET SCRIPT_DIRECTORY=%~dp0 SET SCRIPT_PATH_DOC=%~n0[%~x0] + IF DEFINED SIS_CMAKE_BUILD_DIR ( - SET "CMAKE_DIR=%SIS_CMAKE_BUILD_DIR%" + SET CMAKE_DIR=%SIS_CMAKE_BUILD_DIR% ) ELSE ( - SET "CMAKE_DIR=%SCRIPT_DIRECTORY%_build" + SET CMAKE_DIR=%SCRIPT_DIRECTORY%_build ) -SET ListOnly=0 -SET Verbose=0 -SET UnitOnly=0 -SET ComponentOnly=0 -SET status=0 - FOR %%a IN (%*) DO ( + IF /I {--help}=={%%a} ( + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( - type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ) ECHO ^ -Runs all ^(matching^) unit-test and/or component-test programs ^ +Runs all ^(matching^) unit-test programs ^ ^ @@ -38,41 +35,11 @@ Flags/options: ^ behaviour: ^ -^ - - -l ^ - - --list-only ^ - - lists the target programs but does not execute them ^ - -^ - - -M ^ - - --no-make ^ - - accepted for parity with the .sh script ^(build is not invoked^) ^ - ^ --unit-only ^ - runs only unit-test programs ^(test.unit.* / test_unit*^) ^ - -^ - - --component-only ^ - - runs only component-test programs ^(test.component.* / test_component*^) ^ - -^ - - -v ^ - - --verbose ^ - - lists each test program before executing it ^ + accepted for compatibility; this script always runs unit tests only ^ ^ @@ -86,41 +53,22 @@ Flags/options: ^ EXIT /B 0 - ) ELSE IF /I {-l}=={%%a} ( - SET ListOnly=1 - ) ELSE IF /I {--list-only}=={%%a} ( - SET ListOnly=1 - ) ELSE IF /I {-M}=={%%a} ( - REM no-op: this .cmd never invokes the build - ) ELSE IF /I {--no-make}=={%%a} ( - REM no-op: this .cmd never invokes the build ) ELSE IF /I {--unit-only}=={%%a} ( - SET UnitOnly=1 - ) ELSE IF /I {--component-only}=={%%a} ( - SET ComponentOnly=1 - ) ELSE IF /I {-v}=={%%a} ( - SET Verbose=1 - ) ELSE IF /I {--verbose}=={%%a} ( - SET Verbose=1 + + REM Benign: this script is already unit-only ) ELSE ( - ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 + + ECHO "%SCRIPT_DIRECTORY%: unrecognised argument '%%a'; use --help for usage" 1>&2 EXIT /B 1 ) ) -IF !UnitOnly! EQU 1 IF !ComponentOnly! EQU 1 ( - - ECHO %SCRIPT_PATH_DOC%: --unit-only and --component-only are mutually exclusive 1>&2 - - EXIT /B 1 -) - -IF NOT EXIST "%CMAKE_DIR%" ( +if NOT EXIST "%CMAKE_DIR%" ( - ECHO %SCRIPT_PATH_DOC%: CMake build directory '%CMAKE_DIR%' does not exist 1>&2 + ECHO "CMake build directory '%CMAKE_DIR%' does not exist" - EXIT /B 1 + EXIT /B 1 ) SET "ProjectName=" @@ -128,61 +76,19 @@ FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO IF NOT DEFINED ProjectName ( - ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 - - EXIT /B 1 -) - -IF !UnitOnly! EQU 1 ( - - SET "TestKindDescription=unit test" -) ELSE IF !ComponentOnly! EQU 1 ( - - SET "TestKindDescription=component test" -) ELSE ( + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 - SET "TestKindDescription=component and unit test" + EXIT /B 1 ) -IF !ListOnly! EQU 1 ( - - ECHO Listing all !ProjectName! !TestKindDescription! programs -) ELSE ( +ECHO Running all %ProjectName% unit-test programs - ECHO Running all !ProjectName! !TestKindDescription! programs -) +FOR /F "usebackq" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%" ^| FINDSTR /I test.*unit.*\.exe$`) DO ( -IF !UnitOnly! EQU 1 ( - - SET "FindPattern=test\.unit\..*\.exe$" -) ELSE IF !ComponentOnly! EQU 1 ( - - SET "FindPattern=test\.component\..*\.exe$" -) ELSE ( - - SET "FindPattern=test\.unit\..*\.exe$ test\.component\..*\.exe$" -) - -FOR /F "usebackq delims=" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%\*.exe" 2^>NUL ^| FINDSTR /I /R "!FindPattern!"`) DO ( - IF !ListOnly! EQU 1 ( - - ECHO would execute %%f: - ) ELSE ( - - IF !Verbose! EQU 1 ( - - ECHO executing %%f: - ) - - "%%f" - IF ERRORLEVEL 1 ( - - SET status=1 - - GOTO :done - ) - ) + ECHO . + ECHO executing %%f + %%f + IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL% ) -:done -EXIT /B !status! +ENDLOCAL diff --git a/run_all_unit_tests.sh b/run_all_unit_tests.sh index bed7973..301ccae 100755 --- a/run_all_unit_tests.sh +++ b/run_all_unit_tests.sh @@ -1,27 +1,132 @@ #! /bin/bash -ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) -Basename=$(basename "$ScriptPath") +# ########################################################## +# functions - 1 + +sis_cmake_is_truey() { + case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in + + 1|ok|on|true|yes|y) + + return 0 + ;; + *) + + return 1 + ;; + esac +} + + +# ########################################################## +# constants and variables + +Basename=$(basename "$0") +Dir=$(cd "$(dirname "$0")" && pwd) CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} -[[ -n "$MSYSTEM" ]] && DefaultMakeCmd=mingw32-make.exe || DefaultMakeCmd=make -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +ScriptPath=$0 +AlwaysUseColours=${SIS_CMAKE_ALWAYS_USE_COLOURS:-${SIS_ALWAYS_USE_COLOURS:-0}} ListOnly=0 RunMake=1 -UnitOnly=0 -ComponentOnly=0 +SisUseColours=0 Verbosity=${XTESTS_VERBOSITY:-${TEST_VERBOSITY:-3}} +# ########################################################## +# colours +# +# Enable when tput is available and either: +# - AlwaysUseColours is set (overrides NO_COLOR; may set TERM if +# empty/dumb), or +# - NO_COLOR is unset, stdout is a TTY, and TERM is not dumb (union of +# collect-c's "TERM set + TTY" and cstring's "TTY" — empty TERM on a +# TTY is OK). + +SisClr_Blue= +SisClr_Bold= +SisClr_Green= +SisClr_None= +SisClr_Red= +SisClr_Yellow= + +for arg in "$@"; do + + case $arg in + --always-use-colors|--always-use-colours|-A) + + AlwaysUseColours=1 + ;; + esac +done + +if command -v tput >/dev/null 2>&1; then + + if [ $AlwaysUseColours -ne 0 ]; then + + if [ -z "${TERM:-}" ] || [ "$TERM" = "dumb" ]; then + + TERM=xterm-256color + fi + + SisUseColours=1 + elif [ -z "${NO_COLOR:-}" ] && [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then + + SisUseColours=1 + fi +fi + +if [ $SisUseColours -ne 0 ]; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_Green=${FG_GREEN:-$(tput setaf 2)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Yellow=${FG_YELLOW:-$(tput setaf 3)} +fi + +CMakeDirClr="${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None}" +ProjectNameClr="${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None}" +ScriptPathClr="${SisClr_Blue}${SisClr_Bold}${ScriptPath}${SisClr_None}" + + +# ########################################################## +# functions - 2 + +sis_cmake_build() { + + local config="${SIS_CMAKE_CONFIG:-Release}" + local args=(--build "$CMakeDir") + if [ -f "$CMakeDir/CMakeCache.txt" ] && grep -q '^CMAKE_CONFIGURATION_TYPES:' "$CMakeDir/CMakeCache.txt" 2>/dev/null; then + + args+=(--config "$config") + fi + if [ "$#" -gt 0 ]; then + + local t + for t in "$@"; do + + args+=(--target "$t") + done + fi + + cmake "${args[@]}" +} + + # ########################################################## # command-line handling while [[ $# -gt 0 ]]; do case $1 in + --always-use-colors|--always-use-colours|-A) + + # AlwaysUseColours=1 - this is handled by the for loop above + ;; --list-only|-l) ListOnly=1 @@ -32,11 +137,7 @@ while [[ $# -gt 0 ]]; do ;; --unit-only) - UnitOnly=1 - ;; - --component-only) - - ComponentOnly=1 + # Benign: this script is already unit-only (aggregate / CI may pass it) ;; --verbosity) @@ -47,30 +148,32 @@ while [[ $# -gt 0 ]]; do [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" cat << EOF -Runs all (matching) unit-test and/or component-test programs +Runs all (matching) unit-test programs -$ScriptPath [ ... flags/options ... ] +${ScriptPath} [ ... flags/options ... ] Flags/options: behaviour: + -A + --always-use-colors + --always-use-colours + forces use of colours even when stdout is not a TTY + -l --list-only lists the target programs but does not execute them -M --no-make - does not execute CMake and make before running tests + does not execute a build before running programs --unit-only - runs only unit-test programs (test.unit.* / test_unit*) - - --component-only - runs only component-test programs (test.component.* / test_component*) + accepted for compatibility; this script always runs unit tests only --verbosity - specifies an explicit verbosity for the unit-test(s) + specifies an explicit verbosity, forwarded to each program standard flags: @@ -84,7 +187,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "${ScriptPathClr}: unrecognised argument '${SisClr_Red}${SisClr_Bold}$1${SisClr_None}'; use --help for usage" exit 1 ;; @@ -93,50 +196,36 @@ EOF shift done -if [ $UnitOnly -ne 0 ] && [ $ComponentOnly -ne 0 ]; then - - >&2 echo "$ScriptPath: --unit-only and --component-only are mutually exclusive" - - exit 1 -fi - # ########################################################## # main() status=0 -if [ $UnitOnly -ne 0 ]; then - - TestKindDescription='unit test' -elif [ $ComponentOnly -ne 0 ]; then - - TestKindDescription='component test' -else - - TestKindDescription='component and unit test' -fi - if [ $RunMake -ne 0 ]; then if [ $ListOnly -eq 0 ]; then - echo "Executing build of ${ProjectName} (via command \`$MakeCmd\`) and then running all ${TestKindDescription} programs" + echo + echo "Executing build of ${ProjectNameClr} (via cmake --build) and then running all unit-test programs" - mkdir -p $CMakeDir || exit 1 + mkdir -p "$CMakeDir" || exit 1 - cd $CMakeDir + if [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - $MakeCmd - status=$? + >&2 echo "${ScriptPathClr}: '${CMakeDirClr}' is not configured; use prepare_cmake.sh first" - cd ->/dev/null + exit 1 + fi + + sis_cmake_build + status=$? fi else - if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ] || [ ! -d "$CMakeDir/CMakeFiles" ]; then + if [ ! -d "$CMakeDir" ] || [ ! -f "$CMakeDir/CMakeCache.txt" ]; then - >&2 echo "$ScriptPath: cannot run in '--no-make' mode without a previous successful build step" + >&2 echo "${ScriptPathClr}: cannot run in '--no-make' mode without a previous successful configure/build" exit 1 fi @@ -146,29 +235,31 @@ if [ $status -eq 0 ]; then if [ $ListOnly -ne 0 ]; then - echo "Listing all ${ProjectName} ${TestKindDescription} programs" + echo + echo "Listing all ${ProjectNameClr} unit-test programs" else - echo "Running all ${ProjectName} ${TestKindDescription} programs" + echo + echo "Running all ${ProjectNameClr} unit-test programs" fi - if [ $UnitOnly -ne 0 ]; then + NumPrograms=0 - find_name_expr=( \( -name 'test_unit*' -o -name 'test.unit.*' \) ) - elif [ $ComponentOnly -ne 0 ]; then + while IFS= read -r -d '' f; do - find_name_expr=( \( -name 'test_component*' -o -name 'test.component.*' \) ) - else + case "$f" in + *.pdb|*.ilk|*.log|*.obj|*.o) + continue + ;; + esac - find_name_expr=( \( -name 'test_unit*' -o -name 'test.unit.*' -o -name 'test_component*' -o -name 'test.component.*' \) ) - fi + NumPrograms=$((NumPrograms + 1)) - for f in $(find "$CMakeDir" -type f "${find_name_expr[@]}" -exec test -x {} \; -print | sort) - do + fClr="${SisClr_Blue}${SisClr_Bold}${f}${SisClr_None}" if [ $ListOnly -ne 0 ]; then - echo "would execute $f:" + echo "would execute ${fClr}:" continue fi @@ -179,10 +270,10 @@ if [ $status -eq 0 ]; then fi if [ $Verbosity -ge 2 ]; then - echo "executing $f:" + echo "executing ${fClr}:" fi - if $f --verbosity=$Verbosity; then + if "$f" --verbosity="$Verbosity"; then : else @@ -191,7 +282,14 @@ if [ $status -eq 0 ]; then break 1 fi - done + done < <(find "$CMakeDir" -type f \( -name 'test_unit*' -o -name 'test.unit.*' \) \( -perm -100 -o -name '*.exe' \) -print0 2>/dev/null | sort -z) + + if [ $NumPrograms -eq 0 ]; then + + echo "${ScriptPathClr}: found no unit-test programs under '${CMakeDirClr}' (none found)" + + exit 0 + fi fi exit $status diff --git a/test/component/CMakeLists.txt b/test/component/CMakeLists.txt index bddd3d8..2656862 100644 --- a/test/component/CMakeLists.txt +++ b/test/component/CMakeLists.txt @@ -1,6 +1,4 @@ # SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -add_subdirectory(test.component.dirent) -add_subdirectory(test.component.glob) -add_subdirectory(test.component.unistd.mkdtemp) -add_subdirectory(test.component.unistd.mkstemp) -add_subdirectory(test.component.unistd.usleep) +add_subdirectory(dirent) +add_subdirectory(glob) +add_subdirectory(unistd) diff --git a/test/component/dirent/CMakeLists.txt b/test/component/dirent/CMakeLists.txt new file mode 100644 index 0000000..6d434f1 --- /dev/null +++ b/test/component/dirent/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.component.dirent entry.cpp) diff --git a/test/component/test.component.dirent/entry.cpp b/test/component/dirent/entry.cpp similarity index 99% rename from test/component/test.component.dirent/entry.cpp rename to test/component/dirent/entry.cpp index 99f8433..d999ca3 100644 --- a/test/component/test.component.dirent/entry.cpp +++ b/test/component/dirent/entry.cpp @@ -24,7 +24,7 @@ namespace { } // anonymous namespace -int main(int argc, char** argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/component/glob/CMakeLists.txt b/test/component/glob/CMakeLists.txt new file mode 100644 index 0000000..9f5cbfb --- /dev/null +++ b/test/component/glob/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.component.glob entry.cpp) diff --git a/test/component/test.component.glob/entry.cpp b/test/component/glob/entry.cpp similarity index 95% rename from test/component/test.component.glob/entry.cpp rename to test/component/glob/entry.cpp index aaafd31..0eb223e 100644 --- a/test/component/test.component.glob/entry.cpp +++ b/test/component/glob/entry.cpp @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.component.glob.cpp + * File: test/component/glob/entry.cpp * * Purpose: Unit-test of `glob()`. * * Created: 20th May 2012 - * Updated: 18th May 2025 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -70,12 +70,6 @@ namespace static void TEST_readdir_CWD_FOR_DIRECTORIES_AND_FILES_AND_DOTS(void); static void TEST_readdir_CWD_FOR_DIRECTORIES_AND_DOTS(void); static void TEST_readdir_HOMEDIR_FOR_DIRECTORIES_AND_FILES_AND_DOTS(void); - static void test_1_14(void); - static void test_1_15(void); - static void test_1_16(void); - static void test_1_17(void); - static void test_1_18(void); - static void test_1_19(void); #if 0 static int setup(void*); @@ -94,7 +88,7 @@ namespace * main() */ -int main(int argc, char **argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; @@ -141,12 +135,6 @@ int main(int argc, char **argv) XTESTS_RUN_CASE(TEST_readdir_CWD_FOR_DIRECTORIES_AND_FILES_AND_DOTS); XTESTS_RUN_CASE(TEST_readdir_CWD_FOR_DIRECTORIES_AND_DOTS); XTESTS_RUN_CASE(TEST_readdir_HOMEDIR_FOR_DIRECTORIES_AND_FILES_AND_DOTS); - XTESTS_RUN_CASE(test_1_14); - XTESTS_RUN_CASE(test_1_15); - XTESTS_RUN_CASE(test_1_16); - XTESTS_RUN_CASE(test_1_17); - XTESTS_RUN_CASE(test_1_18); - XTESTS_RUN_CASE(test_1_19); XTESTS_PRINT_RESULTS(); @@ -588,30 +576,6 @@ static void TEST_readdir_HOMEDIR_FOR_DIRECTORIES_AND_FILES_AND_DOTS() } } -static void test_1_14() -{ -} - -static void test_1_15() -{ -} - -static void test_1_16() -{ -} - -static void test_1_17() -{ -} - -static void test_1_18() -{ -} - -static void test_1_19() -{ -} - } // anonymous namespace diff --git a/test/component/test.component.glob/implicit_link.cpp b/test/component/glob/implicit_link.cpp similarity index 99% rename from test/component/test.component.glob/implicit_link.cpp rename to test/component/glob/implicit_link.cpp index cfd8483..4d621c5 100644 --- a/test/component/test.component.glob/implicit_link.cpp +++ b/test/component/glob/implicit_link.cpp @@ -7,3 +7,4 @@ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/component/test.component.dirent/CMakeLists.txt b/test/component/test.component.dirent/CMakeLists.txt deleted file mode 100644 index 9838280..0000000 --- a/test/component/test.component.dirent/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.component.dirent entry.cpp) diff --git a/test/component/test.component.glob/CMakeLists.txt b/test/component/test.component.glob/CMakeLists.txt deleted file mode 100644 index b99362f..0000000 --- a/test/component/test.component.glob/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.component.glob entry.cpp) diff --git a/test/component/test.component.unistd.usleep/CMakeLists.txt b/test/component/test.component.unistd.usleep/CMakeLists.txt deleted file mode 100644 index 76c9426..0000000 --- a/test/component/test.component.unistd.usleep/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.component.unistd.usleep entry.cpp) diff --git a/test/component/unistd/CMakeLists.txt b/test/component/unistd/CMakeLists.txt new file mode 100644 index 0000000..56acb62 --- /dev/null +++ b/test/component/unistd/CMakeLists.txt @@ -0,0 +1,4 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +add_subdirectory(mkdtemp) +add_subdirectory(mkstemp) +add_subdirectory(usleep) diff --git a/test/component/test.component.unistd.mkdtemp/CMakeLists.txt b/test/component/unistd/mkdtemp/CMakeLists.txt similarity index 100% rename from test/component/test.component.unistd.mkdtemp/CMakeLists.txt rename to test/component/unistd/mkdtemp/CMakeLists.txt diff --git a/test/component/test.component.unistd.mkdtemp/entry.c b/test/component/unistd/mkdtemp/entry.c similarity index 98% rename from test/component/test.component.unistd.mkdtemp/entry.c rename to test/component/unistd/mkdtemp/entry.c index 2c68ced..8340e50 100644 --- a/test/component/test.component.unistd.mkdtemp/entry.c +++ b/test/component/unistd/mkdtemp/entry.c @@ -13,7 +13,7 @@ #include -int main(int argc, char** argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/component/test.component.unistd.mkdtemp/implicit_link.c b/test/component/unistd/mkdtemp/implicit_link.c similarity index 99% rename from test/component/test.component.unistd.mkdtemp/implicit_link.c rename to test/component/unistd/mkdtemp/implicit_link.c index cfd8483..4d621c5 100644 --- a/test/component/test.component.unistd.mkdtemp/implicit_link.c +++ b/test/component/unistd/mkdtemp/implicit_link.c @@ -7,3 +7,4 @@ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/component/test.component.unistd.mkstemp/CMakeLists.txt b/test/component/unistd/mkstemp/CMakeLists.txt similarity index 100% rename from test/component/test.component.unistd.mkstemp/CMakeLists.txt rename to test/component/unistd/mkstemp/CMakeLists.txt diff --git a/test/component/test.component.unistd.mkstemp/entry.c b/test/component/unistd/mkstemp/entry.c similarity index 98% rename from test/component/test.component.unistd.mkstemp/entry.c rename to test/component/unistd/mkstemp/entry.c index 8b1574c..12bd049 100644 --- a/test/component/test.component.unistd.mkstemp/entry.c +++ b/test/component/unistd/mkstemp/entry.c @@ -13,7 +13,7 @@ #include -int main(int argc, char** argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/component/test.component.unistd.mkstemp/implicit_link.c b/test/component/unistd/mkstemp/implicit_link.c similarity index 99% rename from test/component/test.component.unistd.mkstemp/implicit_link.c rename to test/component/unistd/mkstemp/implicit_link.c index cfd8483..4d621c5 100644 --- a/test/component/test.component.unistd.mkstemp/implicit_link.c +++ b/test/component/unistd/mkstemp/implicit_link.c @@ -7,3 +7,4 @@ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/component/unistd/usleep/CMakeLists.txt b/test/component/unistd/usleep/CMakeLists.txt new file mode 100644 index 0000000..ca80987 --- /dev/null +++ b/test/component/unistd/usleep/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.component.unistd.usleep entry.cpp) diff --git a/test/component/test.component.unistd.usleep/entry.cpp b/test/component/unistd/usleep/entry.cpp similarity index 96% rename from test/component/test.component.unistd.usleep/entry.cpp rename to test/component/unistd/usleep/entry.cpp index 1aabd2a..a048138 100644 --- a/test/component/test.component.unistd.usleep/entry.cpp +++ b/test/component/unistd/usleep/entry.cpp @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.component.unistd.usleep/entry.cpp + * File: test/component/unistd/usleep/entry.cpp * * Purpose: Unit-test of `usleep()`. * * Created: 29th November 2024 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -39,7 +39,7 @@ namespace * main() */ -int main(int argc, char **argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/scratch/CMakeLists.txt b/test/scratch/CMakeLists.txt index 377d3a2..ac2d179 100644 --- a/test/scratch/CMakeLists.txt +++ b/test/scratch/CMakeLists.txt @@ -1,13 +1,14 @@ -add_subdirectory(test.scratch.dlfcn) +add_subdirectory(dlfcn) #[====[ -add_subdirectory(test.scratch.fnmatch) +add_subdirectory(fnmatch) ]====] -add_subdirectory(test.scratch.getrusage) -add_subdirectory(test.scratch.link) +add_subdirectory(getrusage) +add_subdirectory(link) #[====[ -add_subdirectory(test.scratch.mmap) +add_subdirectory(mmap) ]====] -add_subdirectory(test.scratch.setenv) -add_subdirectory(test.scratch.syslog) -add_subdirectory(test.scratch.uio) +add_subdirectory(setenv) +add_subdirectory(syslog) +add_subdirectory(uio) +add_subdirectory(versions) diff --git a/test/scratch/dlfcn/CMakeLists.txt b/test/scratch/dlfcn/CMakeLists.txt new file mode 100644 index 0000000..84522aa --- /dev/null +++ b/test/scratch/dlfcn/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.dlfcn main.c) diff --git a/test/scratch/test.scratch.dlfcn/test.scratch.dlfcn.c b/test/scratch/dlfcn/main.c similarity index 97% rename from test/scratch/test.scratch.dlfcn/test.scratch.dlfcn.c rename to test/scratch/dlfcn/main.c index 2770d7c..5f75e60 100644 --- a/test/scratch/test.scratch.dlfcn/test.scratch.dlfcn.c +++ b/test/scratch/dlfcn/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.dlfcn.c + * File: test/scratch/dlfcn/main.c * * Purpose: Unit-test of `dlopen()`, `dlsym()`, `dlclose()`. * * Created: 1st January 2004 - * Updated: 4th August 2026 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -26,7 +26,8 @@ * constants */ -/* Defaults so bare invocation (e.g. run_all_scratch_tests.sh) is a useful smoke. */ +/* Defaults so bare invocation (e.g. run_all_scratch_tests.sh) is a useful + * smoke. */ #define TEST_SCRATCH_DLFCN_DEFAULT_MODULE "kernel32.dll" #define TEST_SCRATCH_DLFCN_DEFAULT_SYMBOL "GetCurrentProcessId" @@ -125,3 +126,4 @@ int main(int argc, char *argv[]) /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/scratch/fnmatch/CMakeLists.txt b/test/scratch/fnmatch/CMakeLists.txt new file mode 100644 index 0000000..8ced370 --- /dev/null +++ b/test/scratch/fnmatch/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.fnmatch main.c) diff --git a/test/scratch/test.scratch.fnmatch/test.scratch.fnmatch.c b/test/scratch/fnmatch/main.c similarity index 96% rename from test/scratch/test.scratch.fnmatch/test.scratch.fnmatch.c rename to test/scratch/fnmatch/main.c index 4a06c0b..be8cc97 100644 --- a/test/scratch/test.scratch.fnmatch/test.scratch.fnmatch.c +++ b/test/scratch/fnmatch/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.fnmatch.c + * File: test/scratch/fnmatch/main.c * * Purpose: Unit-test of `fnmatch()`. * * Created: 24th April 2006 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ diff --git a/test/scratch/getrusage/CMakeLists.txt b/test/scratch/getrusage/CMakeLists.txt new file mode 100644 index 0000000..e30fa5f --- /dev/null +++ b/test/scratch/getrusage/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.getrusage main.c) diff --git a/test/scratch/test.scratch.getrusage/test.scratch.getrusage.c b/test/scratch/getrusage/main.c similarity index 95% rename from test/scratch/test.scratch.getrusage/test.scratch.getrusage.c rename to test/scratch/getrusage/main.c index 78cf3c2..56177af 100644 --- a/test/scratch/test.scratch.getrusage/test.scratch.getrusage.c +++ b/test/scratch/getrusage/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.getrusage.c + * File: test/scratch/getrusage/main.c * * Purpose: Unit-test of `getrusage()`. * * Created: 9th June 2006 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ diff --git a/test/scratch/link/CMakeLists.txt b/test/scratch/link/CMakeLists.txt new file mode 100644 index 0000000..3415a2f --- /dev/null +++ b/test/scratch/link/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.link main.c) diff --git a/test/scratch/test.scratch.link/test.scratch.link.c b/test/scratch/link/main.c similarity index 97% rename from test/scratch/test.scratch.link/test.scratch.link.c rename to test/scratch/link/main.c index 5c30370..f813722 100644 --- a/test/scratch/test.scratch.link/test.scratch.link.c +++ b/test/scratch/link/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.link.c + * File: test/scratch/link/main.c * * Purpose: Unit-test of `link()`. * * Created: 2nd September 2005 - * Updated: 4th August 2026 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ diff --git a/test/scratch/mmap/CMakeLists.txt b/test/scratch/mmap/CMakeLists.txt new file mode 100644 index 0000000..50c116b --- /dev/null +++ b/test/scratch/mmap/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.mmap main.c) diff --git a/test/scratch/test.scratch.mmap/test.scratch.mmap.c b/test/scratch/mmap/main.c similarity index 97% rename from test/scratch/test.scratch.mmap/test.scratch.mmap.c rename to test/scratch/mmap/main.c index 83211ef..7cd183c 100644 --- a/test/scratch/test.scratch.mmap/test.scratch.mmap.c +++ b/test/scratch/mmap/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.mmap.cpp + * File: test/scratch/mmap/main.c * * Purpose: Unit-test of `mmap()`, `munmap()`. * * Created: 18th December 2003 - * Updated: 1st May 2025 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ diff --git a/test/scratch/setenv/CMakeLists.txt b/test/scratch/setenv/CMakeLists.txt new file mode 100644 index 0000000..8aea02f --- /dev/null +++ b/test/scratch/setenv/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.setenv main.c) diff --git a/test/scratch/test.scratch.setenv/test.scratch.setenv.c b/test/scratch/setenv/main.c similarity index 96% rename from test/scratch/test.scratch.setenv/test.scratch.setenv.c rename to test/scratch/setenv/main.c index e818f0b..f93bcfd 100644 --- a/test/scratch/test.scratch.setenv/test.scratch.setenv.c +++ b/test/scratch/setenv/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.setenv.c + * File: test/scratch/setenv/main.c * * Purpose: Unit-test of `setenv()`. * * Created: 9th December 2005 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ diff --git a/test/scratch/test.scratch.syslog/CMakeLists.txt b/test/scratch/syslog/CMakeLists.txt similarity index 68% rename from test/scratch/test.scratch.syslog/CMakeLists.txt rename to test/scratch/syslog/CMakeLists.txt index 1e91427..7a15a6f 100644 --- a/test/scratch/test.scratch.syslog/CMakeLists.txt +++ b/test/scratch/syslog/CMakeLists.txt @@ -2,4 +2,4 @@ list(APPEND X_GCC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED unused-variable) #]====] list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.syslog test.scratch.syslog.c) +define_example_program(test.scratch.syslog main.c) diff --git a/test/scratch/test.scratch.syslog/test.scratch.syslog.c b/test/scratch/syslog/main.c similarity index 92% rename from test/scratch/test.scratch.syslog/test.scratch.syslog.c rename to test/scratch/syslog/main.c index fc2ee99..09bf9b4 100644 --- a/test/scratch/test.scratch.syslog/test.scratch.syslog.c +++ b/test/scratch/syslog/main.c @@ -1,12 +1,12 @@ -/* ////////////////////////////////////////////////////////////////////////// - * File: test.scratch.syslog.c +/* ///////////////////////////////////////////////////////////////////////// + * File: test/scratch/syslog/main.c * * Purpose: Unit-test of `syslog()`. * * Created: 1st October 2006 - * Updated: 29th November 2024 + * Updated: 9th October 2026 * - * /////////////////////////////////////////////////////////////////////// */ + * ////////////////////////////////////////////////////////////////////// */ /* ///////////////////////////////////////////////////////////////////////// diff --git a/test/scratch/test.scratch.dlfcn/CMakeLists.txt b/test/scratch/test.scratch.dlfcn/CMakeLists.txt deleted file mode 100644 index 0f8f30e..0000000 --- a/test/scratch/test.scratch.dlfcn/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.dlfcn test.scratch.dlfcn.c) diff --git a/test/scratch/test.scratch.fnmatch/CMakeLists.txt b/test/scratch/test.scratch.fnmatch/CMakeLists.txt deleted file mode 100644 index cffb88e..0000000 --- a/test/scratch/test.scratch.fnmatch/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.fnmatch test.scratch.fnmatch.c) diff --git a/test/scratch/test.scratch.getrusage/CMakeLists.txt b/test/scratch/test.scratch.getrusage/CMakeLists.txt deleted file mode 100644 index bee859d..0000000 --- a/test/scratch/test.scratch.getrusage/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.getrusage test.scratch.getrusage.c) diff --git a/test/scratch/test.scratch.link/CMakeLists.txt b/test/scratch/test.scratch.link/CMakeLists.txt deleted file mode 100644 index 88070cd..0000000 --- a/test/scratch/test.scratch.link/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.link test.scratch.link.c) diff --git a/test/scratch/test.scratch.mmap/CMakeLists.txt b/test/scratch/test.scratch.mmap/CMakeLists.txt deleted file mode 100644 index 9aa534f..0000000 --- a/test/scratch/test.scratch.mmap/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.mmap test.scratch.mmap.c) diff --git a/test/scratch/test.scratch.setenv/CMakeLists.txt b/test/scratch/test.scratch.setenv/CMakeLists.txt deleted file mode 100644 index 88e0629..0000000 --- a/test/scratch/test.scratch.setenv/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.setenv test.scratch.setenv.c) diff --git a/test/scratch/test.scratch.uio/CMakeLists.txt b/test/scratch/test.scratch.uio/CMakeLists.txt deleted file mode 100644 index 25461de..0000000 --- a/test/scratch/test.scratch.uio/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) -define_example_program(test.scratch.uio test.scratch.uio.c) diff --git a/test/scratch/uio/CMakeLists.txt b/test/scratch/uio/CMakeLists.txt new file mode 100644 index 0000000..e950176 --- /dev/null +++ b/test/scratch/uio/CMakeLists.txt @@ -0,0 +1,2 @@ +list(APPEND X_MSVC_CUSTOM_WARNINGS_TO_BE_SUPPRESSED 4996) +define_example_program(test.scratch.uio main.c) diff --git a/test/scratch/test.scratch.uio/test.scratch.uio.c b/test/scratch/uio/main.c similarity index 96% rename from test/scratch/test.scratch.uio/test.scratch.uio.c rename to test/scratch/uio/main.c index 31ec5ab..e95ab5a 100644 --- a/test/scratch/test.scratch.uio/test.scratch.uio.c +++ b/test/scratch/uio/main.c @@ -1,10 +1,10 @@ /* ///////////////////////////////////////////////////////////////////////// - * File: test.scratch.uio.c + * File: test/scratch/uio/main.c * * Purpose: Unit-test of `uio()`. * * Created: 19th September 2005 - * Updated: 4th August 2026 + * Updated: 9th October 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -45,7 +45,8 @@ static int main_(int argc, char* argv[]) { case 1: - /* Bare invocation (e.g. run_all_scratch_tests.sh): smoke against self. */ + /* Bare invocation (e.g. run_all_scratch_tests.sh): smoke against + * self. */ fileName = argv[0]; break; case 2: @@ -109,3 +110,4 @@ int main(int argc, char *argv[]) /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/scratch/versions/CMakeLists.txt b/test/scratch/versions/CMakeLists.txt new file mode 100644 index 0000000..94022e4 --- /dev/null +++ b/test/scratch/versions/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_example_program(test.scratch.versions main.c) diff --git a/test/scratch/versions/main.c b/test/scratch/versions/main.c new file mode 100644 index 0000000..ec5bb8a --- /dev/null +++ b/test/scratch/versions/main.c @@ -0,0 +1,61 @@ +/* ///////////////////////////////////////////////////////////////////////// + * File: test/scratch/versions/main.c + * + * Purpose: Prints UNIXem composite version. + * + * Created: 17th September 2026 + * Updated: 9th October 2026 + * + * ////////////////////////////////////////////////////////////////////// */ + + +#include + +#include +#include + + +#define PROGRAM_NAME "versions" + + +static void +version( + FILE* stm +, char const* prefix +, char const* libname +, char const* macroname +, unsigned libver +) +{ + fprintf( + stm + , "%s%s: v%u.%u.%u.%u (%s = 0x%08x)\n" + , prefix + , libname + , (libver >> 24) & 0xff + , (libver >> 16) & 0xff + , (libver >> 8) & 0xff + , (libver >> 0) & 0xff + , macroname + , libver + ); +} + + +int main(int argc, char* argv[]) +{ + ((void)&argc); + ((void)&argv); + + { + unsigned const libver = (unsigned)UNIXEM_VER; + + version(stdout, "", "UNIXem", "UNIXEM_VER", libver); + } + + return EXIT_SUCCESS; +} + + +/* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 664a986..d076d36 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,6 +1,4 @@ # SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten -add_subdirectory(test.unit.unistd.gethostname) -add_subdirectory(test.unit.unistd.getpid) -add_subdirectory(test.unit.unistd.pathconf) -add_subdirectory(test.unit.util.fs) -add_subdirectory(test.unit.util.str) +add_subdirectory(unistd) +add_subdirectory(util.fs) +add_subdirectory(util.str) diff --git a/test/unit/test.unit.unistd.gethostname/CMakeLists.txt b/test/unit/test.unit.unistd.gethostname/CMakeLists.txt deleted file mode 100644 index 73f6cde..0000000 --- a/test/unit/test.unit.unistd.gethostname/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.unit.unistd.gethostname entry.c) diff --git a/test/unit/test.unit.unistd.getpid/CMakeLists.txt b/test/unit/test.unit.unistd.getpid/CMakeLists.txt deleted file mode 100644 index 0249910..0000000 --- a/test/unit/test.unit.unistd.getpid/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.unit.unistd.getpid entry.c) diff --git a/test/unit/test.unit.unistd.pathconf/CMakeLists.txt b/test/unit/test.unit.unistd.pathconf/CMakeLists.txt deleted file mode 100644 index 8cf40cc..0000000 --- a/test/unit/test.unit.unistd.pathconf/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.unit.unistd.pathconf entry.c) diff --git a/test/unit/test.unit.util.str/CMakeLists.txt b/test/unit/test.unit.util.str/CMakeLists.txt deleted file mode 100644 index b47517b..0000000 --- a/test/unit/test.unit.util.str/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# SIS:AUTO_GENERATED: Do not edit! -define_automated_test_program(test.unit.util.str entry.c) diff --git a/test/unit/unistd/CMakeLists.txt b/test/unit/unistd/CMakeLists.txt new file mode 100644 index 0000000..7c5d8b3 --- /dev/null +++ b/test/unit/unistd/CMakeLists.txt @@ -0,0 +1,4 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +add_subdirectory(gethostname) +add_subdirectory(getpid) +add_subdirectory(pathconf) diff --git a/test/unit/unistd/gethostname/CMakeLists.txt b/test/unit/unistd/gethostname/CMakeLists.txt new file mode 100644 index 0000000..be636ee --- /dev/null +++ b/test/unit/unistd/gethostname/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.unit.unistd.gethostname entry.c) diff --git a/test/unit/test.unit.unistd.gethostname/entry.c b/test/unit/unistd/gethostname/entry.c similarity index 96% rename from test/unit/test.unit.unistd.gethostname/entry.c rename to test/unit/unistd/gethostname/entry.c index cc51966..759d958 100644 --- a/test/unit/test.unit.unistd.gethostname/entry.c +++ b/test/unit/unistd/gethostname/entry.c @@ -7,7 +7,7 @@ #include -int main(int argc, char** argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/unit/test.unit.unistd.gethostname/implicit_link.c b/test/unit/unistd/gethostname/implicit_link.c similarity index 99% rename from test/unit/test.unit.unistd.gethostname/implicit_link.c rename to test/unit/unistd/gethostname/implicit_link.c index cfd8483..4d621c5 100644 --- a/test/unit/test.unit.unistd.gethostname/implicit_link.c +++ b/test/unit/unistd/gethostname/implicit_link.c @@ -7,3 +7,4 @@ /* ///////////////////////////// end of file //////////////////////////// */ + diff --git a/test/unit/unistd/getpid/CMakeLists.txt b/test/unit/unistd/getpid/CMakeLists.txt new file mode 100644 index 0000000..e740e32 --- /dev/null +++ b/test/unit/unistd/getpid/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.unit.unistd.getpid entry.c) diff --git a/test/unit/test.unit.unistd.getpid/entry.c b/test/unit/unistd/getpid/entry.c similarity index 95% rename from test/unit/test.unit.unistd.getpid/entry.c rename to test/unit/unistd/getpid/entry.c index 7b82132..58520cc 100644 --- a/test/unit/test.unit.unistd.getpid/entry.c +++ b/test/unit/unistd/getpid/entry.c @@ -7,7 +7,7 @@ #include -int main(int argc, char** argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/unit/unistd/pathconf/CMakeLists.txt b/test/unit/unistd/pathconf/CMakeLists.txt new file mode 100644 index 0000000..67a097f --- /dev/null +++ b/test/unit/unistd/pathconf/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.unit.unistd.pathconf entry.c) diff --git a/test/unit/test.unit.unistd.pathconf/entry.c b/test/unit/unistd/pathconf/entry.c similarity index 98% rename from test/unit/test.unit.unistd.pathconf/entry.c rename to test/unit/unistd/pathconf/entry.c index f6871e4..2ddfcb1 100644 --- a/test/unit/test.unit.unistd.pathconf/entry.c +++ b/test/unit/unistd/pathconf/entry.c @@ -8,7 +8,7 @@ #include -int main(int argc, char** argv) +int main(int argc, char* argv[]) { int retCode = EXIT_SUCCESS; int verbosity = 2; diff --git a/test/unit/test.unit.util.fs/CMakeLists.txt b/test/unit/util.fs/CMakeLists.txt similarity index 100% rename from test/unit/test.unit.util.fs/CMakeLists.txt rename to test/unit/util.fs/CMakeLists.txt diff --git a/test/unit/test.unit.util.fs/entry.cpp b/test/unit/util.fs/entry.cpp similarity index 100% rename from test/unit/test.unit.util.fs/entry.cpp rename to test/unit/util.fs/entry.cpp diff --git a/test/unit/util.str/CMakeLists.txt b/test/unit/util.str/CMakeLists.txt new file mode 100644 index 0000000..1fe14f6 --- /dev/null +++ b/test/unit/util.str/CMakeLists.txt @@ -0,0 +1,2 @@ +# SIS:AUTO_GENERATED: Remove this line if you edit the file, otherwise it will be overwritten +define_automated_test_program(test.unit.util.str entry.c) diff --git a/test/unit/test.unit.util.str/entry.c b/test/unit/util.str/entry.c similarity index 100% rename from test/unit/test.unit.util.str/entry.c rename to test/unit/util.str/entry.c