Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tools/scripts
diff options
context:
space:
mode:
authorLeitwolf2026-10-25 10:31:36 +0300
committerGitHub2026-10-25 10:31:36 +0300
commitd2e3e074bb2e1b8ffd9fc990d0b87667ea602f58 (patch)
tree0bce4462b2e190c39b3e1c5f697e3e4abd1a5e2a /tools/scripts
parent13f81a480a93807c14dddb5abdb97355ced4d4c5 (diff)
parent126dc333564cb72b5115d9a9242d66694694b6d0 (diff)
downloadcatch3-d2e3e074bb2e1b8ffd9fc990d0b87667ea602f58.tar.gz
Merge pull request #18 from Progmasoft/build/catch3-identity
Give Catch3 its own build names and headers
Diffstat (limited to 'tools/scripts')
-rwxr-xr-xtools/scripts/checkConvenienceHeaders.py140
-rwxr-xr-xtools/scripts/checkDuplicateFilenames.py18
-rwxr-xr-xtools/scripts/checkLicense.py16
-rwxr-xr-xtools/scripts/generateAmalgamatedFiles.py37
-rw-r--r--tools/scripts/releaseCommon.py6
-rw-r--r--tools/scripts/scriptCommon.py7
-rw-r--r--tools/scripts/upstreamFiles.txt246
7 files changed, 374 insertions, 96 deletions
diff --git a/tools/scripts/checkConvenienceHeaders.py b/tools/scripts/checkConvenienceHeaders.py
index 06957524..6a8b7bc3 100755
--- a/tools/scripts/checkConvenienceHeaders.py
+++ b/tools/scripts/checkConvenienceHeaders.py
@@ -1,68 +1,73 @@
#!/usr/bin/env python3
"""
-Checks that all of the "catch_foo_all.hpp" headers include all subheaders.
+Checks that all of the "All.hpp" headers of the engine include all subheaders.
-The logic is simple: given a folder, e.g. `catch2/matchers`, then the
-ccorresponding header is called `catch_matchers_all.hpp` and contains
-* all headers in `catch2/matchers`,
-* all headers in `catch2/matchers/{internal, detail}`,
-* all convenience catch_matchers_*_all.hpp headers from any non-internal subfolders
+The logic is simple: given a folder, e.g. `Progmasoft/Catch3/Matchers`, the
+corresponding header is `Progmasoft/Catch3/Matchers/All.hpp` and contains
+* all engine headers in `Progmasoft/Catch3/Matchers`,
+* all engine headers in `Progmasoft/Catch3/Matchers/{Internal, Detail}`,
+* the `All.hpp` headers of its other subfolders that hold engine headers.
-The top level header is called `catch_all.hpp`.
+The top level header is `Progmasoft/Catch3/All.hpp`. Engine headers are the
+ones listed in upstreamFiles.txt; Progmasoft's own headers in the same
+folders are not part of the convenience headers.
"""
-internal_dirs = ['detail', 'internal']
+internal_dirs = ['Detail', 'Internal']
-from scriptCommon import catchPath
-from glob import glob
-from pprint import pprint
+from scriptCommon import catchPath, upstreamFiles
import os
import re
+import sys
-def normalized_path(path):
- r"""Replaces \ in paths on Windows with /"""
- return path.replace('\\', '/')
+source_root = 'src/Progmasoft/Catch3'
+include_parser = re.compile(r'#include <(Progmasoft/Catch3/.+\.hpp)>')
+engine_headers = {path[len('src/'):] for path in upstreamFiles() if path.endswith('.hpp')}
-def normalized_paths(paths):
- r"""Replaces \ with / in every path"""
- return [normalized_path(path) for path in paths]
+errors_found = False
-source_path = catchPath + '/src/catch2'
-source_path = normalized_path(source_path)
-include_parser = re.compile(r'#include <(catch2/.+\.hpp)>')
-errors_found = False
+def engine_headers_in(folder):
+ """Engine headers directly in folder, as include paths."""
+ prefix = folder + '/'
+ return sorted(h for h in engine_headers
+ if h.startswith(prefix) and '/' not in h[len(prefix):])
-def headers_in_folder(folder):
- return glob(folder + '/*.hpp')
-def folders_in_folder(folder):
- return [x for x in os.scandir(folder) if x.is_dir()]
+def subfolders_with_engine_headers(folder):
+ prefix = folder + '/'
+ names = set()
+ for header in engine_headers:
+ if header.startswith(prefix):
+ rest = header[len(prefix):]
+ if '/' in rest:
+ names.add(rest.split('/')[0])
+ return sorted(names)
+
def collated_includes(folder):
- base = headers_in_folder(folder)
- for subfolder in folders_in_folder(folder):
- if subfolder.name in internal_dirs:
- base.extend(headers_in_folder(subfolder.path))
+ base = engine_headers_in(folder)
+ for name in subfolders_with_engine_headers(folder):
+ subfolder = folder + '/' + name
+ if name in internal_dirs:
+ base.extend(engine_headers_in(subfolder))
else:
- base.append(subfolder.path + '/catch_{}_all.hpp'.format(subfolder.name))
- return normalized_paths(sorted(base))
+ base.append(subfolder + '/All.hpp')
+ return sorted(base)
+
def includes_from_file(header):
includes = []
- with open(header, 'r', encoding = 'utf-8') as file:
+ with open(os.path.join(catchPath, 'src', header), 'r', encoding='utf-8') as file:
for line in file:
if not line.startswith('#include'):
continue
match = include_parser.match(line)
if match:
includes.append(match.group(1))
- return normalized_paths(includes)
+ return includes
-def normalize_includes(includes):
- """Returns """
- return [include[len(catchPath)+5:] for include in includes]
def get_duplicates(xs):
seen = set()
@@ -73,55 +78,42 @@ def get_duplicates(xs):
seen.add(x)
return duplicated
+
def verify_convenience_header(folder):
"""
- Performs the actual checking of convenience header for specific folder.
- Checks that
- 1) The header even exists
- 2) That all includes in the header are sorted
- 3) That there are no duplicated includes
- 4) That all includes that should be in the header are actually present in the header
- 5) That there are no superfluous includes that should not be in the header
+ Checks the convenience header of one folder:
+ 1) The header exists
+ 2) Its includes are sorted
+ 3) It has no duplicated includes
+ 4) It includes every header it should
+ 5) It includes nothing else
"""
global errors_found
-
- path = normalized_path(folder.path)
-
- assert path.startswith(source_path), '{} does not start with {}'.format(path, source_path)
- stripped_path = path[len(source_path) + 1:]
- path_pieces = stripped_path.split('/')
-
- if path == source_path:
- header_name = 'catch_all.hpp'
- else:
- header_name = 'catch_{}_all.hpp'.format('_'.join(path_pieces))
+ header_name = folder + '/All.hpp'
# 1) Does it exist?
- full_path = path + '/' + header_name
- if not os.path.isfile(full_path):
+ if header_name not in engine_headers:
errors_found = True
- print('Missing convenience header: {}'.format(full_path))
+ print('Missing convenience header: {}'.format(header_name))
return
- file_incs = includes_from_file(path + '/' + header_name)
- # 2) Are the includes are sorted?
+ file_incs = includes_from_file(header_name)
+ # 2) Are the includes sorted?
if sorted(file_incs) != file_incs:
errors_found = True
print("'{}': Includes are not in sorted order!".format(header_name))
# 3) Are there no duplicates?
- duplicated = get_duplicates(file_incs)
- for duplicate in duplicated:
+ for duplicate in get_duplicates(file_incs):
errors_found = True
print("'{}': Duplicated include: '{}'".format(header_name, duplicate))
- target_includes = normalize_includes(collated_includes(path))
- # Avoid requiring the convenience header to include itself
- target_includes = [x for x in target_includes if header_name not in x]
+ # The convenience header does not include itself.
+ target_includes = [x for x in collated_includes(folder) if x != header_name]
# 4) Are all required headers present?
file_incs_set = set(file_incs)
for include in target_includes:
if (include not in file_incs_set and
- include != 'catch2/internal/catch_windows_h_proxy.hpp'):
+ include != 'Progmasoft/Catch3/Internal/WindowsHProxy.hpp'):
errors_found = True
print("'{}': missing include '{}'".format(header_name, include))
@@ -133,19 +125,17 @@ def verify_convenience_header(folder):
print("'{}': superfluous include '{}'".format(header_name, include))
+def walk_source_folders(folder):
+ verify_convenience_header(folder)
+ for name in subfolders_with_engine_headers(folder):
+ if name not in internal_dirs:
+ walk_source_folders(folder + '/' + name)
-def walk_source_folders(current):
- verify_convenience_header(current)
- for folder in folders_in_folder(current.path):
- fname = folder.name
- if fname not in internal_dirs:
- walk_source_folders(folder)
-# This is an ugly hack because we cannot instantiate DirEntry manually
-base_dir = [x for x in os.scandir(catchPath + '/src') if x.name == 'catch2']
-walk_source_folders(base_dir[0])
+walk_source_folders('Progmasoft/Catch3')
# Propagate error "code" upwards
if not errors_found:
print('Everything ok')
-exit(errors_found)
+else:
+ sys.exit(1)
diff --git a/tools/scripts/checkDuplicateFilenames.py b/tools/scripts/checkDuplicateFilenames.py
index b46a2b4b..0a68d504 100755
--- a/tools/scripts/checkDuplicateFilenames.py
+++ b/tools/scripts/checkDuplicateFilenames.py
@@ -1,12 +1,28 @@
#!/usr/bin/env python3
+# Copyright Catch2 Authors
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE.txt or copy at
+# https://www.boost.org/LICENSE_1_0.txt)
+
+# SPDX-License-Identifier: BSL-1.0
+
+"""Checks that no two source files of the library share a file name.
+
+Build tools that keep object files in one directory, such as Visual Studio
+projects, would otherwise compile one over the other. Headers may share
+names: they are always included with their directory.
+"""
+
import os
import sys
files_set = set()
-for root, dir, files in os.walk("src/catch2"):
+for root, dir, files in os.walk("src/Progmasoft"):
for file in files:
+ if not file.endswith('.cpp'):
+ continue
if file not in files_set:
files_set.add(file)
else:
diff --git a/tools/scripts/checkLicense.py b/tools/scripts/checkLicense.py
index 827c94b7..9e1e24ae 100755
--- a/tools/scripts/checkLicense.py
+++ b/tools/scripts/checkLicense.py
@@ -4,6 +4,8 @@ import sys
import glob
from pathlib import Path
+from scriptCommon import upstreamFiles
+
correct_licence = """\
// Copyright Catch2 Authors
@@ -19,11 +21,15 @@ progmasoft_licence = """\
// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-1.1
"""
+upstream_files = upstreamFiles()
+
def check_licence_in_file(filename: str) -> bool:
- # Keep upstream files on BSL-1.0 while checking the fork's own source
- # and tests against their separate MPL exception header.
- expected = (progmasoft_licence if 'Progmasoft' in Path(filename).parts
- else correct_licence)
+ # Files that come from Catch2 keep BSL-1.0; the fork's own source and
+ # tests carry the MPL header with Progmasoft's exception.
+ relative = filename.replace('\\', '/')
+ progmasoft = ('Progmasoft' in Path(filename).parts
+ and relative not in upstream_files)
+ expected = progmasoft_licence if progmasoft else correct_licence
with open(filename, 'r', encoding='utf-8') as f:
file_preamble = f.read(len(expected))
@@ -44,7 +50,7 @@ def check_licences_in_path(path: str) -> int:
def check_licences():
failed = 0
# Add 'extras' after the amalgamated files are regenerated with the new script (past 3.4.0)
- roots = ['src/catch2', 'src/Progmasoft', 'tests', 'examples', 'fuzzing']
+ roots = ['src/Progmasoft', 'tests', 'examples', 'fuzzing']
for root in roots:
failed += check_licences_in_path(root)
diff --git a/tools/scripts/generateAmalgamatedFiles.py b/tools/scripts/generateAmalgamatedFiles.py
index 2d40bcb4..ffd069ef 100755
--- a/tools/scripts/generateAmalgamatedFiles.py
+++ b/tools/scripts/generateAmalgamatedFiles.py
@@ -9,11 +9,11 @@ import os
import re
import datetime
-from scriptCommon import catchPath
+from scriptCommon import catchPath, upstreamFiles
from releaseCommon import Version
root_path = os.path.join(catchPath, 'src')
-starting_header = os.path.join(root_path, 'catch2', 'catch_all.hpp')
+starting_header = os.path.join(root_path, 'Progmasoft', 'Catch3', 'All.hpp')
output_header = os.path.join(catchPath, 'extras', 'catch_amalgamated.hpp')
output_cpp = os.path.join(catchPath, 'extras', 'catch_amalgamated.cpp')
@@ -71,16 +71,28 @@ def formatted_file_header(version):
# processed again)
concatenated_headers = set()
-internal_include_parser = re.compile(r'\s*#include <(catch2/.*)>.*')
+# The engine's files are the ones that come from Catch2.
+upstream_files = upstreamFiles()
+include_parser = re.compile(r'\s*#include <(Progmasoft/Catch3/[^>]+)>.*')
+
+
+def engine_include(line):
+ """The engine header a line includes, or None."""
+ m = include_parser.match(line)
+ # The configuration header is generated from UserConfig.hpp.in.
+ if m and ('src/' + m.group(1) in upstream_files
+ or m.group(1) == 'Progmasoft/Catch3/UserConfig.hpp'):
+ return m.group(1)
+ return None
def concatenate_file(out, filename: str, expand_headers: bool) -> int:
# Gathers statistics on how many headers were expanded
concatenated = 1
with open(filename, mode='r', encoding='utf-8') as input:
for line in input:
- if line in copyright_lines:
+ if line in copyright_lines or line.strip() == '#pragma once':
continue
- m = internal_include_parser.match(line)
+ m = engine_include(line)
# The runner's headers are expanded at the start of the .cpp file.
if not m and not expand_headers and progmasoft_include_parser.match(line):
continue
@@ -99,7 +111,7 @@ def concatenate_file(out, filename: str, expand_headers: bool) -> int:
if not expand_headers:
continue
- next_header = m.group(1)
+ next_header = m
# We have to avoid re-expanding the same header over and
# over again, or the header will end up with couple
# hundred thousands lines (~300k as of preview3 :-) )
@@ -110,7 +122,7 @@ def concatenate_file(out, filename: str, expand_headers: bool) -> int:
# because it has not been generated yet at this point.
# The code around it should be written so that just not including
# it is equivalent with all-default user configuration.
- if next_header == 'catch2/catch_user_config.hpp':
+ if next_header == 'Progmasoft/Catch3/UserConfig.hpp':
concatenated_headers.add(next_header)
continue
@@ -142,8 +154,8 @@ def concatenate_runner_file(out, filename: str, expand_headers: bool):
for line in input:
if line.strip() == '#pragma once':
continue
- # Catch2's own headers are all in the amalgamated header.
- if internal_include_parser.match(line):
+ # The engine's headers are all in the amalgamated header.
+ if engine_include(line):
continue
m = progmasoft_include_parser.match(line)
if not m:
@@ -161,7 +173,8 @@ def concatenate_runner_file(out, filename: str, expand_headers: bool):
def generate_cpp():
from glob import glob
- cpp_files = sorted(glob(os.path.join(root_path, 'catch2', '**/*.cpp'), recursive=True))
+ cpp_files = sorted(os.path.join(catchPath, path) for path in upstream_files
+ if path.endswith('.cpp'))
runner_headers = sorted(glob(os.path.join(root_path, 'Progmasoft', 'Runner', '*.hpp'))) + [
os.path.join(root_path, 'Progmasoft', 'Catch3', name)
for name in ('Results.hpp', 'Runner.hpp', 'Version.hpp', 'XmlWriter.hpp')]
@@ -171,7 +184,7 @@ def generate_cpp():
with open(output_cpp, mode='w', encoding='utf-8') as cpp:
cpp.write(formatted_file_header(Version()))
cpp.write('\n#include "catch_amalgamated.hpp"\n')
- concatenate_file(cpp, os.path.join(root_path, 'catch2/internal/catch_windows_h_proxy.hpp'), False)
+ concatenate_file(cpp, os.path.join(root_path, 'Progmasoft/Catch3/Internal/WindowsHProxy.hpp'), False)
# The runner's headers come first: Catch::Session reaches the runner.
for header in runner_headers:
header = os.path.normpath(header)
@@ -195,6 +208,6 @@ if __name__ == "__main__":
# * The .cpp file needs to start with `#include "catch_amalgamated.hpp"
# * include guards can be left/stripped, doesn't matter
# * *.cpp files should be included sorted, to minimize diffs between versions
-# * *.hpp files should also be somehow sorted -> use catch_all.hpp as the
+# * *.hpp files should also be somehow sorted -> use Progmasoft/Catch3/All.hpp as the
# * entrypoint
# * allow disabling main in the .cpp amalgamation
diff --git a/tools/scripts/releaseCommon.py b/tools/scripts/releaseCommon.py
index cbdd92e1..42c57baf 100644
--- a/tools/scripts/releaseCommon.py
+++ b/tools/scripts/releaseCommon.py
@@ -4,11 +4,11 @@ import re
from scriptCommon import catchPath
versionParser = re.compile( r'(\s*static\sVersion\sversion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' )
-rootPath = os.path.join( catchPath, 'src/catch2' )
-versionPath = os.path.join( rootPath, "catch_version.cpp" )
+rootPath = os.path.join( catchPath, 'src/Progmasoft/Catch3' )
+versionPath = os.path.join( rootPath, "EngineVersion.cpp" )
class Version:
- """The version of the Catch2 compatibility engine, from catch_version.cpp."""
+ """The version of the Catch2 compatibility engine, from Progmasoft/Catch3/EngineVersion.cpp."""
def __init__(self):
f = open( versionPath, 'r' )
for line in f:
diff --git a/tools/scripts/scriptCommon.py b/tools/scripts/scriptCommon.py
index 5894185d..f64ef01d 100644
--- a/tools/scripts/scriptCommon.py
+++ b/tools/scripts/scriptCommon.py
@@ -2,3 +2,10 @@ import os
import sys
catchPath = os.path.dirname(os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0]))))
+
+
+def upstreamFiles():
+ """The files below src/Progmasoft that come from Catch2, relative to the
+ repository with forward slashes; see upstreamFiles.txt."""
+ with open(os.path.join(catchPath, 'tools', 'scripts', 'upstreamFiles.txt'), encoding='utf-8') as listing:
+ return {line.strip() for line in listing if line.strip() and not line.startswith('#')}
diff --git a/tools/scripts/upstreamFiles.txt b/tools/scripts/upstreamFiles.txt
new file mode 100644
index 00000000..e6999ff5
--- /dev/null
+++ b/tools/scripts/upstreamFiles.txt
@@ -0,0 +1,246 @@
+# Files of src/Progmasoft that come from Catch2 and keep its license
+# (BSL-1.0). Every other file below src/Progmasoft is Progmasoft's own.
+src/Progmasoft/Catch3/All.hpp
+src/Progmasoft/Catch3/Approx.cpp
+src/Progmasoft/Catch3/Approx.hpp
+src/Progmasoft/Catch3/AssertionInfo.hpp
+src/Progmasoft/Catch3/AssertionResult.cpp
+src/Progmasoft/Catch3/AssertionResult.hpp
+src/Progmasoft/Catch3/Benchmark/All.hpp
+src/Progmasoft/Catch3/Benchmark/Benchmark.cpp
+src/Progmasoft/Catch3/Benchmark/Benchmark.hpp
+src/Progmasoft/Catch3/Benchmark/Chronometer.cpp
+src/Progmasoft/Catch3/Benchmark/Chronometer.hpp
+src/Progmasoft/Catch3/Benchmark/Clock.hpp
+src/Progmasoft/Catch3/Benchmark/Constructor.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/Analyse.cpp
+src/Progmasoft/Catch3/Benchmark/Detail/Analyse.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/BenchmarkFunction.cpp
+src/Progmasoft/Catch3/Benchmark/Detail/BenchmarkFunction.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/BenchmarkStats.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/BenchmarkStatsFwd.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/CompleteInvoke.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/EstimateClock.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/Measure.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/Repeat.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/RunForAtLeast.cpp
+src/Progmasoft/Catch3/Benchmark/Detail/RunForAtLeast.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/Stats.cpp
+src/Progmasoft/Catch3/Benchmark/Detail/Stats.hpp
+src/Progmasoft/Catch3/Benchmark/Detail/Timing.hpp
+src/Progmasoft/Catch3/Benchmark/Environment.hpp
+src/Progmasoft/Catch3/Benchmark/Estimate.hpp
+src/Progmasoft/Catch3/Benchmark/ExecutionPlan.hpp
+src/Progmasoft/Catch3/Benchmark/Optimizer.hpp
+src/Progmasoft/Catch3/Benchmark/OutlierClassification.hpp
+src/Progmasoft/Catch3/Benchmark/SampleAnalysis.hpp
+src/Progmasoft/Catch3/CaseSensitive.hpp
+src/Progmasoft/Catch3/Config.cpp
+src/Progmasoft/Catch3/Config.hpp
+src/Progmasoft/Catch3/EngineVersion.cpp
+src/Progmasoft/Catch3/EngineVersion.hpp
+src/Progmasoft/Catch3/EngineVersionMacros.hpp
+src/Progmasoft/Catch3/Generators/Adapters.hpp
+src/Progmasoft/Catch3/Generators/All.hpp
+src/Progmasoft/Catch3/Generators/GeneratorException.cpp
+src/Progmasoft/Catch3/Generators/GeneratorException.hpp
+src/Progmasoft/Catch3/Generators/Generators.cpp
+src/Progmasoft/Catch3/Generators/Generators.hpp
+src/Progmasoft/Catch3/Generators/Random.cpp
+src/Progmasoft/Catch3/Generators/Random.hpp
+src/Progmasoft/Catch3/Generators/Range.hpp
+src/Progmasoft/Catch3/Generators/Throw.cpp
+src/Progmasoft/Catch3/Generators/Throw.hpp
+src/Progmasoft/Catch3/GetRandomSeed.cpp
+src/Progmasoft/Catch3/GetRandomSeed.hpp
+src/Progmasoft/Catch3/Interfaces/All.hpp
+src/Progmasoft/Catch3/Interfaces/EventListenerFactory.cpp
+src/Progmasoft/Catch3/Interfaces/EventListenerFactory.hpp
+src/Progmasoft/Catch3/Interfaces/IConfig.cpp
+src/Progmasoft/Catch3/Interfaces/IConfig.hpp
+src/Progmasoft/Catch3/Interfaces/IEventListener.cpp
+src/Progmasoft/Catch3/Interfaces/IEventListener.hpp
+src/Progmasoft/Catch3/Interfaces/IExceptionTranslator.cpp
+src/Progmasoft/Catch3/Interfaces/IExceptionTranslator.hpp
+src/Progmasoft/Catch3/Interfaces/IGeneratorTracker.cpp
+src/Progmasoft/Catch3/Interfaces/IGeneratorTracker.hpp
+src/Progmasoft/Catch3/Interfaces/IRegistryHub.cpp
+src/Progmasoft/Catch3/Interfaces/IRegistryHub.hpp
+src/Progmasoft/Catch3/Interfaces/IResultCapture.cpp
+src/Progmasoft/Catch3/Interfaces/IResultCapture.hpp
+src/Progmasoft/Catch3/Interfaces/ITagAliasRegistry.hpp
+src/Progmasoft/Catch3/Interfaces/ITestCaseRegistry.cpp
+src/Progmasoft/Catch3/Interfaces/ITestCaseRegistry.hpp
+src/Progmasoft/Catch3/Interfaces/ITestInvoker.hpp
+src/Progmasoft/Catch3/Internal/AssertionHandler.cpp
+src/Progmasoft/Catch3/Internal/AssertionHandler.hpp
+src/Progmasoft/Catch3/Internal/CaseInsensitiveComparisons.cpp
+src/Progmasoft/Catch3/Internal/CaseInsensitiveComparisons.hpp
+src/Progmasoft/Catch3/Internal/CompareTraits.hpp
+src/Progmasoft/Catch3/Internal/CompilerCapabilities.hpp
+src/Progmasoft/Catch3/Internal/ConfigAndroidLogWrite.hpp
+src/Progmasoft/Catch3/Internal/ConfigCounter.hpp
+src/Progmasoft/Catch3/Internal/ConfigPrefixMessages.hpp
+src/Progmasoft/Catch3/Internal/ConfigStaticAnalysisSupport.hpp
+src/Progmasoft/Catch3/Internal/ConfigUncaughtExceptions.hpp
+src/Progmasoft/Catch3/Internal/ConfigWchar.hpp
+src/Progmasoft/Catch3/Internal/ContainerNonMembers.hpp
+src/Progmasoft/Catch3/Internal/Context.cpp
+src/Progmasoft/Catch3/Internal/Context.hpp
+src/Progmasoft/Catch3/Internal/Debugger.cpp
+src/Progmasoft/Catch3/Internal/Debugger.hpp
+src/Progmasoft/Catch3/Internal/Decomposer.cpp
+src/Progmasoft/Catch3/Internal/Decomposer.hpp
+src/Progmasoft/Catch3/Internal/DeprecationMacro.hpp
+src/Progmasoft/Catch3/Internal/Enforce.cpp
+src/Progmasoft/Catch3/Internal/Enforce.hpp
+src/Progmasoft/Catch3/Internal/EnumInfo.cpp
+src/Progmasoft/Catch3/Internal/EnumInfo.hpp
+src/Progmasoft/Catch3/Internal/ErrnoGuard.cpp
+src/Progmasoft/Catch3/Internal/ErrnoGuard.hpp
+src/Progmasoft/Catch3/Internal/ExceptionTranslatorRegistry.cpp
+src/Progmasoft/Catch3/Internal/ExceptionTranslatorRegistry.hpp
+src/Progmasoft/Catch3/Internal/FatalConditionHandler.cpp
+src/Progmasoft/Catch3/Internal/FatalConditionHandler.hpp
+src/Progmasoft/Catch3/Internal/FloatingPointHelpers.cpp
+src/Progmasoft/Catch3/Internal/FloatingPointHelpers.hpp
+src/Progmasoft/Catch3/Internal/GetEnv.cpp
+src/Progmasoft/Catch3/Internal/GetEnv.hpp
+src/Progmasoft/Catch3/Internal/IsPermutation.hpp
+src/Progmasoft/Catch3/Internal/LazyExpr.cpp
+src/Progmasoft/Catch3/Internal/LazyExpr.hpp
+src/Progmasoft/Catch3/Internal/LeakDetector.cpp
+src/Progmasoft/Catch3/Internal/LeakDetector.hpp
+src/Progmasoft/Catch3/Internal/LifetimeBound.hpp
+src/Progmasoft/Catch3/Internal/LogicalTraits.hpp
+src/Progmasoft/Catch3/Internal/Main.cpp
+src/Progmasoft/Catch3/Internal/MessageInfo.cpp
+src/Progmasoft/Catch3/Internal/MessageInfo.hpp
+src/Progmasoft/Catch3/Internal/Meta.hpp
+src/Progmasoft/Catch3/Internal/MoveAndForward.hpp
+src/Progmasoft/Catch3/Internal/NonCopyable.hpp
+src/Progmasoft/Catch3/Internal/Optional.hpp
+src/Progmasoft/Catch3/Internal/OutputRedirect.cpp
+src/Progmasoft/Catch3/Internal/OutputRedirect.hpp
+src/Progmasoft/Catch3/Internal/ParseNumbers.cpp
+src/Progmasoft/Catch3/Internal/ParseNumbers.hpp
+src/Progmasoft/Catch3/Internal/PathFilter.hpp
+src/Progmasoft/Catch3/Internal/Platform.hpp
+src/Progmasoft/Catch3/Internal/Polyfills.cpp
+src/Progmasoft/Catch3/Internal/Polyfills.hpp
+src/Progmasoft/Catch3/Internal/Preprocessor.hpp
+src/Progmasoft/Catch3/Internal/PreprocessorInternalStringify.hpp
+src/Progmasoft/Catch3/Internal/PreprocessorRemoveParens.hpp
+src/Progmasoft/Catch3/Internal/RandomFloatingPointHelpers.hpp
+src/Progmasoft/Catch3/Internal/RandomIntegerHelpers.hpp
+src/Progmasoft/Catch3/Internal/RandomNumberGenerator.cpp
+src/Progmasoft/Catch3/Internal/RandomNumberGenerator.hpp
+src/Progmasoft/Catch3/Internal/RandomSeedGeneration.cpp
+src/Progmasoft/Catch3/Internal/RandomSeedGeneration.hpp
+src/Progmasoft/Catch3/Internal/ReporterRegistry.cpp
+src/Progmasoft/Catch3/Internal/ReporterRegistry.hpp
+src/Progmasoft/Catch3/Internal/ResultType.hpp
+src/Progmasoft/Catch3/Internal/ReusableStringStream.cpp
+src/Progmasoft/Catch3/Internal/ReusableStringStream.hpp
+src/Progmasoft/Catch3/Internal/RunContext.cpp
+src/Progmasoft/Catch3/Internal/RunContext.hpp
+src/Progmasoft/Catch3/Internal/Section.cpp
+src/Progmasoft/Catch3/Internal/Section.hpp
+src/Progmasoft/Catch3/Internal/Singletons.cpp
+src/Progmasoft/Catch3/Internal/Singletons.hpp
+src/Progmasoft/Catch3/Internal/SourceLineInfo.cpp
+src/Progmasoft/Catch3/Internal/SourceLineInfo.hpp
+src/Progmasoft/Catch3/Internal/StartupExceptionRegistry.cpp
+src/Progmasoft/Catch3/Internal/StartupExceptionRegistry.hpp
+src/Progmasoft/Catch3/Internal/StdStreams.cpp
+src/Progmasoft/Catch3/Internal/StdStreams.hpp
+src/Progmasoft/Catch3/Internal/StreamEndStop.hpp
+src/Progmasoft/Catch3/Internal/StringManip.cpp
+src/Progmasoft/Catch3/Internal/StringManip.hpp
+src/Progmasoft/Catch3/Internal/StringRef.cpp
+src/Progmasoft/Catch3/Internal/StringRef.hpp
+src/Progmasoft/Catch3/Internal/TagAliasRegistry.cpp
+src/Progmasoft/Catch3/Internal/TagAliasRegistry.hpp
+src/Progmasoft/Catch3/Internal/TemplateTestRegistry.hpp
+src/Progmasoft/Catch3/Internal/TestCaseInfoHasher.cpp
+src/Progmasoft/Catch3/Internal/TestCaseInfoHasher.hpp
+src/Progmasoft/Catch3/Internal/TestCaseRegistryImpl.cpp
+src/Progmasoft/Catch3/Internal/TestCaseRegistryImpl.hpp
+src/Progmasoft/Catch3/Internal/TestCaseTracker.cpp
+src/Progmasoft/Catch3/Internal/TestCaseTracker.hpp
+src/Progmasoft/Catch3/Internal/TestFailureException.cpp
+src/Progmasoft/Catch3/Internal/TestFailureException.hpp
+src/Progmasoft/Catch3/Internal/TestMacroImpl.hpp
+src/Progmasoft/Catch3/Internal/TestRegistry.cpp
+src/Progmasoft/Catch3/Internal/TestRegistry.hpp
+src/Progmasoft/Catch3/Internal/TestSpecParser.cpp
+src/Progmasoft/Catch3/Internal/TestSpecParser.hpp
+src/Progmasoft/Catch3/Internal/ThreadLocal.hpp
+src/Progmasoft/Catch3/Internal/ThreadSupport.hpp
+src/Progmasoft/Catch3/Internal/ToString.hpp
+src/Progmasoft/Catch3/Internal/UncaughtExceptions.cpp
+src/Progmasoft/Catch3/Internal/UncaughtExceptions.hpp
+src/Progmasoft/Catch3/Internal/UniformFloatingPointDistribution.hpp
+src/Progmasoft/Catch3/Internal/UniformIntegerDistribution.hpp
+src/Progmasoft/Catch3/Internal/UniqueName.hpp
+src/Progmasoft/Catch3/Internal/UniquePtr.hpp
+src/Progmasoft/Catch3/Internal/Unreachable.hpp
+src/Progmasoft/Catch3/Internal/VoidType.hpp
+src/Progmasoft/Catch3/Internal/WildcardPattern.cpp
+src/Progmasoft/Catch3/Internal/WildcardPattern.hpp
+src/Progmasoft/Catch3/Internal/WindowsHProxy.hpp
+src/Progmasoft/Catch3/Matchers/All.hpp
+src/Progmasoft/Catch3/Matchers/ContainerProperties.cpp
+src/Progmasoft/Catch3/Matchers/ContainerProperties.hpp
+src/Progmasoft/Catch3/Matchers/Contains.hpp
+src/Progmasoft/Catch3/Matchers/Exception.cpp
+src/Progmasoft/Catch3/Matchers/Exception.hpp
+src/Progmasoft/Catch3/Matchers/FloatingPoint.cpp
+src/Progmasoft/Catch3/Matchers/FloatingPoint.hpp
+src/Progmasoft/Catch3/Matchers/Internal/Impl.cpp
+src/Progmasoft/Catch3/Matchers/Internal/Impl.hpp
+src/Progmasoft/Catch3/Matchers/Matchers.cpp
+src/Progmasoft/Catch3/Matchers/Matchers.hpp
+src/Progmasoft/Catch3/Matchers/Predicate.cpp
+src/Progmasoft/Catch3/Matchers/Predicate.hpp
+src/Progmasoft/Catch3/Matchers/Quantifiers.cpp
+src/Progmasoft/Catch3/Matchers/Quantifiers.hpp
+src/Progmasoft/Catch3/Matchers/RangeEquals.hpp
+src/Progmasoft/Catch3/Matchers/String.cpp
+src/Progmasoft/Catch3/Matchers/String.hpp
+src/Progmasoft/Catch3/Matchers/Templated.cpp
+src/Progmasoft/Catch3/Matchers/Templated.hpp
+src/Progmasoft/Catch3/Matchers/Vector.hpp
+src/Progmasoft/Catch3/Message.cpp
+src/Progmasoft/Catch3/Message.hpp
+src/Progmasoft/Catch3/RegistryHub.cpp
+src/Progmasoft/Catch3/Reporters/All.hpp
+src/Progmasoft/Catch3/Reporters/EventListener.cpp
+src/Progmasoft/Catch3/Reporters/EventListener.hpp
+src/Progmasoft/Catch3/Reporters/Multi.cpp
+src/Progmasoft/Catch3/Reporters/Multi.hpp
+src/Progmasoft/Catch3/Reporters/Registrars.cpp
+src/Progmasoft/Catch3/Reporters/Registrars.hpp
+src/Progmasoft/Catch3/SectionInfo.hpp
+src/Progmasoft/Catch3/Session.cpp
+src/Progmasoft/Catch3/Session.hpp
+src/Progmasoft/Catch3/TagAlias.hpp
+src/Progmasoft/Catch3/TagAliasAutoregistrar.cpp
+src/Progmasoft/Catch3/TagAliasAutoregistrar.hpp
+src/Progmasoft/Catch3/TemplateTestMacros.hpp
+src/Progmasoft/Catch3/TestCaseInfo.cpp
+src/Progmasoft/Catch3/TestCaseInfo.hpp
+src/Progmasoft/Catch3/TestMacros.hpp
+src/Progmasoft/Catch3/TestRunInfo.hpp
+src/Progmasoft/Catch3/TestSpec.cpp
+src/Progmasoft/Catch3/TestSpec.hpp
+src/Progmasoft/Catch3/Timer.cpp
+src/Progmasoft/Catch3/Timer.hpp
+src/Progmasoft/Catch3/ToString.cpp
+src/Progmasoft/Catch3/ToString.hpp
+src/Progmasoft/Catch3/Totals.cpp
+src/Progmasoft/Catch3/Totals.hpp
+src/Progmasoft/Catch3/TranslateException.cpp
+src/Progmasoft/Catch3/TranslateException.hpp
+src/Progmasoft/Catch3/UserConfig.hpp.in
+src/Progmasoft/Catch3/meson.build