From ffafd4603a7ae20123d7dab4fa2b4148ab0dc870 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:14:45 +1000 Subject: [PATCH 01/19] ~ ignores --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 79e3a3c..49613f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ +/_build + *.*~ *.exe *.obj From 069dd22dc54eda74487badc7df4da7a369cd2b10 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:14:58 +1000 Subject: [PATCH 02/19] ~ settings --- .vscode/settings.json | 148 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ff73ad0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,148 @@ +{ + "[bat]": { + "editor.insertSpaces": true, + "editor.rulers": [ 60, 76 ], + "editor.tabSize": 4, + }, + "[c]": { + "editor.insertSpaces": true, + "editor.rulers": [ 60, 76 ], + "editor.tabSize": 4, + }, + "[cpp]": { + "editor.insertSpaces": true, + "editor.rulers": [ 60, 64, 68, 76 ], + "editor.tabSize": 4, + }, + "[cmake]": { + "editor.insertSpaces": false, + "editor.tabSize": 4, + }, + "[json]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + }, + "[markdown]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + }, + "[ruby]": { + "editor.insertSpaces": true, + "editor.tabSize": 2, + }, + "[shellscript]": { + "editor.insertSpaces": true, + "editor.rulers": [ 60, 76 ], + "editor.tabSize": 2, + }, + "cmake.configureOnOpen": false, + "editor.detectIndentation": false, + "editor.insertSpaces": false, + "editor.renderWhitespace" : "all", + "editor.rulers": [ 76 ], + "editor.tabSize": 2, + "files.associations": { + "__bit_reference": "cpp", + "__bits": "cpp", + "__config": "cpp", + "__debug": "cpp", + "__errc": "cpp", + "__functional_03": "cpp", + "__functional_base": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__memory": "cpp", + "__mutex_base": "cpp", + "__node_handle": "cpp", + "__nullptr": "cpp", + "__split_buffer": "cpp", + "__string": "cpp", + "__threading_support": "cpp", + "__tree": "cpp", + "__tuple": "cpp", + "__verbose_abort": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "console_functions.h": "c", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "exception": "cpp", + "execution": "cpp", + "format": "cpp", + "functional": "cpp", + "implicit_link.h": "c", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "mutex": "cpp", + "new": "cpp", + "numeric": "cpp", + "optional": "cpp", + "ostream": "cpp", + "queue": "cpp", + "ratio": "cpp", + "set": "cpp", + "shwild.h": "c", + "sstream": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "stdio.h": "c", + "streambuf": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "variant": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + }, + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, +} From f6c63854f2f9ce1f911c3634fd4ec75d3e5e49b7 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:33:50 +1000 Subject: [PATCH 03/19] + added CMakeLists.txt --- CMakeLists.txt | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ realpath.cpp | 5 ++ 2 files changed, 141 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..15633a3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,136 @@ + +# ######################################################################## # +# File: /CMakeLists.txt +# +# Purpose: Top-level CMake lists file for realpath +# +# Created: 31st December 2024 +# Updated: 25th April 2025 +# +# ######################################################################## # + + +# ########################################################## +# CMake + +cmake_minimum_required(VERSION 3.20 FATAL_ERROR) + +# require out-of-source builds +file(TO_CMAKE_PATH "${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) +if(EXISTS "${LOC_PATH}") + + message(FATAL_ERROR "You cannot build in a source directory (or any directory with a CMakeLists.txt file). Please make a build subdirectory. Feel free to remove CMakeCache.txt and CMakeFiles.") +endif() + +# directory for CMake specific extensions and source files. +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + + +# ########################################################## +# project + +project(realpath + DESCRIPTION "realpath is a version of the Unix system tool implemented in terms of the STLSoft C/C++ libraries." + HOMEPAGE_URL "https://github.com/sistools/realpath" + LANGUAGES C CXX +) + +string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER) +string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER) + +# handle version number +set(RX_PROJ_TAG "${PROJECT_NAME_UPPER}") +set(RX_WS "[ \t]") +file(READ "${CMAKE_SOURCE_DIR}/${PROJECT_NAME_LOWER}.cpp" _impl_file) +string(REGEX MATCH "#${RX_WS}*define${RX_WS}+_?${RX_PROJ_TAG}_VER_MAJOR${RX_WS}+([0-9]+)" MAJOR_DUMMY ${_impl_file}) +set(_VERSION_MAJOR ${CMAKE_MATCH_1}) +string(REGEX MATCH "#${RX_WS}*define${RX_WS}+_?${RX_PROJ_TAG}_VER_MINOR${RX_WS}+([0-9]+)" MINOR_DUMMY ${_impl_file}) +set(_VERSION_MINOR ${CMAKE_MATCH_1}) +string(REGEX MATCH "#${RX_WS}*define${RX_WS}+_?${RX_PROJ_TAG}_VER_PATCH${RX_WS}+([0-9]+)" PATCH_DUMMY ${_impl_file}) +set(_VERSION_PATCH ${CMAKE_MATCH_1}) + +# set project version number here +set(PROJECT_VERSION_MAJOR ${_VERSION_MAJOR}) +set(PROJECT_VERSION_MINOR ${_VERSION_MINOR}) +set(PROJECT_VERSION_PATCH ${_VERSION_PATCH}) +set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") + +# 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) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) # GNU extensions and POSIX standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) + +if(MSVC) + + if(MSVC_VERSION LESS 1930) + + set(CMAKE_C_STANDARD 90) + set(CMAKE_CXX_STANDARD 98) + endif() + + if(MSVC_VERSION GREATER_EQUAL 1914) + + add_compile_options("/Zc:__cplusplus") + + add_definitions(-D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) + endif() +endif(MSVC) + + +# ########################################################## +# dependencies (required) + +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)") + + +# ########################################################## +# install + +# provides install directory variables as defined by the GNU Coding Standards. +include(GNUInstallDirs) + + +# ########################################################## +# tool - realpath + +add_executable(realpath + realpath.cpp +) + +target_compile_options(realpath + PRIVATE + $<$,$,$>: + -Werror -Wall -Wextra -pedantic + + -Wno-ignored-qualifiers + -Wno-incompatible-pointer-types-discards-qualifiers + -Wno-unused-parameter + > + $<$: /WX /W4> +) + +target_link_libraries(realpath + STLSoft::STLSoft +) + +install(TARGETS realpath + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + + +# ########################################################## +# completion + +message(NOTICE "Generating CMake build scripts for ${PROJECT_NAME} ${PROJECT_VERSION}, for C${CMAKE_C_STANDARD} C++${CMAKE_CXX_STANDARD}") + + +# ############################## end of file ############################# # + diff --git a/realpath.cpp b/realpath.cpp index 4e45868..163cf80 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -6,6 +6,11 @@ #include +#define REALPATH_VER_MAJOR 0 +#define REALPATH_VER_MINOR 0 +#define REALPATH_VER_PATCH 2 + + int main(int argc, char* argv[]) { stlsoft::string_slice_m_t const program_name = platformstl::get_executable_name_from_path(argv[0]); From 4611e6b19b82996a3104a4445827bfc909791ee4 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:34:16 +1000 Subject: [PATCH 04/19] + enforcing minimum STLSoft version (in code) --- realpath.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/realpath.cpp b/realpath.cpp index 163cf80..2b38603 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -1,4 +1,10 @@ +#include + +#if _STLSOFT_VER < 0x010b0184 +# error requires STLSoft v1.11.1-b4 or later +#endif + #include #include #include From 49b5997d48099893a5a4a22e55e4fd8e1d1ada43 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:36:10 +1000 Subject: [PATCH 05/19] ~ whitespace --- realpath.cpp | 104 +++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/realpath.cpp b/realpath.cpp index 2b38603..3cfdba3 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -19,57 +19,57 @@ int main(int argc, char* argv[]) { - stlsoft::string_slice_m_t const program_name = platformstl::get_executable_name_from_path(argv[0]); - - switch (argc) - { - case 2: - - { - winstl::absolute_path abs_path(argv[1]); - - if (0 == abs_path.length()) - { - winstl::error_desc ed; - - std::cerr - << program_name - << ": failed to obtain absolute path for '" - << argv[1] - << "': " - << ed - << std::endl; - - return EXIT_FAILURE; - } - else - { - - std::cout - << abs_path - << std::endl; - - return EXIT_SUCCESS; - } - } - break; - case 1: - - std::cerr - << "USAGE: " - << program_name - << " " - << std::endl; - - return EXIT_FAILURE; - default: - - std::cerr - << program_name - << ": too many arguments; use --help for usage" - << std::endl; - - return EXIT_FAILURE; - } + stlsoft::string_slice_m_t const program_name = platformstl::get_executable_name_from_path(argv[0]); + + switch (argc) + { + case 2: + + { + winstl::absolute_path abs_path(argv[1]); + + if (0 == abs_path.length()) + { + winstl::error_desc ed; + + std::cerr + << program_name + << ": failed to obtain absolute path for '" + << argv[1] + << "': " + << ed + << std::endl; + + return EXIT_FAILURE; + } + else + { + + std::cout + << abs_path + << std::endl; + + return EXIT_SUCCESS; + } + } + break; + case 1: + + std::cerr + << "USAGE: " + << program_name + << " " + << std::endl; + + return EXIT_FAILURE; + default: + + std::cerr + << program_name + << ": too many arguments; use --help for usage" + << std::endl; + + return EXIT_FAILURE; + } } From fe5960b34e17647db9bffb36e75ca3afb7fc19a5 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:40:57 +1000 Subject: [PATCH 06/19] + enforcing minimum C++ standard version (in code) --- realpath.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/realpath.cpp b/realpath.cpp index 3cfdba3..7142b52 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -4,6 +4,9 @@ #if _STLSOFT_VER < 0x010b0184 # error requires STLSoft v1.11.1-b4 or later #endif +#if __cplusplus < 201702L +# error requires C++17 or later +#endif #include #include From 276aec948a8d33bb637d67042968a38aa5900cde Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:48:56 +1000 Subject: [PATCH 07/19] + added support for '--help' flag --- realpath.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/realpath.cpp b/realpath.cpp index 7142b52..43ab803 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -12,6 +12,7 @@ #include #include +#include #include @@ -28,6 +29,17 @@ int main(int argc, char* argv[]) { case 2: + if (0 == std::strcmp("--help", argv[1])) + { + std::cout + << "USAGE: " + << program_name + << " " + << std::endl; + + return EXIT_SUCCESS; + } + else { winstl::absolute_path abs_path(argv[1]); @@ -59,9 +71,8 @@ int main(int argc, char* argv[]) case 1: std::cerr - << "USAGE: " << program_name - << " " + << ": no name specified; use --help for usage" << std::endl; return EXIT_FAILURE; From 4b09bba083530201954cac5eda56f9c6d29029b3 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 18:53:11 +1000 Subject: [PATCH 08/19] ~ simplification --- realpath.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/realpath.cpp b/realpath.cpp index 43ab803..8cd4bab 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -23,7 +23,7 @@ int main(int argc, char* argv[]) { - stlsoft::string_slice_m_t const program_name = platformstl::get_executable_name_from_path(argv[0]); + auto const program_name = platformstl::get_executable_name_from_path(argv[0]); switch (argc) { @@ -59,7 +59,6 @@ int main(int argc, char* argv[]) } else { - std::cout << abs_path << std::endl; From 78def9e6508c6f9b6de6617a143e72481f0f724d Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 19:07:38 +1000 Subject: [PATCH 09/19] + added support for '--version' flag --- realpath.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/realpath.cpp b/realpath.cpp index 8cd4bab..d61c5fc 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -40,6 +40,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 632ec9d5e4cf585fedef47de0f18524b4b4bcb52 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 19:12:48 +1000 Subject: [PATCH 10/19] + added support for '--version' flag --- realpath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/realpath.cpp b/realpath.cpp index d61c5fc..f14bd6c 100644 --- a/realpath.cpp +++ b/realpath.cpp @@ -18,7 +18,7 @@ #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[]) From 08c5e8e22114624aaa41e004814c68e35cf11e06 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Fri, 25 Apr 2025 19:33:28 +1000 Subject: [PATCH 11/19] added .gitattributes --- .gitattributes | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cdea8f4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +*.c linguist-language=C +*.h linguist-language=C +*.cpp linguist-language=C++ +*.hpp linguist-language=C++ +*.html linguist-detectable=false +*.sh linguist-detectable=false +makefile linguist-detectable=false +CMakeLists.txt linguist-detectable=false + 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 12/19] 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 13/19] 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 905965f784c7440a648fe3cc5066b73999370c7b Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Wed, 5 Aug 2026 18:32:34 +1000 Subject: [PATCH 14/19] settings --- .vscode/settings.json | 2 ++ 1 file changed, 2 insertions(+) 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", From 141e7ee7a4e20dc2fc3ecadf870cff84ecdfb4cf Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Wed, 5 Aug 2026 18:39:59 +1000 Subject: [PATCH 15/19] squash-commit --- .gitattributes | 14 +- .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 | 51 ++++++- AUTHORS.md | 18 +++ CHANGES.md | 24 +++ 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 | 6 +- remove_cmake_artefacts.sh | 151 +++++++++++++++++++ run_all_unit_tests.cmd | 141 ++++++++++++++++++ 23 files changed, 1635 insertions(+), 36 deletions(-) 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 index cdea8f4..a9c5470 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,17 @@ *.c linguist-language=C -*.h 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 -CMakeLists.txt 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..fec09cc 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,45 @@ "memory_resource": "cpp", "mutex": "cpp", "new": "cpp", + "numbers": "cpp", "numeric": "cpp", "optional": "cpp", "ostream": "cpp", "queue": "cpp", + "random": "cpp", + "ranges": "cpp", "ratio": "cpp", + "rc.h": "c", + "result_codes_.h": "c", + "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 +173,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..cd31c6c --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,24 @@ +# **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); +* 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..ca826c7 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: 5th 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 f14bd6c..22dbf4a 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 3 +#define REALPATH_VER_MINOR 1 +#define REALPATH_VER_PATCH 0 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 eba8a070f74694ed734734db079a915b2fe24058 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Wed, 5 Aug 2026 18:41:47 +1000 Subject: [PATCH 16/19] CI --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) 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: From 9bdea287b899a3a073e81aa559a5161d024bbfb2 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 16 Aug 2026 20:18:56 +1000 Subject: [PATCH 17/19] 0.1.0 --- CHANGES.md | 3 ++- NEWS.md | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cd31c6c..8b2afbf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,8 +1,9 @@ # **realpath** Changes -## 0.1.0 - 6th August 2026 +## 0.1.0 - 16th August 2026 +* added support for '--version'; ## 0.0.3 - 5th August 2026 diff --git a/NEWS.md b/NEWS.md index b419039..44b6d35 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,10 +1,11 @@ # realpath - News -| Date | News Item | -| -------------------- | -------------------------------------------------- | -| 3rd August 2026 | 0.0.3 released | -| 4th May 2025 | 0.0.2 released | +| Date | News Item | +| -------------------- | ---------------- | +| 16ht August 2026 | [0.1.0 released](https://github.com/sistools/realpath/releases/tag/0.0.3) | +| 3rd August 2026 | 0.0.3 released | +| 4th May 2025 | 0.0.2 released | From 5e18ec364d0e8461e662750b4429b20701b5f40c Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 23 Aug 2026 16:38:35 +1000 Subject: [PATCH 18/19] squash-commit --- .gitattributes | 116 +++++++++++++--- .github/workflows/ci.yml | 5 +- .vimrc | 18 +-- .vscode/settings.json | 16 ++- CHANGES.md | 5 + CMakeLists.txt | 12 +- INSTALL.md | 114 ++++++++++++++- NEWS.md | 3 +- README.md | 44 ++++-- TODO.md | 7 +- build_cmake.sh | 35 +++-- clean_cmake.sh | 33 ++++- prepare_cmake.sh | 55 +++++++- remove_cmake_artefacts.sh | 30 +++- run_all_unit_tests.cmd | 282 +++++++++++++++++++------------------- 15 files changed, 559 insertions(+), 216 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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51d1d2b..8ae2494 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,10 @@ on: - master - dev - boilerplate - - update + - idiomatic + - rc1 + - rc2 + - rc3 - version pull_request: diff --git a/.vimrc b/.vimrc index 1bf33a0..1163e13 100644 --- a/.vimrc +++ b/.vimrc @@ -43,27 +43,27 @@ 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 " [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 sh,bash,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 fec09cc..4f84e5d 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", @@ -182,4 +197,3 @@ "files.trimTrailingWhitespace": true, "git.mergeEditor": false, } - diff --git a/CHANGES.md b/CHANGES.md index 8b2afbf..0a8b0f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,11 @@ # **realpath** Changes +## 0.1.1 - 23rd August 2026 + +T.B.C. + + ## 0.1.0 - 16th August 2026 * added support for '--version'; diff --git a/CMakeLists.txt b/CMakeLists.txt index ca826c7..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) @@ -227,7 +233,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 ############################# # diff --git a/INSTALL.md b/INSTALL.md index fdf6151..0746a1a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,6 +1,118 @@ # realpath - Installation and Use +- [Requisites](#requisites) +- [Building](#building) + - [via CMake](#via-cmake) +- [Requisites](#requisites-1) +- [Building](#building-1) +- [Installing](#installing) +- [Testing](#testing) - +## 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 + +**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/NEWS.md b/NEWS.md index 44b6d35..8733477 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,8 @@ | Date | News Item | | -------------------- | ---------------- | -| 16ht August 2026 | [0.1.0 released](https://github.com/sistools/realpath/releases/tag/0.0.3) | +| 23rd August 2026 | [0.1.1 released](https://github.com/sistools/realpath/releases/tag/0.1.1) | +| 16th August 2026 | [0.1.0 released](https://github.com/sistools/realpath/releases/tag/0.1.0) | | 3rd August 2026 | 0.0.3 released | | 4th May 2025 | 0.0.2 released | diff --git a/README.md b/README.md index 46235e0..2e2f639 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # 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) [![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) @@ -17,29 +20,33 @@ - [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 -T.B.C. +**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 -T.B.C. +Detailed instructions - via **CMake** - are provided in the accompanying [INSTALL.md](./INSTALL.md) +file. ## Components -T.B.C. +The project creates a single executable program, **realpath**. ## Examples -T.B.C. +```bat +> realpath . +C:\Users\...\sistools\realpath +``` ## Project Information @@ -47,28 +54,41 @@ 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). + +### Dependencies -#### Tests-only Dependencies +**realpath** depends on: -T.B.C. +* [**STLSoft**](https://github.com/synesissoftware/STLSoft) (1.11+; **WinSTL**, **PlatformSTL**); ### 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 -**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. - diff --git a/TODO.md b/TODO.md index 7c2dfb1..5fc88c7 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,11 @@ # realpath - TODO list -## mksock 0.0.x TODOs: +## realpath 0.0.x TODOs: -* \ +* 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`; - diff --git a/build_cmake.sh b/build_cmake.sh index cca1448..f081647 100755 --- a/build_cmake.sh +++ b/build_cmake.sh @@ -1,23 +1,43 @@ #! /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 + +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 + + # ########################################################## # functions @@ -77,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 ;; @@ -92,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: ${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 @@ -101,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 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 @@ -110,10 +130,10 @@ else if [ -z "$Targets" ]; then - echo "Executing build (via command \`$MakeCmd\`)" + 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 \`$MakeCmd\`) 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[*]} @@ -127,4 +147,3 @@ fi # ############################## end of file ############################# # - diff --git a/clean_cmake.sh b/clean_cmake.sh index 886a201..b2e61b3 100755 --- a/clean_cmake.sh +++ b/clean_cmake.sh @@ -1,18 +1,38 @@ #! /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 + +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 # ########################################################## @@ -45,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 ;; @@ -60,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: ${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 @@ -69,14 +89,14 @@ 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 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=$? @@ -89,4 +109,3 @@ fi # ############################## end of file ############################# # - diff --git a/prepare_cmake.sh b/prepare_cmake.sh index d837045..f83e2b4 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -1,20 +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") Configuration=Release +CxxStandard= MSVC_MT=0 MinGW="${MinGW:=0}" RunMake=0 @@ -23,12 +26,45 @@ TestingDisabled=0 VerboseMakefile=0 +# ########################################################## +# 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 + + # ########################################################## # command-line handling 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 '$CxxStandard'${SisClr_None}; expected 98, 11, 14, 17, 20, or 23" + + exit 1 + ;; + esac + ;; --cmake-verbose-makefile|-v) VerboseMakefile=1 @@ -70,6 +106,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 @@ -114,7 +153,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 ;; @@ -131,16 +170,18 @@ mkdir -p $CMakeDir || exit 1 cd $CMakeDir -echo "Executing CMake (in ${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 \ @@ -151,6 +192,7 @@ if [ $MinGW -ne 0 ]; then else cmake \ + $CMakeCxxStandardVariable \ $CMakeSTLSoftVariable \ -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ @@ -165,7 +207,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=$? @@ -183,4 +225,3 @@ exit $status # ############################## end of file ############################# # - diff --git a/remove_cmake_artefacts.sh b/remove_cmake_artefacts.sh index 7416db9..992153f 100755 --- a/remove_cmake_artefacts.sh +++ b/remove_cmake_artefacts.sh @@ -1,9 +1,12 @@ #! /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") Directories=( CMakeFiles @@ -24,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 @@ -78,7 +99,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 ;; @@ -93,12 +114,12 @@ 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 - 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 @@ -148,4 +169,3 @@ fi # ############################## end of file ############################# # - diff --git a/run_all_unit_tests.cmd b/run_all_unit_tests.cmd index 8c88eae..1a7b941 100644 --- a/run_all_unit_tests.cmd +++ b/run_all_unit_tests.cmd @@ -1,141 +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! +@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 5330925a0d172f2aaa110be0d52ddfbf28770189 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Sun, 23 Aug 2026 16:43:10 +1000 Subject: [PATCH 19/19] generate_doxygen.cmd --- generate_doxygen.cmd | 135 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 generate_doxygen.cmd diff --git a/generate_doxygen.cmd b/generate_doxygen.cmd new file mode 100644 index 0000000..abb2811 --- /dev/null +++ b/generate_doxygen.cmd @@ -0,0 +1,135 @@ +@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 "DOXYGEN_OPTIONS=" + +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 Generates HTML API documentation from public headers via Doxygen + ECHO( + ECHO %SCRIPT_PATH_DOC% [ ... flags/options ... ] + ECHO( + ECHO Flags/options: + ECHO( + ECHO behaviour: + ECHO( + ECHO -q + ECHO --quiet + ECHO causes the flag -q to be passed to Doxygen, which will then act as + ECHO if QUIET=YES has been set + ECHO( + ECHO( + ECHO standard flags: + ECHO( + ECHO --help + ECHO displays this help and terminates + ECHO( + ECHO Environment: + ECHO( + ECHO SIS_CMAKE_BUILD_DIR + ECHO CMake build directory ^(default: ^/_build^); documentation is + ECHO written to ^/doxygen/html/ + ECHO( + EXIT /B 0 + ) ELSE IF /I {-q}=={%%a} ( + SET "DOXYGEN_OPTIONS=-q" + ) ELSE IF /I {--quiet}=={%%a} ( + SET "DOXYGEN_OPTIONS=-q" + ) ELSE ( + ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 + + EXIT /B 1 + ) +) + +IF NOT EXIST "%CMAKE_DIR%" ( + + MKDIR "%CMAKE_DIR%" 2>NUL + IF ERRORLEVEL 1 ( + + ECHO %SCRIPT_PATH_DOC%: could not create CMake build directory '%CMAKE_DIR%' 1>&2 + + EXIT /B 1 + ) +) + +PUSHD "%CMAKE_DIR%" >NUL +IF ERRORLEVEL 1 ( + + ECHO %SCRIPT_PATH_DOC%: could not enter CMake build directory '%CMAKE_DIR%' 1>&2 + + EXIT /B 1 +) + +SET "ProjectName=" +FOR /F "usebackq tokens=* 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 + + POPD + EXIT /B 1 +) + +WHERE doxygen >NUL 2>&1 +IF ERRORLEVEL 1 ( + + ECHO %SCRIPT_PATH_DOC%: doxygen not found on PATH 1>&2 + + POPD + EXIT /B 1 +) + +IF NOT EXIST "Doxyfile" ( + + ECHO %SCRIPT_PATH_DOC%: Doxyfile not found in '%CMAKE_DIR%' 1>&2 + + POPD + EXIT /B 1 +) + +IF NOT EXIST "doxygen" ( + MKDIR "doxygen" + IF ERRORLEVEL 1 ( + + ECHO %SCRIPT_PATH_DOC%: could not create '%CMAKE_DIR%\doxygen' 1>&2 + + POPD + EXIT /B 1 + ) +) + +ECHO Executing Doxygen for %ProjectName% (in %CMAKE_DIR%) + +( + type "Doxyfile" + ECHO. + ECHO # Output directory (overridden by %SCRIPT_PATH_DOC%^) + ECHO OUTPUT_DIRECTORY = %CMAKE_DIR%\doxygen +) | doxygen %DOXYGEN_OPTIONS% - +IF ERRORLEVEL 1 ( + + POPD + EXIT /B 1 +) + +ECHO API documentation written to %CMAKE_DIR%\doxygen\html\index.html + +POPD +EXIT /B 0