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..fe85f6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,10 @@ on: - master - dev - boilerplate - - update - - version + - idiomatic + - rc1 + - rc2 + - rc3 pull_request: concurrency: 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..163e128 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", diff --git a/CHANGES.md b/CHANGES.md index 8b2afbf..246f7be 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,17 @@ -# **realpath** Changes +# realpath - Changes + + +## 0.1.1 - 23rd August 2026 + +* Documented the Windows-only program, its **STLSoft** dependency, and its CMake build, installation, and testing workflows in **README.md** and **INSTALL.md**; +* Added **REQUISITES.md** documenting required build tools, **STLSoft** configuration, Windows toolchains, and optional **Doxygen** support; +* Clarified the Windows-only scope in **README.md**, including a usage example, project information, and a Windows badge; +* Modernised source-control metadata in **.gitattributes** and editor configuration in **.vimrc** and **.vscode/settings.json**; +* Updated **CMakeLists.txt** to preserve caller-selected C and C++ standards and report the configured build type; +* Improved CMake helper scripts with safer path handling, project-aware diagnostics, configurable C standards, and coloured status messages; +* Replaced the POSIX Doxygen helper with the Windows **generate_doxygen.cmd** script; +* Updated GitHub Actions push-branch coverage by removing the obsolete `version` branch and retaining the standard development and release branches; +* Corrected release information in **NEWS.md** and updated the outstanding work in **TODO.md**; ## 0.1.0 - 16th August 2026 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/REQUISITES.md b/REQUISITES.md new file mode 100644 index 0000000..0d7deaf --- /dev/null +++ b/REQUISITES.md @@ -0,0 +1,59 @@ +# realpath - Requisites + + +- [Introduction](#introduction) +- [Build requirements](#build-requirements) + - [STLSoft](#stlsoft) + - [CMake](#cmake) + - [Windows C/C++ toolchain](#windows-cc-toolchain) +- [Optional requirements](#optional-requirements) + - [Doxygen](#doxygen) + + +## Introduction + +**realpath** is a Windows-only command-line program implemented in +[**realpath.cpp**](./realpath.cpp). It uses the **STLSoft** / **WinSTL** +libraries to provide Windows path and error-description facilities. + + +## Build requirements + + +### STLSoft + +**STLSoft** version **1.11.1** or later is required. It may be supplied to +CMake in either of the following ways: + +* install a CMake package that can be found by `find_package(STLSoft)`; +* pass the STLSoft root directory with `-DSTLSOFT=`; or +* set the `STLSOFT` environment variable to the STLSoft root directory. + +The root directory must contain the STLSoft `include` directory. + + +### CMake + +**CMake** version **3.20** or later is required. The default C++ language +standard is C++17; this can be changed when configuring the project with the +**prepare_cmake.sh** helper. + + +### Windows C/C++ toolchain + +A Windows C/C++ toolchain supported by **CMake** is required. The project +supports the toolchains and generators available to the installed CMake, +including Visual C++ and MinGW where configured. + + +## Optional requirements + + +### Doxygen + +**Doxygen** is required only when generating the API documentation with +**generate_doxygen.cmd**. The `doxygen` executable must be available on +`PATH`, and the CMake build directory must contain the generated `Doxyfile`. + + + diff --git a/TODO.md b/TODO.md index 7c2dfb1..0546e50 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +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; +* [x] ~~~Add **REQUISITES.md** (at least **STLSoft**)~~~; +* [x] ~~~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..6b96a40 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 [ -n "${TERM:-}" ] && [ -t 1 ] && command -v tput >/dev/null 2>&1; 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..17d36a3 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 [ -n "${TERM:-}" ] && [ -t 1 ] && command -v tput >/dev/null 2>&1; 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/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 diff --git a/prepare_cmake.sh b/prepare_cmake.sh index d837045..b98a74d 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 [ -n "${TERM:-}" ] && [ -t 1 ] && command -v tput >/dev/null 2>&1; 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: + --c-standard {99|11|17|23} + sets CMAKE_C_STANDARD (default is 11) + -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 CMakeCStandardVariable="" ; else CMakeCStandardVariable="-DCMAKE_C_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 \ + $CMakeCStandardVariable \ $CMakeSTLSoftVariable \ -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ @@ -151,6 +192,7 @@ if [ $MinGW -ne 0 ]; then else cmake \ + $CMakeCStandardVariable \ $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..5b4478e 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 [ -n "${TERM:-}" ] && [ -t 1 ] && command -v tput >/dev/null 2>&1; 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..8c11cf4 100644 --- a/run_all_unit_tests.cmd +++ b/run_all_unit_tests.cmd @@ -6,10 +6,10 @@ SET SCRIPT_DIRECTORY=%~dp0 SET SCRIPT_PATH_DOC=%~n0[%~x0] IF DEFINED SIS_CMAKE_BUILD_DIR ( - SET "CMAKE_DIR=%SIS_CMAKE_BUILD_DIR%" + SET "CMAKE_DIR=%SIS_CMAKE_BUILD_DIR%" ) ELSE ( - SET "CMAKE_DIR=%SCRIPT_DIRECTORY%_build" + SET "CMAKE_DIR=%SCRIPT_DIRECTORY%_build" ) SET ListOnly=0 @@ -17,12 +17,12 @@ SET Verbose=0 SET status=0 FOR %%a IN (%*) DO ( - IF /I {--help}=={%%a} ( - IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( + IF /I {--help}=={%%a} ( + IF EXIST "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" ( - type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" - ) - ECHO ^ + type "%SCRIPT_DIRECTORY%.sis\script_info_lines.txt" + ) + ECHO ^ Runs all ^(matching^) component and unit test programs ^ @@ -71,31 +71,31 @@ Flags/options: ^ displays this help and terminates ^ - EXIT /B 0 - ) ELSE IF /I {-l}=={%%a} ( - SET ListOnly=1 - ) ELSE IF /I {--list-only}=={%%a} ( - SET ListOnly=1 - ) ELSE IF /I {-M}=={%%a} ( - REM no-op: this .cmd never invokes the build - ) ELSE IF /I {--no-make}=={%%a} ( - REM no-op: this .cmd never invokes the build - ) ELSE IF /I {-v}=={%%a} ( - SET Verbose=1 - ) ELSE IF /I {--verbose}=={%%a} ( - SET Verbose=1 - ) ELSE ( - ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 - - EXIT /B 1 - ) + EXIT /B 0 + ) ELSE IF /I {-l}=={%%a} ( + SET ListOnly=1 + ) ELSE IF /I {--list-only}=={%%a} ( + SET ListOnly=1 + ) ELSE IF /I {-M}=={%%a} ( + REM no-op: this .cmd never invokes the build + ) ELSE IF /I {--no-make}=={%%a} ( + REM no-op: this .cmd never invokes the build + ) ELSE IF /I {-v}=={%%a} ( + SET Verbose=1 + ) ELSE IF /I {--verbose}=={%%a} ( + SET Verbose=1 + ) ELSE ( + ECHO %SCRIPT_PATH_DOC%: unrecognised argument '%%a'; use --help for usage 1>&2 + + EXIT /B 1 + ) ) IF NOT EXIST "%CMAKE_DIR%" ( - ECHO %SCRIPT_PATH_DOC%: CMake build directory '%CMAKE_DIR%' does not exist 1>&2 + ECHO %SCRIPT_PATH_DOC%: CMake build directory '%CMAKE_DIR%' does not exist 1>&2 - EXIT /B 1 + EXIT /B 1 ) SET "ProjectName=" @@ -103,38 +103,38 @@ FOR /F "usebackq delims=" %%p IN ("%SCRIPT_DIRECTORY%.sis\project_name.txt") DO IF NOT DEFINED ProjectName ( - ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 + ECHO %SCRIPT_PATH_DOC%: could not read project name from .sis\project_name.txt 1>&2 - EXIT /B 1 + EXIT /B 1 ) IF !ListOnly! EQU 1 ( - ECHO Listing all component and unit test programs + ECHO Listing all component and unit test programs ) ELSE ( - ECHO Running all component and unit test programs + ECHO Running all component and unit test programs ) FOR /F "usebackq delims=" %%f IN (`DIR /A:-D /B /S "%CMAKE_DIR%\*.exe" 2^>NUL ^| FINDSTR /I /R "!ProjectName!.*test.*\.exe$"`) DO ( - IF !ListOnly! EQU 1 ( + IF !ListOnly! EQU 1 ( - ECHO would execute %%f: - ) ELSE ( + ECHO would execute %%f: + ) ELSE ( - IF !Verbose! EQU 1 ( + IF !Verbose! EQU 1 ( - ECHO executing %%f: - ) + ECHO executing %%f: + ) - "%%f" - IF ERRORLEVEL 1 ( + "%%f" + IF ERRORLEVEL 1 ( - SET status=1 + SET status=1 - GOTO :done - ) - ) + GOTO :done + ) + ) ) :done