diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-06-29 19:28:09 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-06-29 19:28:09 +0100 |
| commit | 67b2fae1fa8b033045a44c1355d9dfd8f83e0d9b (patch) | |
| tree | 1ecd818f4bcf7d12622d43dc92c4d4bb9b746d0f /contrib/catch2/tools/misc | |
| parent | a8b0ea58e60bb0326b7f7c8f3c736d89ce9ef1df (diff) | |
| parent | bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1 (diff) | |
| download | nihil-67b2fae1fa8b033045a44c1355d9dfd8f83e0d9b.tar.gz nihil-67b2fae1fa8b033045a44c1355d9dfd8f83e0d9b.tar.bz2 | |
Add 'contrib/catch2/' from commit 'bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1'
git-subtree-dir: contrib/catch2
git-subtree-mainline: a8b0ea58e60bb0326b7f7c8f3c736d89ce9ef1df
git-subtree-split: bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1
Diffstat (limited to 'contrib/catch2/tools/misc')
| -rw-r--r-- | contrib/catch2/tools/misc/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | contrib/catch2/tools/misc/appveyorBuildConfigurationScript.bat | 21 | ||||
| -rw-r--r-- | contrib/catch2/tools/misc/appveyorMergeCoverageScript.py | 9 | ||||
| -rw-r--r-- | contrib/catch2/tools/misc/appveyorTestRunScript.bat | 17 | ||||
| -rw-r--r-- | contrib/catch2/tools/misc/coverage-helper.cpp | 142 | ||||
| -rw-r--r-- | contrib/catch2/tools/misc/installOpenCppCoverage.ps1 | 19 |
6 files changed, 219 insertions, 0 deletions
diff --git a/contrib/catch2/tools/misc/CMakeLists.txt b/contrib/catch2/tools/misc/CMakeLists.txt new file mode 100644 index 0000000..59811df --- /dev/null +++ b/contrib/catch2/tools/misc/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.16) + +project(CatchCoverageHelper) + +add_executable(CoverageHelper coverage-helper.cpp) +set_property(TARGET CoverageHelper PROPERTY CXX_STANDARD 11) +set_property(TARGET CoverageHelper PROPERTY CXX_STANDARD_REQUIRED ON) +set_property(TARGET CoverageHelper PROPERTY CXX_EXTENSIONS OFF) +if (MSVC) + target_compile_options( CoverageHelper PRIVATE /W4 /w44265 /WX /w44061 /w44062 ) +endif() diff --git a/contrib/catch2/tools/misc/appveyorBuildConfigurationScript.bat b/contrib/catch2/tools/misc/appveyorBuildConfigurationScript.bat new file mode 100644 index 0000000..727f829 --- /dev/null +++ b/contrib/catch2/tools/misc/appveyorBuildConfigurationScript.bat @@ -0,0 +1,21 @@ +SETLOCAL EnableDelayedExpansion + +@REM # Possibilities: +@REM # Debug build + coverage +@REM # Debug build + examples +@REM # Debug build + --- +@REM # Release build +if "%CONFIGURATION%"=="Debug" ( + if "%coverage%"=="1" ( + @REM # coverage needs to build the special helper as well as the main + cmake -Htools/misc -Bbuild-misc -A%PLATFORM% || exit /b !ERRORLEVEL! + cmake --build build-misc || exit /b !ERRORLEVEL! + cmake -H. -BBuild -A%PLATFORM% -DCATCH_TEST_USE_WMAIN=%wmain% -DMEMORYCHECK_COMMAND=build-misc\Debug\CoverageHelper.exe -DMEMORYCHECK_COMMAND_OPTIONS=--sep-- -DMEMORYCHECK_TYPE=Valgrind -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% -DCATCH_ENABLE_CONFIGURE_TESTS=%configure_tests% -DCATCH_DEVELOPMENT_BUILD=ON || exit /b !ERRORLEVEL! + ) else ( + @REM # We know that coverage is 0 + cmake -H. -BBuild -A%PLATFORM% -DCATCH_TEST_USE_WMAIN=%wmain% -DCATCH_BUILD_EXAMPLES=%examples% -DCATCH_BUILD_EXTRA_TESTS=%examples% -DCATCH_BUILD_SURROGATES=%surrogates% -DCATCH_DEVELOPMENT_BUILD=ON -DCATCH_ENABLE_CONFIGURE_TESTS=%configure_tests% || exit /b !ERRORLEVEL! + ) +) +if "%CONFIGURATION%"=="Release" ( + cmake -H. -BBuild -A%PLATFORM% -DCATCH_TEST_USE_WMAIN=%wmain% -DCATCH_DEVELOPMENT_BUILD=ON || exit /b !ERRORLEVEL! +) diff --git a/contrib/catch2/tools/misc/appveyorMergeCoverageScript.py b/contrib/catch2/tools/misc/appveyorMergeCoverageScript.py new file mode 100644 index 0000000..5b71f6e --- /dev/null +++ b/contrib/catch2/tools/misc/appveyorMergeCoverageScript.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +import glob +import subprocess + +if __name__ == '__main__': + cov_files = list(glob.glob('tests/cov-report*.bin')) + base_cmd = ['OpenCppCoverage', '--quiet', '--export_type=cobertura:cobertura.xml'] + ['--input_coverage={}'.format(f) for f in cov_files] + subprocess.check_call(base_cmd) diff --git a/contrib/catch2/tools/misc/appveyorTestRunScript.bat b/contrib/catch2/tools/misc/appveyorTestRunScript.bat new file mode 100644 index 0000000..661bae2 --- /dev/null +++ b/contrib/catch2/tools/misc/appveyorTestRunScript.bat @@ -0,0 +1,17 @@ +SETLOCAL EnableDelayedExpansion + +rem Disable launching the JIT debugger for ctest.exe +reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\AutoExclusionList" /v "ctest.ext" /t REG_DWORD /d 1 +cd Build +if "%CONFIGURATION%"=="Debug" ( + if "%coverage%"=="1" ( + ctest -j 2 -C %CONFIGURATION% -D ExperimentalMemCheck -LE uses-signals || exit /b !ERRORLEVEL! + python ..\tools\misc\appveyorMergeCoverageScript.py || exit /b !ERRORLEVEL! + codecov --root .. --no-color --disable gcov -f cobertura.xml -t %CODECOV_TOKEN% || exit /b !ERRORLEVEL! + ) else ( + ctest -j 2 -C %CONFIGURATION% || exit /b !ERRORLEVEL! + ) +) +if "%CONFIGURATION%"=="Release" ( + ctest -j 2 -C %CONFIGURATION% || exit /b !ERRORLEVEL! +) diff --git a/contrib/catch2/tools/misc/coverage-helper.cpp b/contrib/catch2/tools/misc/coverage-helper.cpp new file mode 100644 index 0000000..9e7a8ca --- /dev/null +++ b/contrib/catch2/tools/misc/coverage-helper.cpp @@ -0,0 +1,142 @@ +#include <algorithm> +#include <array> +#include <cassert> +#include <fstream> +#include <iostream> +#include <memory> +#include <numeric> +#include <regex> +#include <string> +#include <vector> + +std::string escape_arg(const std::string& arg) { + if (arg.empty() == false && + arg.find_first_of(" \t\n\v\"") == arg.npos) { + return arg; + } + + std::string escaped; + escaped.push_back('"'); + for (auto it = arg.begin(); ; ++it) { + int num_backslashes = 0; + + while (it != arg.end() && *it == '\\') { + ++it; + ++num_backslashes; + } + + if (it == arg.end()) { + escaped.append(num_backslashes * 2, '\\'); + break; + } else if (*it == '"') { + escaped.append((num_backslashes + 1) * 2, '\\'); + escaped.push_back('"'); + escaped.push_back(*it); + } else { + escaped.append(num_backslashes, '\\'); + escaped.push_back(*it); + } + } + escaped.push_back('"'); + + return escaped; +} + + +void create_empty_file(std::string const& path) { + std::ofstream ofs(path); + ofs << '\n'; +} + +const std::string separator = "--sep--"; +const std::string logfile_prefix = "--log-file="; + +bool starts_with(std::string const& str, std::string const& pref) { + return str.find(pref) == 0; +} + +int parse_log_file_arg(std::string const& arg) { + assert(starts_with(arg, logfile_prefix) && "Attempting to parse incorrect arg!"); + auto fname = arg.substr(logfile_prefix.size()); + create_empty_file(fname); + std::regex regex("MemoryChecker\\.(\\d+)\\.log", std::regex::icase); + std::smatch match; + if (std::regex_search(fname, match, regex)) { + return std::stoi(match[1]); + } else { + throw std::domain_error("Couldn't find desired expression in string: " + fname); + } +} + +std::string catch_path(std::string path) { + auto start = path.find("catch"); + // try capitalized instead + if (start == std::string::npos) { + start = path.find("Catch"); + } + if (start == std::string::npos) { + throw std::domain_error("Couldn't find Catch's base path"); + } + auto end = path.find_first_of("\\/", start); + return path.substr(0, end); +} + +std::string windowsify_path(std::string path) { + for (auto& c : path) { + if (c == '/') { + c = '\\'; + } + } + return path; +} + +int exec_cmd(std::string const& cmd, int log_num, std::string const& path) { + std::array<char, 128> buffer; + + // cmd has already been escaped outside this function. + auto real_cmd = "OpenCppCoverage --export_type binary:cov-report" + std::to_string(log_num) + + ".bin --quiet " + "--sources " + escape_arg(path) + "\\src" + " --cover_children -- " + cmd; + std::cout << "=== Marker ===: Cmd: " << real_cmd << '\n'; + auto pipe = _popen(real_cmd.c_str(), "r"); + + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (!feof(pipe)) { + if (fgets(buffer.data(), 128, pipe) != nullptr) { + std::cout << buffer.data(); + } + } + + auto ret = _pclose(pipe); + if (ret == -1) { + throw std::runtime_error("underlying error in pclose()"); + } + + return ret; +} + +// argv should be: +// [0]: our path +// [1]: "--log-file=<path>" +// [2]: "--sep--" +// [3]+: the actual command + +int main(int argc, char** argv) { + std::vector<std::string> args(argv, argv + argc); + auto sep = std::find(begin(args), end(args), separator); + assert(sep - begin(args) == 2 && "Structure differs from expected!"); + + auto num = parse_log_file_arg(args[1]); + + auto cmdline = std::accumulate(++sep, end(args), std::string{}, [] (const std::string& lhs, const std::string& rhs) { + return lhs + ' ' + escape_arg(rhs); + }); + + try { + return exec_cmd(cmdline, num, windowsify_path(catch_path(args[0]))); + } catch (std::exception const& ex) { + std::cerr << "Helper failed with: '" << ex.what() << "'\n"; + return 12; + } +} diff --git a/contrib/catch2/tools/misc/installOpenCppCoverage.ps1 b/contrib/catch2/tools/misc/installOpenCppCoverage.ps1 new file mode 100644 index 0000000..215fe20 --- /dev/null +++ b/contrib/catch2/tools/misc/installOpenCppCoverage.ps1 @@ -0,0 +1,19 @@ +# Downloads are done from the official github release page links +$downloadUrl = "https://github.com/OpenCppCoverage/OpenCppCoverage/releases/download/release-0.9.9.0/OpenCppCoverageSetup-x64-0.9.9.0.exe" +$installerPath = [System.IO.Path]::Combine($Env:USERPROFILE, "Downloads", "OpenCppCoverageSetup.exe") + +if(-Not (Test-Path $installerPath)) { + Write-Host -ForegroundColor White ("Downloading OpenCppCoverage from: " + $downloadUrl) + Start-FileDownload $downloadUrl -FileName $installerPath +} + +Write-Host -ForegroundColor White "About to install OpenCppCoverage..." + +$installProcess = (Start-Process $installerPath -ArgumentList '/VERYSILENT' -PassThru -Wait) +if($installProcess.ExitCode -ne 0) { + throw [System.String]::Format("Failed to install OpenCppCoverage, ExitCode: {0}.", $installProcess.ExitCode) +} + +# Assume standard, boring, installation path of ".../Program Files/OpenCppCoverage" +$installPath = [System.IO.Path]::Combine(${Env:ProgramFiles}, "OpenCppCoverage") +$env:Path="$env:Path;$installPath" |
