From e2b135482d2725b0982685add5148636b149b213 Mon Sep 17 00:00:00 2001 From: Matt Wilson <152443343+mwsis@users.noreply.github.com> Date: Wed, 5 Aug 2026 18:23:47 +1000 Subject: [PATCH 01/16] Boilerplate, CI (#2) * .gitattributes * .vimrc * chore: VS Code settings * chore: added **NEWS.md** * chore: markdown files structure * chore: added **README.md** badges * chore: added boilerplate files * chore: .sis abstraction of the helper scripts * LICENSE * .gitignore * chore * fix: CMake dependencies * chore: added (empty) makefile * chore: canonicalising helper scripts * chore: canonicalising helper scripts * chore: canonicalising CMakeLists.txt * chore: canonicalising CMakeLists.txt * feature: CMakeLists.txt * chore: project files * feature: added GitHub Actions CI * fix * fix * fix * final touches --- .gitattributes | 17 +++ .github/workflows/ci-cell.yml | 268 ++++++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 39 +++++ .gitignore | 147 ++++++++++++++++++- .sis/project_name.txt | 1 + .sis/script_info_lines.txt | 2 + .vimrc | 70 +++++++++ .vscode/settings.json | 49 ++++++- AUTHORS.md | 18 +++ CHANGES.md | 20 +++ CMakeLists.txt | 141 +++++++++++++++--- INSTALL.md | 6 + LICENSE | 31 ++++ NEWS.md | 10 ++ README.md | 74 ++++++++++ TODO.md | 10 ++ build_cmake.sh | 130 +++++++++++++++++ clean_cmake.sh | 92 ++++++++++++ cmake/BuildType.cmake | 59 ++++++++ prepare_cmake.sh | 186 +++++++++++++++++++++++ realpath.cpp | 4 +- remove_cmake_artefacts.sh | 151 +++++++++++++++++++ run_all_unit_tests.cmd | 141 ++++++++++++++++++ 23 files changed, 1634 insertions(+), 32 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/ci-cell.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .sis/project_name.txt create mode 100644 .sis/script_info_lines.txt create mode 100644 .vimrc create mode 100644 AUTHORS.md create mode 100644 CHANGES.md create mode 100644 INSTALL.md create mode 100644 LICENSE create mode 100644 NEWS.md create mode 100644 README.md create mode 100644 TODO.md create mode 100755 build_cmake.sh create mode 100755 clean_cmake.sh create mode 100644 cmake/BuildType.cmake create mode 100755 prepare_cmake.sh create mode 100755 remove_cmake_artefacts.sh create mode 100644 run_all_unit_tests.cmd diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a9c5470 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +*.c linguist-language=C +*.cmake linguist-vendored +*.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-vendored +makefile linguist-detectable=false diff --git a/.github/workflows/ci-cell.yml b/.github/workflows/ci-cell.yml new file mode 100644 index 0000000..c17166d --- /dev/null +++ b/.github/workflows/ci-cell.yml @@ -0,0 +1,268 @@ +name: CI cell + +on: + workflow_call: + inputs: + cell-id: + required: true + type: string + os: + required: true + type: string + c-compiler: + required: true + type: string + cpp-compiler: + required: true + type: string + build-type: + required: false + type: string + default: Release + with-clasp: + required: false + type: boolean + default: true + with-cstring: + required: false + type: boolean + default: false + with-test-deps: + required: false + type: boolean + default: true + run-tests: + required: false + type: boolean + default: true + +jobs: + cell: + name: ${{ inputs.cell-id }} + runs-on: ${{ inputs.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Install Clang (Ubuntu) + if: runner.os == 'Linux' && inputs.c-compiler == 'clang' + run: sudo apt-get update && sudo apt-get install -y clang + + - name: Setup MSYS2 MinGW + if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: >- + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-cmake + mingw-w64-x86_64-make + + - name: Install dependencies + shell: bash + run: | + set -euxo pipefail + + DEPS="${RUNNER_TEMP}/sis-deps" + mkdir -p "$DEPS" + echo "SIS_DEPS=$DEPS" >> "$GITHUB_ENV" + + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + + cmake_configure() { + local src="$1" bld="$2" + shift 2 + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -S "$src" -B "$bld" \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + "$@" + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + cmake -S "$src" -B "$bld" -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + "$@" + else + cmake -S "$src" -B "$bld" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$DEPS" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + "$@" + fi + } + + cmake_build_install() { + local bld="$1" + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake --build "$bld" --config "${{ inputs.build-type }}" --parallel + cmake --install "$bld" --config "${{ inputs.build-type }}" + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + cmake --build "$bld" --parallel 2 + cmake --install "$bld" + else + cmake --build "$bld" --parallel + cmake --install "$bld" + fi + } + + # STLSoft (required) + STLSRC="${RUNNER_TEMP}/stlsoft-src" + STLBUILD="${RUNNER_TEMP}/stlsoft-build" + git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" + cmake_configure "$STLSRC" "$STLBUILD" + cmake_build_install "$STLBUILD" + + # Catch2 v2 + xTests (test-only) + if [ "${{ inputs.with-test-deps }}" = "true" ]; then + CATCHSRC="${RUNNER_TEMP}/catch2-src" + CATCHBUILD="${RUNNER_TEMP}/catch2-build" + git clone --depth 1 --branch v2.x https://github.com/catchorg/Catch2 "$CATCHSRC" + cmake_configure "$CATCHSRC" "$CATCHBUILD" \ + -DCATCH_BUILD_TESTING=OFF \ + -DCATCH_ENABLE_WERROR=OFF \ + -DCATCH_INSTALL_DOCS=OFF + cmake_build_install "$CATCHBUILD" + + XTSRC="${RUNNER_TEMP}/xtests-src" + XTBUILD="${RUNNER_TEMP}/xtests-build" + git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" + cmake_configure "$XTSRC" "$XTBUILD" -DNO_SHWILD=TRUE + cmake_build_install "$XTBUILD" + fi + + # CLASP + if [ "${{ inputs.with-clasp }}" = "true" ]; then + CLASPSRC="${RUNNER_TEMP}/clasp-src" + CLASPBUILD="${RUNNER_TEMP}/clasp-build" + git clone --depth 1 https://github.com/synesissoftware/CLASP "$CLASPSRC" + cmake_configure "$CLASPSRC" "$CLASPBUILD" + cmake_build_install "$CLASPBUILD" + fi + + # cstring + if [ "${{ inputs.with-cstring }}" = "true" ]; then + CSTRSRC="${RUNNER_TEMP}/cstring-src" + CSTRBUILD="${RUNNER_TEMP}/cstring-build" + git clone --depth 1 https://github.com/synesissoftware/cstring "$CSTRSRC" + cmake_configure "$CSTRSRC" "$CSTRBUILD" + cmake_build_install "$CSTRBUILD" + fi + + - name: Configure + shell: bash + run: | + set -euo pipefail + DEPS="${{ env.SIS_DEPS }}" + + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + + # Bare `cstring` link (rstrip) needs include/lib search paths beyond + # find_package(CLASP)-style imported targets. + if [ "${{ inputs.with-cstring }}" = "true" ]; then + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + export INCLUDE="$(cygpath -w "$DEPS/include");${INCLUDE:-}" + export LIB="$(cygpath -w "$DEPS/lib");${LIB:-}" + else + export CPATH="$DEPS/include${CPATH:+:$CPATH}" + export LIBRARY_PATH="$DEPS/lib${LIBRARY_PATH:+:$LIBRARY_PATH}" + fi + fi + + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -B build -S . \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=ON + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + cmake -B build -G "MinGW Makefiles" \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER=gcc \ + -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=ON + else + cmake -B build -S . \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_PREFIX_PATH="$DEPS" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=ON + fi + + - name: Build + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + if [ "${{ inputs.with-cstring }}" = "true" ]; then + DEPS="${{ env.SIS_DEPS }}" + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + export INCLUDE="$(cygpath -w "$DEPS/include");${INCLUDE:-}" + export LIB="$(cygpath -w "$DEPS/lib");${LIB:-}" + else + export CPATH="$DEPS/include${CPATH:+:$CPATH}" + export LIBRARY_PATH="$DEPS/lib${LIBRARY_PATH:+:$LIBRARY_PATH}" + fi + fi + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake --build build --config "${{ inputs.build-type }}" --parallel + elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + cmake --build build --parallel 2 + else + cmake --build build --parallel + fi + + - name: Run tests + if: inputs.run-tests + shell: bash + run: | + set -euo pipefail + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + export SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" + if [ "${{ runner.os }}" = "Windows" ]; then + cmd.exe //c "run_all_unit_tests.cmd -M -v" + else + ./run_all_unit_tests.sh -M -v + fi + + - name: Install and verify + shell: bash + run: | + set -euo pipefail + PREFIX="${RUNNER_TEMP}/install-prefix" + PROJECT="$(tr -d '[:space:]' < .sis/project_name.txt)" + if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake --install build --config "${{ inputs.build-type }}" --prefix "$PREFIX" + else + cmake --install build --prefix "$PREFIX" + fi + if [ "${{ inputs.c-compiler }}" = "cl" ] || [ "${{ inputs.c-compiler }}" = "mingw" ]; then + test -f "$PREFIX/bin/${PROJECT}.exe" + else + test -x "$PREFIX/bin/${PROJECT}" + fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..05d1e48 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + branches: + - master + - boilerplate + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + cell: + name: CI (${{ matrix.id }}) + strategy: + fail-fast: false + matrix: + include: + - id: windows-cl + os: windows-latest + c_compiler: cl + cpp_compiler: cl + - id: windows-mingw + os: windows-latest + c_compiler: mingw + cpp_compiler: g++ + uses: ./.github/workflows/ci-cell.yml + with: + cell-id: ${{ matrix.id }} + os: ${{ matrix.os }} + c-compiler: ${{ matrix.c_compiler }} + cpp-compiler: ${{ matrix.cpp_compiler }} + build-type: Release + with-clasp: false + with-cstring: false + with-test-deps: false + run-tests: true diff --git a/.gitignore b/.gitignore index 49613f7..f369e23 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,152 @@ -/_build +# directories (by name) -*.*~ +/.svn/ +/.vs/ + +/_build/ +/_internal/ + +/bin/ +/doc/ +/include/ +/lib/ +/node_modules/ + +/include/b64/ +/include/shwild/ +/include/xcontract/ +/include/xcover/ +/include/xtests/ + +/src/b64/ +/src/shwild/ +/src/xcontract/ +/src/xcover/ +/src/xtests/ + +Debug Multithreaded DLL/ +Debug Multithreaded Dll/ +Debug Multithreaded pseudoUNIX/ +Debug Multithreaded pseudoUnix/ +Debug Multithreaded/ +Debug/ +DebugDLLUNIX/ +DebugDll/ +DebugMTDLL/ +DebugMt/ +DebugNox/ +DebugUNIX/ +DebugUnix/ +Release Multithreaded DLL/ +Release Multithreaded Dll/ +Release Multithreaded pseudoUNIX/ +Release Multithreaded pseudoUnix/ +Release Multithreaded/ +Release/ +ReleaseDLLUNIX/ +ReleaseDll/ +ReleaseMTDLL/ +ReleaseMt/ +ReleaseNox/ +ReleaseUnix/ +UDebug/ +UDebugMt/ +URelease/ +UReleaseMt/ +Unicode Debug Multithreaded DLL/ +Unicode Debug Multithreaded Dll/ +Unicode Debug Multithreaded/ +Unicode Debug/ +Unicode Release Multithreaded DLL/ +Unicode Release Multithreaded Dll/ +Unicode Release Multithreaded/ +Unicode Release/ + +Win32/ +ipch/ +x64/ + + +# directories (by pattern) + + +# files (by name) + +.DS_Store +.ruby-version +.svnignore +.svnignore-at-root +.update_deps + +list_changes.cmd +logging-bailout.txt +prepare.cmd +sh.exe.stackdump +update_deps.cmd + +build/makefile.tmpl +build/makefile.tools.xml + +realpath +realpath_test + + +# files (by pattern) + +RCa0* +RCb0* + +*~ +*.???_obj +*.a +*.app +*.aps +*.b64 +*.bak +*.chm +*.class +*.csproj*user +*.d +*.dll +*.dylib *.exe +*.gch +*.gem +*.idb +*.ilk +*.iobj +*.ipch +*.ipdb +*.la +*.lai +*.lib +*.lo +*.log +*.ncb +*.o *.obj +*.opensdf +*.opt +*.org +*.out +*.pch +*.pdb +*.pyc +*.rar +*.res +*.sbr +*.scc +*.sdf +*.slo +*.so +*.suo *.swp +*.tlog +*.tmp +*.unsuccessfulbuild +*.vcproj*user +*.vcxproj*user +*.xcuserstate *.zip diff --git a/.sis/project_name.txt b/.sis/project_name.txt new file mode 100644 index 0000000..cffa451 --- /dev/null +++ b/.sis/project_name.txt @@ -0,0 +1 @@ +realpath \ No newline at end of file diff --git a/.sis/script_info_lines.txt b/.sis/script_info_lines.txt new file mode 100644 index 0000000..a48be4e --- /dev/null +++ b/.sis/script_info_lines.txt @@ -0,0 +1,2 @@ +realpath is a version of the Unix system tool implemented in terms of the STLSoft C/C++ libraries +Copyright (c) 2024-2026, Matthew Wilson and Synesis Information Systems diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..1bf33a0 --- /dev/null +++ b/.vimrc @@ -0,0 +1,70 @@ +" Synesis C/C++ project .vimrc — aligned with .sis/.vscode/c_cxx/settings.json + +set nocompatible +filetype indent plugin on +syntax enable +set autoindent +set backspace=indent,eol,start +set hlsearch +set incsearch +set number + +" files.insertFinalNewline +set eol +set fixeol + +" editor.renderWhitespace: all +set list +set listchars=tab:->,trail:-,extends:>,precedes:<,nbsp:+ + +" editor.detectIndentation: false — global defaults (editor.tabSize: 4, insertSpaces: true) +set colorcolumn=76 +set expandtab +set shiftwidth=4 +set softtabstop=4 +set tabstop=4 + +" colorcolumn draws a full-column tint in Vim (not a VS Code-style 1px line). +" Keep it subtle via the ColorColumn highlight group; reapply after colorscheme changes. +if has('termguicolors') + " set termguicolors +endif + +function! s:ConfigureColorColumn() abort + highlight ColorColumn ctermbg=236 guibg=#2a2a2a cterm=NONE gui=NONE +endfunction + +call s:ConfigureColorColumn() +autocmd ColorScheme * call s:ConfigureColorColumn() + +" files.trimTrailingWhitespace +autocmd BufWritePre * %s/\s\+$//e + +augroup sis_c_cxx + autocmd! + + " [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 + + " [python] + autocmd FileType python setlocal expandtab tabstop=4 shiftwidth=4 softtabstop=4 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 ff73ad0..4044afc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,18 +6,18 @@ }, "[c]": { "editor.insertSpaces": true, - "editor.rulers": [ 60, 76 ], - "editor.tabSize": 4, - }, - "[cpp]": { - "editor.insertSpaces": true, - "editor.rulers": [ 60, 64, 68, 76 ], + "editor.rulers": [ 60, 64, 68, 72, 76 ], "editor.tabSize": 4, }, "[cmake]": { "editor.insertSpaces": false, "editor.tabSize": 4, }, + "[cpp]": { + "editor.insertSpaces": true, + "editor.rulers": [ 60, 64, 68, 72, 76 ], + "editor.tabSize": 4, + }, "[json]": { "editor.insertSpaces": true, "editor.tabSize": 2, @@ -26,6 +26,12 @@ "editor.insertSpaces": true, "editor.tabSize": 2, }, + "[python]": { + "diffEditor.ignoreTrimWhitespace": false, + "editor.insertSpaces": true, + "editor.rulers": [ 51, 60, 61, 76 ], + "editor.tabSize": 4, + }, "[ruby]": { "editor.insertSpaces": true, "editor.tabSize": 2, @@ -35,10 +41,18 @@ "editor.rulers": [ 60, 76 ], "editor.tabSize": 2, }, + "[toml]": { + "editor.insertSpaces": false, + "editor.tabSize": 2, + }, + "[yaml]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + }, "cmake.configureOnOpen": false, "editor.detectIndentation": false, "editor.insertSpaces": false, - "editor.renderWhitespace" : "all", + "editor.renderWhitespace": "all", "editor.rulers": [ 76 ], "editor.tabSize": 2, "files.associations": { @@ -75,6 +89,8 @@ "complex": "cpp", "concepts": "cpp", "console_functions.h": "c", + "corecrt.h": "c", + "crtdefs.h": "c", "cstdarg": "cpp", "cstddef": "cpp", "cstdint": "cpp", @@ -87,10 +103,13 @@ "deque": "cpp", "exception": "cpp", "execution": "cpp", + "fcntl.h": "c", "format": "cpp", + "forward_list": "cpp", "functional": "cpp", "implicit_link.h": "c", "initializer_list": "cpp", + "io.h": "c", "iomanip": "cpp", "ios": "cpp", "iosfwd": "cpp", @@ -105,30 +124,43 @@ "memory_resource": "cpp", "mutex": "cpp", "new": "cpp", + "numbers": "cpp", "numeric": "cpp", "optional": "cpp", "ostream": "cpp", "queue": "cpp", + "random": "cpp", + "ranges": "cpp", "ratio": "cpp", + "semaphore": "cpp", "set": "cpp", + "setenv.h": "c", "shwild.h": "c", + "span": "cpp", "sstream": "cpp", "stack": "cpp", "stdexcept": "cpp", "stdio.h": "c", + "stop_token": "cpp", "streambuf": "cpp", "string": "cpp", "string_view": "cpp", "system_error": "cpp", + "terse-api.h": "c", + "text_encoding": "cpp", "thread": "cpp", "tuple": "cpp", "type_traits": "cpp", "typeinfo": "cpp", + "uio.h": "c", + "unixem.h": "c", "unordered_map": "cpp", + "util.h": "c", "utility": "cpp", "variant": "cpp", "vector": "cpp", "xfacet": "cpp", + "xhash": "cpp", "xiosbase": "cpp", "xlocale": "cpp", "xlocbuf": "cpp", @@ -139,10 +171,13 @@ "xloctime": "cpp", "xmemory": "cpp", "xstring": "cpp", + "xtests.internal.string.c": "cpp", "xtr1common": "cpp", "xtree": "cpp", "xutility": "cpp", }, "files.insertFinalNewline": true, "files.trimTrailingWhitespace": true, + "git.mergeEditor": false, } + diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 0000000..c3bd1d8 --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,18 @@ +# realpath - Authors + + +## Major Contributors: + +* Matt Wilson ([mwsis](https://github.com/mwsis)) + + +## Defect reports, fixes and suggestions (for which we are very grateful): + +* \ (yet) + + +Contributions are welcomed. + + + + diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..64f6fbb --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,20 @@ +# **realpath** Changes + + +## 0.0.3 - 3rd August 2026 + +* Added modular GitHub Actions CI (**ci.yml** / **ci-cell.yml**) for Windows (Windows-only tool); +* Modernised **CMakeLists.txt** (explicit Windows-only guard; **STLSoft** discovery/`STLSOFT` override; MSVC options; `BUILD_TESTING`); +* Added CMake helper scripts (**prepare_cmake.sh**, **build_cmake.sh**, **clean_cmake.sh**, **remove_cmake_artefacts.sh**) and **run_all_unit_tests.cmd**; +* Added **cmake/BuildType.cmake**; +* Added **.sis/script_info_lines.txt** and **.sis/project_name.txt**; +* Project boilerplate bootstrap (**.gitattributes**, **.gitignore**, **.vimrc**, **.vscode/settings.json**, **AUTHORS.md**, **LICENSE**, **README.md**, **INSTALL.md**, **TODO.md**, **NEWS.md**); +* Fixed missing standard-library includes in **realpath.cpp**; + + +## 0.0.2 - 4th May 2025 + +* Added CMake support (**CMakeLists.txt**); + + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 15633a3..127c7ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,10 @@ - # ######################################################################## # # File: /CMakeLists.txt # # Purpose: Top-level CMake lists file for realpath # # Created: 31st December 2024 -# Updated: 25th April 2025 +# Updated: 3rd August 2026 # # ######################################################################## # @@ -66,46 +65,127 @@ set(CMAKE_CXX_EXTENSIONS ON) if(MSVC) + if(MSVC_VERSION GREATER_EQUAL 1914) + + add_compile_options("/Zc:__cplusplus") + + add_definitions(-D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) + endif() + if(MSVC_VERSION LESS 1930) set(CMAKE_C_STANDARD 90) set(CMAKE_CXX_STANDARD 98) endif() - if(MSVC_VERSION GREATER_EQUAL 1914) + if(MSVC_USE_MT) - add_compile_options("/Zc:__cplusplus") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif(MSVC_USE_MT) +else(MSVC) - add_definitions(-D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) - endif() + if(MSVC_USE_MT) + + # this here just to absorb warning about not using `MSVC_USE_MT` (to + # enable **prepare_cmake.sh** to be simple) + endif(MSVC_USE_MT) endif(MSVC) # ########################################################## -# dependencies (required) +# dependencies, includes, options -set(STLSoft_REQUIRED_VERSION_ 1.11.1) +# ################################################ +# includes - 1 -find_package(STLSoft ${STLSoft_REQUIRED_VERSION_} REQUIRED) +include(BuildType) +#[====[ +include(LanguageFullVersion) +include(TargetMacros) +#]====] -message("-- CMake package STLSoft found (version ${STLSoft_VERSION}; ${STLSoft_REQUIRED_VERSION_} requested)") +# ################################################ +# dependencies, features, and options -# ########################################################## -# install -# provides install directory variables as defined by the GNU Coding Standards. +# ###################################### +# options + +option(BUILD_EXAMPLES "Build examples" ON) + +option(BUILD_TESTING "Build tests" ON) + + +# ###################################### +# features + +# This tool targets Windows only (WinSTL). +if(NOT WIN32) + + message(FATAL_ERROR "${PROJECT_NAME} targets Windows only") +endif() + + +# ###################################### +# dependencies +# +# required: +# - STLSoft; +# +# required if testing enabled: +# - (none); +# +# optional: + + +# ############################ +# STLSoft + +if(DEFINED STLSOFT) + + message("-- STLSOFT provided as CMake variable with value '${STLSOFT}'") + + set(STLSOFT_INCLUDE_DIR ${STLSOFT}/include) +elseif(DEFINED ENV{STLSOFT}) + + message("-- STLSOFT provided as environment variable with value '$ENV{STLSOFT}'") + + set(STLSOFT_INCLUDE_DIR $ENV{STLSOFT}/include) +else() + + set(STLSoft_REQUIRED_VERSION_ 1.11.1) + + find_package(STLSoft ${STLSoft_REQUIRED_VERSION_} REQUIRED) + + message("-- CMake package STLSoft found (version ${STLSoft_VERSION}; ${STLSoft_REQUIRED_VERSION_} requested)") +endif() + +if(DEFINED STLSOFT_INCLUDE_DIR) + + include_directories(${STLSOFT_INCLUDE_DIR}) +endif() + + +# ################################################ +# includes - 2 + +include(CMakePackageConfigHelpers) +if(BUILD_TESTING) + + include(CTest) +endif(BUILD_TESTING) include(GNUInstallDirs) # ########################################################## -# tool - realpath +# tool -add_executable(realpath - realpath.cpp +add_executable(${PROJECT_NAME_LOWER} + ${PROJECT_NAME_LOWER}.cpp ) -target_compile_options(realpath +target_compile_options(${PROJECT_NAME_LOWER} PRIVATE $<$,$,$>: -Werror -Wall -Wextra -pedantic @@ -114,18 +194,36 @@ target_compile_options(realpath -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-parameter > - $<$: /WX /W4> + $<$: + /WX /W4 + > ) -target_link_libraries(realpath - STLSoft::STLSoft +target_link_libraries(${PROJECT_NAME_LOWER} + $<$:STLSoft::STLSoft> ) -install(TARGETS realpath +install(TARGETS ${PROJECT_NAME_LOWER} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) +# ################################################ +# examples + + +# ################################################ +# tests + +if(BUILD_TESTING) + + message("-- enabled building of tests ...") +else(BUILD_TESTING) + + message("-- disabled building of tests - define BUILD_TESTING to enable") +endif(BUILD_TESTING) + + # ########################################################## # completion @@ -133,4 +231,3 @@ message(NOTICE "Generating CMake build scripts for ${PROJECT_NAME} ${PROJECT_VER # ############################## end of file ############################# # - diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..fdf6151 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,6 @@ +# realpath - Installation and Use + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7fea35c --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +realpath - BSD 3-Clause License + +Copyright (c) 2024-2026, Synesis Information Systems +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..b419039 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,10 @@ +# realpath - News + + +| Date | News Item | +| -------------------- | -------------------------------------------------- | +| 3rd August 2026 | 0.0.3 released | +| 4th May 2025 | 0.0.2 released | + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..46235e0 --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +# realpath + + +![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=flat&logo=c%2B%2B&logoColor=white) +[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) +[![GitHub release](https://img.shields.io/github/v/release/sistools/realpath.svg)](https://github.com/sistools/realpath/releases/latest) +[![Last Commit](https://img.shields.io/github/last-commit/sistools/realpath)](https://github.com/sistools/realpath/commits/master) +[![CI](https://github.com/sistools/realpath/actions/workflows/ci.yml/badge.svg)](https://github.com/sistools/realpath/actions/workflows/ci.yml) + + +## Table of Contents + +- [Introduction](#introduction) +- [Installation](#installation) +- [Components](#components) +- [Examples](#examples) +- [Project Information](#project-information) + - [Where to get help](#where-to-get-help) + - [Contribution guidelines](#contribution-guidelines) + - [Tests-only Dependencies](#tests-only-dependencies) + - [Related projects](#related-projects) + - [License](#license) + + +## Introduction + +T.B.C. + + +## Installation + +T.B.C. + + +## Components + +T.B.C. + + +## Examples + +T.B.C. + + +## Project Information + + +### Where to get help + +T.B.C. + + +### Contribution guidelines + +T.B.C. + + +#### Tests-only Dependencies + +T.B.C. + + +### Related projects + +T.B.C. + + +### License + +**lstrip** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details. + + + + diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..7c2dfb1 --- /dev/null +++ b/TODO.md @@ -0,0 +1,10 @@ +# realpath - TODO list + + +## mksock 0.0.x TODOs: + +* \ + + + + diff --git a/build_cmake.sh b/build_cmake.sh new file mode 100755 index 0000000..cca1448 --- /dev/null +++ b/build_cmake.sh @@ -0,0 +1,130 @@ +#! /bin/bash + +ScriptPath=$0 +Dir=$(cd $(dirname "$ScriptPath"); pwd) +Basename=$(basename "$ScriptPath") +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +if [[ -n "$MSYSTEM" ]]; then + + DefaultMakeCmd=mingw32-make.exe + MinGW=1 +else + + DefaultMakeCmd=make +fi +MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} + +IgnoreRemainingFlagsAndOptions=0 +Targets=() + + +# ########################################################## +# functions + +function join_by { local IFS="$1"; shift; echo "$*"; } + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + if [ $IgnoreRemainingFlagsAndOptions -ne 0 ]; then + + Targets+=($1) + + shift + + continue + else + + if [ ! ${1:0:1} = '-' ]; then + + Targets+=($1) + + shift + + continue + fi + fi + + case $1 in + --) + + IgnoreRemainingFlagsAndOptions=1 + ;; + --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 ... ] + +Flags/options: + + behaviour: + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +if [ ! -d "$CMakeDir" ]; 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" + + 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 + + if [ -z "$Targets" ]; then + + echo "Executing build (via command \`$MakeCmd\`)" + else + + echo "Executing build (via command \`$MakeCmd\`) with specific target(s) $(join_by , "${Targets[@]}")" + fi + + $MakeCmd ${Targets[*]} + status=$? + + cd ->/dev/null + + exit $status + fi +fi + + +# ############################## end of file ############################# # + diff --git a/clean_cmake.sh b/clean_cmake.sh new file mode 100755 index 0000000..886a201 --- /dev/null +++ b/clean_cmake.sh @@ -0,0 +1,92 @@ +#! /bin/bash + +ScriptPath=$0 +Dir=$(cd $(dirname "$ScriptPath"); pwd) +Basename=$(basename "$ScriptPath") +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +if [[ -n "$MSYSTEM" ]]; then + + DefaultMakeCmd=mingw32-make.exe + MinGW=1 +else + + DefaultMakeCmd=make +fi +MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Executes CMake-generated artefacts to clean project + +$ScriptPath [ ... flags/options ... ] + +Flags/options: + + behaviour: + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +if [ ! -d "$CMakeDir" ]; 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" + + 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 (via command \`$MakeCmd clean\`)" + + $MakeCmd clean + status=$? + + cd ->/dev/null + + exit $status + fi +fi + + +# ############################## end of file ############################# # + diff --git a/cmake/BuildType.cmake b/cmake/BuildType.cmake new file mode 100644 index 0000000..a315b8d --- /dev/null +++ b/cmake/BuildType.cmake @@ -0,0 +1,59 @@ + +# ######################################################################## # +# File: /cmake/BuildType.cmake +# +# Purpose: CMake module file (for BuildType) +# +# Created: 16th October 2019 +# Updated: 25th October 2024 +# +# ######################################################################## # + + +# Including this module sets the `CMAKE_BUILD_TYPE` value as follows: +# +# 1. If user specifies on the command line, then `CMAKE_BUILD_TYPE` already +# has a valid, so this is accepted; +# 2. If the top-level .git directory is specified, then "Debug" is used; +# otherwise +# 3. "Release" is used. +# +# Note: +# - `CMAKE_BUILD_TYPE` is the build (configuration) type; +# - `CMAKE_CONFIGURATION_TYPES` is, if specified, a list of valid +# configurations (see +# https://cmake.org/cmake/help/latest/variable/CMAKE_CONFIGURATION_TYPES.html); +# +# Example usage: +# +#[========[ + +# CMakeLists.txt + +include(BuildType) + +]========] + + +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + set(DEFAULT_BUILD_TYPE "Debug") +else() + set(DEFAULT_BUILD_TYPE "Release") +endif() + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + + message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.") + + set(CACHE CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" + STRING "Choose the type of build." FORCE + ) + + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "MinSizeRel" "RelWithDebInfo" + ) +endif() + +# ############################## end of file ############################# # + diff --git a/prepare_cmake.sh b/prepare_cmake.sh new file mode 100755 index 0000000..d837045 --- /dev/null +++ b/prepare_cmake.sh @@ -0,0 +1,186 @@ +#! /bin/bash + +ScriptPath=$0 +Dir=$(cd $(dirname "$ScriptPath"); pwd) +Basename=$(basename "$ScriptPath") +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +if [[ -n "$MSYSTEM" ]]; then + + DefaultMakeCmd=mingw32-make.exe + MinGW=1 +else + + DefaultMakeCmd=make +fi +MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} + +Configuration=Release +MSVC_MT=0 +MinGW="${MinGW:=0}" +RunMake=0 +STLSoftDirGiven= +TestingDisabled=0 +VerboseMakefile=0 + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --cmake-verbose-makefile|-v) + + VerboseMakefile=1 + ;; + --debug-configuration|-d) + + Configuration=Debug + ;; + --disable-testing|-T) + + TestingDisabled=1 + ;; + --mingw) + + MinGW=1 + ;; + --msvc-mt) + + MSVC_MT=1 + ;; + --run-make|-m) + + RunMake=1 + ;; + --stlsoft-root-dir|-s) + + shift + STLSoftDirGiven=$1 + ;; + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Creates/reinitialises the CMake build script(s) + +$ScriptPath [ ... flags/options ... ] + +Flags/options: + + behaviour: + + -v + --cmake-verbose-makefile + configures CMake to run verbosely (by setting CMAKE_VERBOSE_MAKEFILE + to be ON) + + -d + --debug-configuration + use Debug configuration (by setting CMAKE_BUILD_TYPE=Debug). Default + is to use Release + + -T + --disable-testing + disables building of tests (by setting BUILD_TESTING=OFF) + + --mingw + uses explicitly the "MinGW Makefiles" generator, and defaults the + make-command to "mingw32-make.exe" + + --msvc-mt + when using Visual C++ (MSVC), the static runtime library will be + selected; the default is the dynamic runtime library + + -m + --run-make + executes make after a successful running of CMake + + -s + --stlsoft-root-dir + specifies the STLSoft root-directory, which will be passed to CMake + as the variable STLSOFT, and which will override the environment + variable STLSOFT (if present) + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +mkdir -p $CMakeDir || exit 1 + +cd $CMakeDir + +echo "Executing CMake (in ${CMakeDir})" + +if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="ON" ; fi +if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi +if [ $TestingDisabled -eq 0 ]; then CMakeBuildTestingFlag="ON" ; else CMakeBuildTestingFlag="OFF" ; fi +if [ $VerboseMakefile -eq 0 ]; then CMakeVerboseMakefileFlag="OFF" ; else CMakeVerboseMakefileFlag="ON" ; fi + +if [ $MinGW -ne 0 ]; then + + cmake \ + $CMakeSTLSoftVariable \ + -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ + -DCMAKE_BUILD_TYPE=$Configuration \ + -G "MinGW Makefiles" \ + -S $Dir \ + -B $CMakeDir \ + || (cd ->/dev/null ; exit 1) +else + + cmake \ + $CMakeSTLSoftVariable \ + -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ + -DCMAKE_BUILD_TYPE=$Configuration \ + -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ + -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ + -S $Dir \ + -B $CMakeDir \ + || (cd ->/dev/null ; exit 1) +fi + +status=0 + +if [ $RunMake -ne 0 ]; then + + echo "Executing build (via command \`$MakeCmd\`)" + + $MakeCmd + status=$? +fi + +cd ->/dev/null + +if [ $VerboseMakefile -ne 0 ]; then + + echo -e "contents of $CMakeDir:" + ls -al $CMakeDir +fi + +exit $status + + +# ############################## end of file ############################# # + diff --git a/realpath.cpp b/realpath.cpp index 8cd4bab..dcd0ba2 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -13,12 +13,14 @@ #include #include +#include +#include #include #define REALPATH_VER_MAJOR 0 #define REALPATH_VER_MINOR 0 -#define REALPATH_VER_PATCH 2 +#define REALPATH_VER_PATCH 3 int main(int argc, char* argv[]) diff --git a/remove_cmake_artefacts.sh b/remove_cmake_artefacts.sh new file mode 100755 index 0000000..7416db9 --- /dev/null +++ b/remove_cmake_artefacts.sh @@ -0,0 +1,151 @@ +#! /bin/bash + +ScriptPath=$0 +Dir=$(cd $(dirname "$ScriptPath"); pwd) +Basename=$(basename "$ScriptPath") +CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} + +Directories=( + CMakeFiles + Testing + cmake + examples + projects + src + test +) +Files=( + CMakeCache.txt + CTestTestfile.cmake + DartConfiguration.tcl + Makefile + cmake_install.cmake + install_manifest.txt +) + + +# ########################################################## +# operating environment detection + +OsName="$(uname -s)" +case "${OsName}" in + CYGWIN*|MINGW*|MSYS_NT*) + + Directories+=( + ARM64 + Win32 + x64 + ) + Files+=( + "*.filters" + "*.sln" + "*.vcxproj" + ) + ;; + *) + + ;; +esac + + +# ########################################################## +# command-line handling + +while [[ $# -gt 0 ]]; do + + case $1 in + --help) + + [ -f "$Dir/.sis/script_info_lines.txt" ] && cat "$Dir/.sis/script_info_lines.txt" + cat << EOF +Removes all known CMake artefacts + +$ScriptPath [ ... flags/options ... ] + +Flags/options: + + behaviour: + + + standard flags: + + --help + displays this help and terminates + +EOF + + exit 0 + ;; + *) + + >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + + exit 1 + ;; + esac + + shift +done + + +# ########################################################## +# main() + +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" + + exit 0 +else + + echo "Removing all cmake artefacts in '$CMakeDir'" + + num_dirs_removed=0 + num_files_removed=0 + + for d in ${Directories[@]} + do + + fq_dir_path="$CMakeDir/$d" + + [ -d "$fq_dir_path" ] || continue + + echo "removing directory '$d'" + + rm -dfr "$fq_dir_path" + + num_dirs_removed=$((num_dirs_removed+1)) + done + + cd "$CMakeDir" + + for f in ${Files[@]} + do + + for fq_file_path in $f + do + + [ -f "$fq_file_path" ] || continue + + echo "removing file '$fq_file_path'" + + rm -f "$fq_file_path" + + num_files_removed=$((num_files_removed+1)) + done + done + + cd ->/dev/null + + if [ 0 -eq $num_dirs_removed ] && [ 0 -eq $num_files_removed ]; then + + echo "nothing to do" + else + + echo "removed $num_dirs_removed directories and $num_files_removed files" + fi +fi + + +# ############################## end of file ############################# # + diff --git a/run_all_unit_tests.cmd b/run_all_unit_tests.cmd new file mode 100644 index 0000000..8c88eae --- /dev/null +++ b/run_all_unit_tests.cmd @@ -0,0 +1,141 @@ +@echo off + +SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION + +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" +) + +SET ListOnly=0 +SET Verbose=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" + ) + ECHO ^ + +Runs all ^(matching^) component and unit test programs ^ + +^ + +%SCRIPT_PATH_DOC% [ ... flags/options ... ] ^ + +^ + +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^) ^ + +^ + + -v ^ + + --verbose ^ + + lists each test program before executing it ^ + +^ + + standard flags: ^ + +^ + + --help ^ + + displays this help and terminates ^ + + + 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 {-v}=={%%a} ( + SET Verbose=1 + ) ELSE IF /I {--verbose}=={%%a} ( + SET Verbose=1 + ) ELSE ( + ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 + + EXIT /B 1 + ) +) + +IF NOT EXIST "%CMAKE_DIR%" ( + + ECHO %SCRIPT_PATH_DOC%: CMake build directory '%CMAKE_DIR%' does not exist 1>&2 + + 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 +) + +IF !ListOnly! EQU 1 ( + + ECHO Listing all component and unit test programs +) ELSE ( + + ECHO Running all component and unit test programs +) + +FOR /F "usebackq delims=" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%\*.exe" 2^>NUL ^| FINDSTR /I /R "!ProjectName!.*test.*\.exe$"`) 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 + ) + ) +) + +:done +EXIT /B !status! From d7130e052288dd421e10cfec27a27c03473b1fd6 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Wed, 5 Aug 2026 18:28:07 +1000 Subject: [PATCH 02/16] version --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 64f6fbb..3e102b0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ # **realpath** Changes -## 0.0.3 - 3rd August 2026 +## 0.0.3 - 5th August 2026 * Added modular GitHub Actions CI (**ci.yml** / **ci-cell.yml**) for Windows (Windows-only tool); * Modernised **CMakeLists.txt** (explicit Windows-only guard; **STLSoft** discovery/`STLSOFT` override; MSVC options; `BUILD_TESTING`); From 85ba620c9c3a21f14cf60fe7bd94d29b499b1120 Mon Sep 17 00:00:00 2001 From: synesissoftware Date: Sun, 16 Aug 2026 20:07:40 +1000 Subject: [PATCH 03/16] Version (#3) * ~ ignores * ~ settings * + added CMakeLists.txt * + enforcing minimum STLSoft version (in code) * ~ whitespace * + enforcing minimum C++ standard version (in code) * + added support for '--help' flag * ~ simplification * + added support for '--version' flag * + added support for '--version' flag * added .gitattributes * settings * squash-commit * CI --- .github/workflows/ci.yml | 3 +++ .vscode/settings.json | 2 ++ CHANGES.md | 4 ++++ CMakeLists.txt | 2 +- realpath.cpp | 19 +++++++++++++++++-- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05d1e48..51d1d2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,10 @@ on: push: branches: - master + - dev - boilerplate + - update + - version pull_request: concurrency: diff --git a/.vscode/settings.json b/.vscode/settings.json index 4044afc..fec09cc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -132,6 +132,8 @@ "random": "cpp", "ranges": "cpp", "ratio": "cpp", + "rc.h": "c", + "result_codes_.h": "c", "semaphore": "cpp", "set": "cpp", "setenv.h": "c", diff --git a/CHANGES.md b/CHANGES.md index 3e102b0..cd31c6c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,10 @@ # **realpath** Changes +## 0.1.0 - 6th August 2026 + + + ## 0.0.3 - 5th August 2026 * Added modular GitHub Actions CI (**ci.yml** / **ci-cell.yml**) for Windows (Windows-only tool); diff --git a/CMakeLists.txt b/CMakeLists.txt index 127c7ff..ca826c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # Purpose: Top-level CMake lists file for realpath # # Created: 31st December 2024 -# Updated: 3rd August 2026 +# Updated: 5th August 2026 # # ######################################################################## # diff --git a/realpath.cpp b/realpath.cpp index dcd0ba2..22dbf4a 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -19,8 +19,8 @@ #define REALPATH_VER_MAJOR 0 -#define REALPATH_VER_MINOR 0 -#define REALPATH_VER_PATCH 3 +#define REALPATH_VER_MINOR 1 +#define REALPATH_VER_PATCH 0 int main(int argc, char* argv[]) @@ -42,6 +42,21 @@ int main(int argc, char* argv[]) return EXIT_SUCCESS; } else + if (0 == std::strcmp("--version", argv[1])) + { + std::cout + << program_name + << " v" + << REALPATH_VER_MAJOR + << '.' + << REALPATH_VER_MINOR + << '.' + << REALPATH_VER_PATCH + << std::endl; + + return EXIT_SUCCESS; + } + else { winstl::absolute_path abs_path(argv[1]); From 95f78d9eb7562a2b5c2cd17c807943e15bf03ca6 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 16 Aug 2026 21:02:13 +1000 Subject: [PATCH 04/16] .vscode/settings.json --- .vscode/settings.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4044afc..a20fc3c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,8 @@ "editor.tabSize": 4, }, "[c]": { + "editor.defaultFormatter": "ms-vscode.cpptools", + "editor.formatOnSave": true, "editor.insertSpaces": true, "editor.rulers": [ 60, 64, 68, 72, 76 ], "editor.tabSize": 4, @@ -14,6 +16,8 @@ "editor.tabSize": 4, }, "[cpp]": { + "editor.defaultFormatter": "ms-vscode.cpptools", + "editor.formatOnSave": true, "editor.insertSpaces": true, "editor.rulers": [ 60, 64, 68, 72, 76 ], "editor.tabSize": 4, @@ -49,7 +53,17 @@ "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", @@ -128,6 +142,7 @@ "numeric": "cpp", "optional": "cpp", "ostream": "cpp", + "print": "cpp", "queue": "cpp", "random": "cpp", "ranges": "cpp", @@ -180,4 +195,3 @@ "files.trimTrailingWhitespace": true, "git.mergeEditor": false, } - From c10f3377ee8ac8537a0601f6aebc4008ef59f925 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 14:26:58 +1000 Subject: [PATCH 05/16] .gitattributes --- .gitattributes | 116 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 99 insertions(+), 17 deletions(-) diff --git a/.gitattributes b/.gitattributes index a9c5470..66f0c82 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,17 +1,99 @@ -*.c linguist-language=C -*.cmake linguist-vendored -*.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-vendored -makefile linguist-detectable=false +# .gitattributes — C++ (GitHub-hosted) +# +# Sources: GitHub Docs (line endings), git-scm gitattributes (diff=cpp), +# gitattributes/gitattributes C++.gitattributes + Common.gitattributes, +# github-linguist overrides. + +# 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 From dfad33e6174c5f689180011308f294558f425c28 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 15:20:00 +1000 Subject: [PATCH 06/16] ci --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51d1d2b..fe85f6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,10 @@ on: - master - dev - boilerplate - - update - - version + - idiomatic + - rc1 + - rc2 + - rc3 pull_request: concurrency: From d2ee05fd4cf0a8a264868755983157533c65eec9 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 16:03:35 +1000 Subject: [PATCH 07/16] README.md "related projects" --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46235e0..a8b2940 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,17 @@ T.B.C. ### Related projects -T.B.C. +Other **sistools** projects include: + +* [**chomp**](https://github.com/sistools/chomp); +* [**errni**](https://github.com/sistools/errni) (errno on all platforms, and also GetLastError codes on Windows); +* [**lnunique**](https://github.com/sistools/lnunique); +* [**lslocales**](https://github.com/sistools/lslocales); +* [**lstrip**](https://github.com/sistools/lstrip); +* [**mksock**](https://github.com/sistools/mksock) (Unix-only); +* [**ReadDebugString**](https://github.com/sistools/ReadDebugString) (Windows-only); +* [**rstrip**](https://github.com/sistools/rstrip); +* [**WriteDebugString**](https://github.com/sistools/WriteDebugString) (Windows-only); ### License From d2be88acd60db4c3bb52f6754b15524b173be838 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 16:08:09 +1000 Subject: [PATCH 08/16] README.md operating-system badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a8b2940..74ecd73 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ ![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=flat&logo=c%2B%2B&logoColor=white) +![Windows](https://img.shields.io/badge/OS-Windows-0078D6?style=flat&logo=windows&logoColor=white) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![GitHub release](https://img.shields.io/github/v/release/sistools/realpath.svg)](https://github.com/sistools/realpath/releases/latest) [![Last Commit](https://img.shields.io/github/last-commit/sistools/realpath)](https://github.com/sistools/realpath/commits/master) From e4f6bd0a6893494a043853f424bf835ce50102ee Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 16:16:08 +1000 Subject: [PATCH 09/16] README.md initial contents --- README.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 74ecd73..624ad4f 100644 --- a/README.md +++ b/README.md @@ -25,22 +25,30 @@ ## Introduction -T.B.C. +**realpath** is a small Windows-only utility that resolves a path in terms of +the STLSoft C/C++ libraries. ## Installation -T.B.C. +The project uses CMake. From the project directory: + +```powershell +cmake -S . -B _build +cmake --build _build --config Release +``` ## Components -T.B.C. +The project creates a single executable program, **realpath**. ## Examples -T.B.C. +```powershell +> realpath.exe path +``` ## Project Information @@ -48,17 +56,19 @@ T.B.C. ### Where to get help -T.B.C. +[GitHub Page](https://github.com/sistools/realpath "GitHub Page") ### Contribution guidelines -T.B.C. +Defect reports, feature requests, and pull requests are welcome on [the +**realpath** GitHub page](https://github.com/sistools/realpath). #### Tests-only Dependencies -T.B.C. +For unit-testing, **realpath** uses the test dependencies configured by its +CMake build. ### Related projects @@ -78,7 +88,8 @@ Other **sistools** projects include: ### License -**lstrip** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details. +**realpath** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) +for details. From dd7e88404436cb678d10a32200fd84f6a4ed7001 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 16:20:43 +1000 Subject: [PATCH 10/16] boilerplate --- INSTALL.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ TODO.md | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/INSTALL.md b/INSTALL.md index fdf6151..512a046 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,5 +2,50 @@ +## Requisites + +**realpath** requires: + +* [**STLSoft**](https://github.com/synesissoftware/STLSoft), version 1.11.1 + or later; +* CMake 3.20 or later; +* a Windows C/C++ toolchain supported by CMake. + + +## Building + +The primary build method is CMake. From PowerShell: + +```powershell +git clone https://github.com/sistools/realpath.git +Set-Location realpath +cmake -S . -B _build +cmake --build _build --config Release +``` + +The resulting executable is `_build/Release/realpath.exe`. + + +## Installing + +To install into a user-local directory: + +```powershell +cmake --install _build --config Release --prefix "$env:LOCALAPPDATA\Programs\realpath" +``` + +The installed executable is placed in the `bin` directory beneath the +selected prefix. + + +## Testing + +Configure the project with `-DBUILD_TESTING=ON` to build its tests, then run: + +```powershell +ctest --test-dir _build -C Release --output-on-failure +``` + + diff --git a/TODO.md b/TODO.md index 13a9689..5fc88c7 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,7 @@ ## realpath 0.0.x TODOs: -* Complete **INSTALL.md** and **README.md** (replace **T.B.C.** stubs); +* Review and expand **INSTALL.md** as the build and dependency requirements evolve; * Add **REQUISITES.md** (at least **STLSoft**); * Set GitHub repository topics: `cpp`, `cli`, `command-line`, `cmake`, `stlsoft`, `windows`, `win32`, `filesystem`, `path`, `bsd-3-clause`, `sistools`; From d743bacc0bdc24fee139935021d37fb826df4485 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 16:39:33 +1000 Subject: [PATCH 11/16] chore: standardise helper project identity handling --- build_cmake.sh | 2 ++ clean_cmake.sh | 2 ++ prepare_cmake.sh | 4 +++- remove_cmake_artefacts.sh | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/build_cmake.sh b/build_cmake.sh index cca1448..65bee2b 100755 --- a/build_cmake.sh +++ b/build_cmake.sh @@ -4,6 +4,8 @@ ScriptPath=$0 Dir=$(cd $(dirname "$ScriptPath"); pwd) Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") if [[ -n "$MSYSTEM" ]]; then DefaultMakeCmd=mingw32-make.exe diff --git a/clean_cmake.sh b/clean_cmake.sh index 886a201..cef4212 100755 --- a/clean_cmake.sh +++ b/clean_cmake.sh @@ -4,6 +4,8 @@ ScriptPath=$0 Dir=$(cd $(dirname "$ScriptPath"); pwd) Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") if [[ -n "$MSYSTEM" ]]; then DefaultMakeCmd=mingw32-make.exe diff --git a/prepare_cmake.sh b/prepare_cmake.sh index d837045..6adeb66 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -4,6 +4,8 @@ ScriptPath=$0 Dir=$(cd $(dirname "$ScriptPath"); pwd) Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") if [[ -n "$MSYSTEM" ]]; then DefaultMakeCmd=mingw32-make.exe @@ -131,7 +133,7 @@ mkdir -p $CMakeDir || exit 1 cd $CMakeDir -echo "Executing CMake (in ${CMakeDir})" +echo "Executing CMake for ${ProjectName} (in ${CMakeDir})" if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="ON" ; fi if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi diff --git a/remove_cmake_artefacts.sh b/remove_cmake_artefacts.sh index 7416db9..0e5a7b3 100755 --- a/remove_cmake_artefacts.sh +++ b/remove_cmake_artefacts.sh @@ -4,6 +4,8 @@ ScriptPath=$0 Dir=$(cd $(dirname "$ScriptPath"); pwd) Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +ProjectNameFile="$Dir/.sis/project_name.txt" +ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") Directories=( CMakeFiles From 841e6d8bb1905b2589f0659194ad95a5ac7863e1 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 16:46:24 +1000 Subject: [PATCH 12/16] chore: standardize shell-script color output --- build_cmake.sh | 28 +++++++++++++++++++++++----- clean_cmake.sh | 24 +++++++++++++++++++++--- prepare_cmake.sh | 24 +++++++++++++++++++++--- remove_cmake_artefacts.sh | 22 ++++++++++++++++++++-- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/build_cmake.sh b/build_cmake.sh index 65bee2b..3f455e2 100755 --- a/build_cmake.sh +++ b/build_cmake.sh @@ -6,6 +6,24 @@ Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") + +# ########################################################## +# colours + +if command -v tput > /dev/null; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_None=${FD_NONE:-$(tput sgr0)} +else + + SisClr_Blue= + SisClr_Red= + SisClr_Bold= + SisClr_None= +fi + if [[ -n "$MSYSTEM" ]]; then DefaultMakeCmd=mingw32-make.exe @@ -79,7 +97,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}unrecognised argument '$1'${SisClr_None}; use --help for usage" exit 1 ;; @@ -94,7 +112,7 @@ done if [ ! -d "$CMakeDir" ]; 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 "$ScriptPath: CMake build directory '$CMakeDir' ${SisClr_Red}${SisClr_Bold}not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" exit 1 else @@ -103,7 +121,7 @@ else 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'" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' does not contain${SisClr_None} 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 @@ -112,10 +130,10 @@ else if [ -z "$Targets" ]; then - echo "Executing build (via command \`$MakeCmd\`)" + echo "Executing build (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`)" else - echo "Executing build (via command \`$MakeCmd\`) with specific target(s) $(join_by , "${Targets[@]}")" + echo "Executing build (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`) with specific target(s) $(join_by , "${Targets[@]}")" fi $MakeCmd ${Targets[*]} diff --git a/clean_cmake.sh b/clean_cmake.sh index cef4212..3bcdb95 100755 --- a/clean_cmake.sh +++ b/clean_cmake.sh @@ -6,6 +6,24 @@ Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") + +# ########################################################## +# colours + +if command -v tput > /dev/null; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_None=${FD_NONE:-$(tput sgr0)} +else + + SisClr_Blue= + SisClr_Red= + SisClr_Bold= + SisClr_None= +fi + if [[ -n "$MSYSTEM" ]]; then DefaultMakeCmd=mingw32-make.exe @@ -47,7 +65,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}unrecognised argument '$1'${SisClr_None}; use --help for usage" exit 1 ;; @@ -62,7 +80,7 @@ done if [ ! -d "$CMakeDir" ]; 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 "$ScriptPath: CMake build directory '$CMakeDir' ${SisClr_Red}${SisClr_Bold}not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" exit 1 else @@ -71,7 +89,7 @@ else 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'" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' does not contain${SisClr_None} 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 diff --git a/prepare_cmake.sh b/prepare_cmake.sh index 6adeb66..5c1bdae 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -6,6 +6,24 @@ Basename=$(basename "$ScriptPath") CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") + +# ########################################################## +# colours + +if command -v tput > /dev/null; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_None=${FD_NONE:-$(tput sgr0)} +else + + SisClr_Blue= + SisClr_Red= + SisClr_Bold= + SisClr_None= +fi + if [[ -n "$MSYSTEM" ]]; then DefaultMakeCmd=mingw32-make.exe @@ -116,7 +134,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}unrecognised argument '$1'${SisClr_None}; use --help for usage" exit 1 ;; @@ -133,7 +151,7 @@ mkdir -p $CMakeDir || exit 1 cd $CMakeDir -echo "Executing CMake for ${ProjectName} (in ${CMakeDir})" +echo "Executing CMake for ${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None} (in ${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None})" if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="ON" ; fi if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi @@ -167,7 +185,7 @@ status=0 if [ $RunMake -ne 0 ]; then - echo "Executing build (via command \`$MakeCmd\`)" + echo "Executing build (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`)" $MakeCmd status=$? diff --git a/remove_cmake_artefacts.sh b/remove_cmake_artefacts.sh index 0e5a7b3..aa41a0a 100755 --- a/remove_cmake_artefacts.sh +++ b/remove_cmake_artefacts.sh @@ -7,6 +7,24 @@ CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +# ########################################################## +# colours + +if command -v tput > /dev/null; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_None=${FD_NONE:-$(tput sgr0)} +else + + SisClr_Blue= + SisClr_Red= + SisClr_Bold= + SisClr_None= +fi + + Directories=( CMakeFiles Testing @@ -80,7 +98,7 @@ EOF ;; *) - >&2 echo "$ScriptPath: unrecognised argument '$1'; use --help for usage" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}unrecognised argument '$1'${SisClr_None}; use --help for usage" exit 1 ;; @@ -95,7 +113,7 @@ 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 "$ScriptPath: CMake build directory '$CMakeDir' ${SisClr_Red}${SisClr_Bold}not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" exit 0 else From da58f2e6cc3fdcbef79f48f64ca24b463cadf19f Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 20:51:27 +1000 Subject: [PATCH 13/16] chore: canonicalised helper scripts --- build_cmake.sh | 38 ++++++++--------- clean_cmake.sh | 30 +++++++------- prepare_cmake.sh | 64 +++++++++++++++++++---------- remove_cmake_artefacts.sh | 42 +++++++++---------- run_all_unit_tests.cmd | 86 +++++++++++++++++++-------------------- 5 files changed, 141 insertions(+), 119 deletions(-) diff --git a/build_cmake.sh b/build_cmake.sh index 3f455e2..3f261e7 100755 --- a/build_cmake.sh +++ b/build_cmake.sh @@ -1,12 +1,26 @@ #! /bin/bash ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) +Dir=$(cd "$(dirname "$ScriptPath")" && pwd) Basename=$(basename "$ScriptPath") + CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +if [[ -n "$MSYSTEM" ]]; then + + DefaultMakeCmd=mingw32-make.exe + MinGW=1 +else + + DefaultMakeCmd=make +fi +MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +IgnoreRemainingFlagsAndOptions=0 +Targets=() + + # ########################################################## # colours @@ -24,19 +38,6 @@ else SisClr_None= fi -if [[ -n "$MSYSTEM" ]]; then - - DefaultMakeCmd=mingw32-make.exe - MinGW=1 -else - - DefaultMakeCmd=make -fi -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} - -IgnoreRemainingFlagsAndOptions=0 -Targets=() - # ########################################################## # functions @@ -112,7 +113,7 @@ done if [ ! -d "$CMakeDir" ]; then - >&2 echo "$ScriptPath: CMake build directory '$CMakeDir' ${SisClr_Red}${SisClr_Bold}not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" exit 1 else @@ -121,7 +122,7 @@ else if [ ! -f "$CMakeDir/Makefile" ]; then - >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' does not contain${SisClr_None} 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'" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' does not contain expected file 'Makefile'${SisClr_None}, 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 @@ -130,10 +131,10 @@ else if [ -z "$Targets" ]; then - echo "Executing build (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`)" + echo "Executing build of ${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None} (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`)" else - echo "Executing build (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`) with specific target(s) $(join_by , "${Targets[@]}")" + echo "Executing build of ${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None} (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd${SisClr_None}\`) with specific target(s) $(join_by , "${Targets[@]}")" fi $MakeCmd ${Targets[*]} @@ -147,4 +148,3 @@ fi # ############################## end of file ############################# # - diff --git a/clean_cmake.sh b/clean_cmake.sh index 3bcdb95..96b6c07 100755 --- a/clean_cmake.sh +++ b/clean_cmake.sh @@ -1,12 +1,23 @@ #! /bin/bash ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) +Dir=$(cd "$(dirname "$ScriptPath")" && pwd) Basename=$(basename "$ScriptPath") + CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +if [[ -n "$MSYSTEM" ]]; then + + DefaultMakeCmd=mingw32-make.exe + MinGW=1 +else + + DefaultMakeCmd=make +fi +MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") + # ########################################################## # colours @@ -24,16 +35,6 @@ else SisClr_None= fi -if [[ -n "$MSYSTEM" ]]; then - - DefaultMakeCmd=mingw32-make.exe - MinGW=1 -else - - DefaultMakeCmd=make -fi -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} - # ########################################################## # command-line handling @@ -80,7 +81,7 @@ done if [ ! -d "$CMakeDir" ]; then - >&2 echo "$ScriptPath: CMake build directory '$CMakeDir' ${SisClr_Red}${SisClr_Bold}not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' not found${SisClr_None} so nothing to do; use script 'prepare_cmake.sh' if you wish to prepare CMake artefacts" exit 1 else @@ -89,14 +90,14 @@ else if [ ! -f "$CMakeDir/Makefile" ]; then - >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' does not contain${SisClr_None} 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'" + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}CMake build directory '$CMakeDir' does not contain expected file 'Makefile'${SisClr_None}, 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 (via command \`$MakeCmd clean\`)" + echo "Cleaning ${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None} (via command \`${SisClr_Blue}${SisClr_Bold}$MakeCmd clean${SisClr_None}\`)" $MakeCmd clean status=$? @@ -109,4 +110,3 @@ fi # ############################## end of file ############################# # - diff --git a/prepare_cmake.sh b/prepare_cmake.sh index 5c1bdae..6253e78 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -1,12 +1,32 @@ #! /bin/bash ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) +Dir=$(cd "$(dirname "$ScriptPath")" && pwd) Basename=$(basename "$ScriptPath") + CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} +if [[ -n "$MSYSTEM" ]]; then + + DefaultMakeCmd=mingw32-make.exe + MinGW=1 +else + + DefaultMakeCmd=make +fi +MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") +Configuration=Release +CxxStandard= +MSVC_MT=0 +MinGW="${MinGW:=0}" +RunMake=0 +STLSoftDirGiven= +TestingDisabled=0 +VerboseMakefile=0 + + # ########################################################## # colours @@ -24,24 +44,6 @@ else SisClr_None= fi -if [[ -n "$MSYSTEM" ]]; then - - DefaultMakeCmd=mingw32-make.exe - MinGW=1 -else - - DefaultMakeCmd=make -fi -MakeCmd=${SIS_CMAKE_MAKE_COMMAND:-${SIS_CMAKE_COMMAND:-$DefaultMakeCmd}} - -Configuration=Release -MSVC_MT=0 -MinGW="${MinGW:=0}" -RunMake=0 -STLSoftDirGiven= -TestingDisabled=0 -VerboseMakefile=0 - # ########################################################## # command-line handling @@ -49,6 +51,21 @@ VerboseMakefile=0 while [[ $# -gt 0 ]]; do case $1 in + --cxx-standard) + + shift + CxxStandard=$1 + case $CxxStandard in + 98|11|14|17|20|23) + ;; + *) + + >&2 echo "$ScriptPath: ${SisClr_Red}${SisClr_Bold}invalid C++ standard '$CStandard'${SisClr_None}; expected 98, 11, 14, 17, 20, or 23" + + exit 1 + ;; + esac + ;; --cmake-verbose-makefile|-v) VerboseMakefile=1 @@ -90,6 +107,9 @@ Flags/options: behaviour: + --cxx-standard {98|11|14|17|20|23} + sets CMAKE_CXX_STANDARD (default is 17) + -v --cmake-verbose-makefile configures CMake to run verbosely (by setting CMAKE_VERBOSE_MAKEFILE @@ -153,14 +173,16 @@ cd $CMakeDir echo "Executing CMake for ${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None} (in ${SisClr_Blue}${SisClr_Bold}${CMakeDir}${SisClr_None})" +if [ -z "$CxxStandard" ]; then CMakeCxxStandardVariable="" ; else CMakeCxxStandardVariable="-DCMAKE_CXX_STANDARD=$CxxStandard" ; fi if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="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 if [ $MinGW -ne 0 ]; then cmake \ + $CMakeCxxStandardVariable \ $CMakeSTLSoftVariable \ -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ @@ -171,6 +193,7 @@ if [ $MinGW -ne 0 ]; then else cmake \ + $CMakeCxxStandardVariable \ $CMakeSTLSoftVariable \ -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ @@ -203,4 +226,3 @@ exit $status # ############################## end of file ############################# # - diff --git a/remove_cmake_artefacts.sh b/remove_cmake_artefacts.sh index aa41a0a..992153f 100755 --- a/remove_cmake_artefacts.sh +++ b/remove_cmake_artefacts.sh @@ -1,30 +1,13 @@ #! /bin/bash ScriptPath=$0 -Dir=$(cd $(dirname "$ScriptPath"); pwd) +Dir=$(cd "$(dirname "$ScriptPath")" && pwd) Basename=$(basename "$ScriptPath") + CMakeDir=${SIS_CMAKE_BUILD_DIR:-$Dir/_build} ProjectNameFile="$Dir/.sis/project_name.txt" ProjectName=$(tr -d '[:space:]' < "$ProjectNameFile") -# ########################################################## -# colours - -if command -v tput > /dev/null; then - - SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} - SisClr_Red=${FG_RED:-$(tput setaf 1)} - SisClr_Bold=${FD_BOLD:-$(tput bold)} - SisClr_None=${FD_NONE:-$(tput sgr0)} -else - - SisClr_Blue= - SisClr_Red= - SisClr_Bold= - SisClr_None= -fi - - Directories=( CMakeFiles Testing @@ -44,6 +27,24 @@ Files=( ) +# ########################################################## +# colours + +if command -v tput > /dev/null; then + + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_None=${FD_NONE:-$(tput sgr0)} +else + + SisClr_Blue= + SisClr_Red= + SisClr_Bold= + SisClr_None= +fi + + # ########################################################## # operating environment detection @@ -118,7 +119,7 @@ if [ ! -d "$CMakeDir" ]; then exit 0 else - echo "Removing all cmake artefacts in '$CMakeDir'" + echo "Removing all ${SisClr_Blue}${SisClr_Bold}${ProjectName}${SisClr_None} cmake artefacts in '${SisClr_Blue}${SisClr_Bold}$CMakeDir${SisClr_None}'" num_dirs_removed=0 num_files_removed=0 @@ -168,4 +169,3 @@ fi # ############################## end of file ############################# # - diff --git a/run_all_unit_tests.cmd b/run_all_unit_tests.cmd index 8c88eae..8c11cf4 100644 --- a/run_all_unit_tests.cmd +++ b/run_all_unit_tests.cmd @@ -6,10 +6,10 @@ 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 @@ -17,12 +17,12 @@ SET Verbose=0 SET status=0 FOR %%a IN (%*) DO ( - IF /I {--help}=={%%a} ( - IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + IF /I {--help}=={%%a} ( + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( - type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" - ) - ECHO ^ + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ Runs all ^(matching^) component and unit test programs ^ @@ -71,31 +71,31 @@ Flags/options: ^ displays this help and terminates ^ - 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 {-v}=={%%a} ( - SET Verbose=1 - ) ELSE IF /I {--verbose}=={%%a} ( - SET Verbose=1 - ) ELSE ( - ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 - - EXIT /B 1 - ) + 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 {-v}=={%%a} ( + SET Verbose=1 + ) ELSE IF /I {--verbose}=={%%a} ( + SET Verbose=1 + ) ELSE ( + ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 + + EXIT /B 1 + ) ) IF NOT EXIST "%CMAKE_DIR%" ( - ECHO %SCRIPT_PATH_DOC%: CMake build directory '%CMAKE_DIR%' does not exist 1>&2 + ECHO %SCRIPT_PATH_DOC%: CMake build directory '%CMAKE_DIR%' does not exist 1>&2 - EXIT /B 1 + EXIT /B 1 ) SET "ProjectName=" @@ -103,38 +103,38 @@ 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 + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 - EXIT /B 1 + EXIT /B 1 ) IF !ListOnly! EQU 1 ( - ECHO Listing all component and unit test programs + ECHO Listing all component and unit test programs ) ELSE ( - ECHO Running all component and unit test programs + ECHO Running all component and unit test programs ) FOR /F "usebackq delims=" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%\*.exe" 2^>NUL ^| FINDSTR /I /R "!ProjectName!.*test.*\.exe$"`) DO ( - IF !ListOnly! EQU 1 ( + IF !ListOnly! EQU 1 ( - ECHO would execute %%f: - ) ELSE ( + ECHO would execute %%f: + ) ELSE ( - IF !Verbose! EQU 1 ( + IF !Verbose! EQU 1 ( - ECHO executing %%f: - ) + ECHO executing %%f: + ) - "%%f" - IF ERRORLEVEL 1 ( + "%%f" + IF ERRORLEVEL 1 ( - SET status=1 + SET status=1 - GOTO :done - ) - ) + GOTO :done + ) + ) ) :done From 390095e6ea49c9fddd478c8512c6e39775164335 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 21:05:40 +1000 Subject: [PATCH 14/16] CMake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ca826c7..7ae5608 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,7 +227,7 @@ endif(BUILD_TESTING) # ########################################################## # completion -message(NOTICE "Generating CMake build scripts for ${PROJECT_NAME} ${PROJECT_VERSION}, for C${CMAKE_C_STANDARD} C++${CMAKE_CXX_STANDARD}") +message(NOTICE "Generating CMake build scripts for ${PROJECT_NAME} ${PROJECT_VERSION}, for C${CMAKE_C_STANDARD} C++${CMAKE_CXX_STANDARD}, with build type ${CMAKE_BUILD_TYPE}") # ############################## end of file ############################# # From a3c1e1f3da5817bd7c2a0c2a120f5c2a706ea23a Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Mon, 17 Aug 2026 21:13:57 +1000 Subject: [PATCH 15/16] CMake --- CMakeLists.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ae5608..7ababa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,10 +56,16 @@ set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT # adhere strictly to C and C++ standards plus extensions. These are actually # useless since we do not compile anything; they merely state our intention. -set(CMAKE_C_STANDARD 17) +if(NOT CMAKE_C_STANDARD) + + set(CMAKE_C_STANDARD 17) +endif() set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) # GNU extensions and POSIX standard -set(CMAKE_CXX_STANDARD 17) +if(NOT CMAKE_CXX_STANDARD) + + set(CMAKE_CXX_STANDARD 17) +endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS ON) From 6ef124f0ce3781f61b94a3b1181d50acaa3a5c59 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Wed, 19 Aug 2026 10:52:52 +1000 Subject: [PATCH 16/16] squash-commit --- INSTALL.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++- README.md | 28 +++++++++++------------ 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 512a046..71a338d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,70 @@ # realpath - Installation and Use +- [Requisites](#requisites) +- [Building](#building) + - [via CMake](#via-cmake) + + +## Requisites + +**realpath** is a **Windows-only** program (implemented in [**realpath.cpp**](./realpath.cpp)) and depends on: + +* [**STLSoft**](https://github.com/synesissoftware/STLSoft) (1.11+) - **WinSTL** absolute-path and error-description components; + + +## Building + + +### via CMake + +The primary choice for installation is by use of **CMake** on Windows. + +1. Obtain the latest distribution of **realpath**, from + https://github.com/sistools/realpath/, e.g. + + ```bash + $ mkdir -p ~/open-source + $ cd ~/open-source + $ git clone https://github.com/sistools/realpath/ + ``` + +2. Prepare the CMake configuration, via the **prepare_cmake.sh** script, as + in: + + ```bash + $ cd ~/open-source/realpath + $ ./prepare_cmake.sh + ``` + + (**NOTE**: configuring on a non-Windows host fails: the tool targets + Windows only.) + +3. Run a build of the generated **CMake**-derived build files via the + **build_cmake.sh** script, as in: + + ```bash + $ cd ~/open-source/realpath + $ ./build_cmake.sh + ``` + + (**NOTE**: if you provide the flag `--run-make` (=== `-m`) in step 2 then you do + not need this step.) + +4. As a check, execute the built program, as in: + + ```bash + $ cd ~/open-source/realpath + $ ./_build/realpath --help + ``` + +5. Finally, if you wish to do so, you can install the tool on the host, via `cmake`, as in: + + ```bash + $ cd ~/open-source/realpath + $ cmake --install ./_build --config Release + ``` + ## Requisites @@ -48,4 +112,3 @@ ctest --test-dir _build -C Release --output-on-failure - diff --git a/README.md b/README.md index 624ad4f..2e2f639 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # realpath +Windows analogue of the Unix **realpath**(1) utility. + ![C++](https://img.shields.io/badge/C%2B%2B-00599C?style=flat&logo=c%2B%2B&logoColor=white) ![Windows](https://img.shields.io/badge/OS-Windows-0078D6?style=flat&logo=windows&logoColor=white) @@ -18,25 +20,20 @@ - [Project Information](#project-information) - [Where to get help](#where-to-get-help) - [Contribution guidelines](#contribution-guidelines) - - [Tests-only Dependencies](#tests-only-dependencies) + - [Dependencies](#dependencies) - [Related projects](#related-projects) - [License](#license) ## Introduction -**realpath** is a small Windows-only utility that resolves a path in terms of -the STLSoft C/C++ libraries. +**realpath** is a small, standalone Windows utility that prints the absolute path of a given (possibly relative) path, implemented in terms of the **STLSoft** / **WinSTL** libraries. It is a **Windows-only** analogue of Unix **realpath**(1). ## Installation -The project uses CMake. From the project directory: - -```powershell -cmake -S . -B _build -cmake --build _build --config Release -``` +Detailed instructions - via **CMake** - are provided in the accompanying [INSTALL.md](./INSTALL.md) +file. ## Components @@ -46,8 +43,9 @@ The project creates a single executable program, **realpath**. ## Examples -```powershell -> realpath.exe path +```bat +> realpath . +C:\Users\...\sistools\realpath ``` @@ -65,10 +63,11 @@ Defect reports, feature requests, and pull requests are welcome on [the **realpath** GitHub page](https://github.com/sistools/realpath). -#### Tests-only Dependencies +### Dependencies -For unit-testing, **realpath** uses the test dependencies configured by its -CMake build. +**realpath** depends on: + +* [**STLSoft**](https://github.com/synesissoftware/STLSoft) (1.11+; **WinSTL**, **PlatformSTL**); ### Related projects @@ -93,4 +92,3 @@ for details. -