diff --git a/.clang-tidy b/.clang-tidy index cdfaf8b2..d861c0bf 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -13,6 +13,9 @@ Checks: "*, -readability-avoid-const-params-in-decls, -cppcoreguidelines-non-private-member-variables-in-classes, -misc-non-private-member-variables-in-classes, + -misc-no-recursion, + -misc-use-anonymous-namespace, + -misc-use-internal-linkage " WarningsAsErrors: '' HeaderFilterRegex: '' diff --git a/.github/workflows/auto-clang-format.yml b/.github/workflows/auto-clang-format.yml index b4e0a1b9..25b08afc 100644 --- a/.github/workflows/auto-clang-format.yml +++ b/.github/workflows/auto-clang-format.yml @@ -7,12 +7,12 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: DoozyX/clang-format-lint-action@v0.13 + - uses: DoozyX/clang-format-lint-action@v0.20 with: source: '.' exclude: './third_party ./external' extensions: 'h,cpp,hpp' - clangFormatVersion: 12 + clangFormatVersion: 19 inplace: True - uses: EndBug/add-and-commit@v4 with: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db6c6110..0ef3f36f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ on: - develop env: - CLANG_TIDY_VERSION: "15.0.2" + CLANG_TIDY_VERSION: "19.1.1" VERBOSE: 1 @@ -29,13 +29,13 @@ jobs: # and your own projects needs matrix: os: - - ubuntu-20.04 - - macos-10.15 - - windows-2019 + - ubuntu-latest + - macos-latest + - windows-latest compiler: # you can specify the version after `-` like "llvm-15.0.2". - - llvm-15.0.2 - - gcc-11 + - llvm-19.1.1 + - gcc-14 generator: - "Ninja Multi-Config" build_type: @@ -49,66 +49,66 @@ jobs: exclude: # mingw is determined by this author to be too buggy to support - - os: windows-2019 - compiler: gcc-11 + - os: windows-latest + compiler: gcc-14 include: # Add appropriate variables for gcov version required. This will intentionally break # if you try to use a compiler that does not have gcov set - - compiler: gcc-11 - gcov_executable: gcov + - compiler: gcc-14 + gcov_executable: gcov-14 enable_ipo: On - - compiler: llvm-15.0.2 + - compiler: llvm-19.1.1 enable_ipo: Off gcov_executable: "llvm-cov gcov" - - os: macos-10.15 + - os: macos-latest enable_ipo: Off # Set up preferred package generators, for given build configurations - build_type: Release - packaging_maintainer_mode: OFF + packaging_maintainer_mode: On package_generator: TBZ2 # This exists solely to make sure a non-multiconfig build works - - os: ubuntu-20.04 - compiler: gcc-11 + - os: ubuntu-latest + compiler: gcc-14 generator: "Unix Makefiles" build_type: Debug - gcov_executable: gcov + gcov_executable: gcov-14 packaging_maintainer_mode: On enable_ipo: Off # Windows msvc builds - - os: windows-2022 + - os: windows-latest compiler: msvc generator: "Visual Studio 17 2022" build_type: Debug packaging_maintainer_mode: On enable_ipo: On - - os: windows-2022 + - os: windows-latest compiler: msvc generator: "Visual Studio 17 2022" build_type: Release packaging_maintainer_mode: On enable_ipo: On - - os: windows-2022 + - os: windows-latest compiler: msvc generator: "Visual Studio 17 2022" build_type: Debug packaging_maintainer_mode: Off - - os: windows-2022 + - os: windows-latest compiler: msvc generator: "Visual Studio 17 2022" build_type: Release packaging_maintainer_mode: Off package_generator: ZIP - - os: windows-2022 + - os: windows-latest compiler: msvc generator: "Visual Studio 17 2022" build_type: Release @@ -175,7 +175,7 @@ jobs: # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail run: | ctest -C ${{matrix.build_type}} - gcovr -j ${{env.nproc}} --delete --root ../ --print-summary --xml-pretty --xml coverage.xml . --gcov-executable '${{ matrix.gcov_executable }}' + gcovr -j ${{env.nproc}} --root ../ --print-summary --xml-pretty --xml coverage.xml . --gcov-executable '${{ matrix.gcov_executable }}' - name: Windows - Test and coverage if: runner.os == 'Windows' diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e21dc29e..b0c96979 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,7 +38,7 @@ jobs: # Learn more about CodeQL language support at https://git.io/codeql-language-support compiler: # you can specify the version after `-` like "llvm-13.0.0". - - gcc-11 + - gcc-14 generator: - "Ninja Multi-Config" build_type: diff --git a/.github/workflows/template-janitor.yml b/.github/workflows/template-janitor.yml index bc56ba05..2dc8e216 100644 --- a/.github/workflows/template-janitor.yml +++ b/.github/workflows/template-janitor.yml @@ -25,12 +25,12 @@ jobs: strategy: matrix: compiler: - - gcc-11 + - gcc-14 generator: - "Unix Makefiles" build_type: - Debug - developer_mode: + packaging_maintainer_mode: - OFF steps: @@ -41,7 +41,7 @@ jobs: with: compiler: ${{ matrix.compiler }} build_type: ${{ matrix.build_type }} - developer_mode: ${{ matrix.developer_mode }} + package_maintainer_mode: ${{ matrix.package_maintainer_mode }} generator: ${{ matrix.generator }} - name: Get organization and project name @@ -53,9 +53,7 @@ jobs: - uses: octokit/request-action@v2.x id: get_repo_meta with: - route: GET /repos/{owner}/{repo} - owner: ${{ env.NEW_ORG }} - repo: ${{ env.NEW_PROJECT }} + route: GET /repos/${{ env.NEW_ORG }}/${{ env.NEW_PROJECT }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -161,8 +159,8 @@ jobs: - "Unix Makefiles" build_type: - Debug - developer_mode: - - OFF + packaging_maintainer_mode: + - ON steps: - uses: actions/checkout@v3 @@ -172,7 +170,7 @@ jobs: with: compiler: ${{ matrix.compiler }} build_type: ${{ matrix.build_type }} - developer_mode: ${{ matrix.developer_mode }} + packaging_maintainer_mode: ${{ matrix.packaging_maintainer_mode }} generator: ${{ matrix.generator }} - name: Get organization and project name @@ -187,9 +185,7 @@ jobs: - uses: octokit/request-action@v2.x id: get_repo_meta with: - route: GET /repos/{owner}/{repo} - owner: ${{ env.NEW_ORG }} - repo: ${{ env.NEW_PROJECT }} + route: GET /repos/${{ env.NEW_ORG }}/${{ env.NEW_PROJECT }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -230,7 +226,7 @@ jobs: opencppcoverage: false - - name: Test simple configuration to make sure nothing broke (default compiler,cmake,developer_mode OFF) + - name: Test simple configuration to make sure nothing broke (default compiler,cmake,packaging_maintainer_mode OFF) run: | cmake -S . -B ./build -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE:STRING=${{ matrix.build_type }} -D${{ env.PROJECT_NAME }}_PACKAGING_MAINTAINER_MODE:BOOL=ON diff --git a/CMakeLists.txt b/CMakeLists.txt index 45e19f03..a5ac5435 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.21) # Only set the cxx_standard if it is not set by someone else if (NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD 23) endif() # strongly encouraged to enable this globally to avoid conflicts between @@ -76,7 +76,7 @@ endif() if(myproject_BUILD_FUZZ_TESTS) message(AUTHOR_WARNING "Building Fuzz Tests, using fuzzing sanitizer https://www.llvm.org/docs/LibFuzzer.html") - if (NOT myproject_ENABLE_ADDRESS_SANITIZER AND NOT myproject_ENABLE_THREAD_SANITIZER) + if (NOT myproject_ENABLE_SANITIZER_ADDRESS AND NOT myproject_ENABLE_SANITIZER_THREAD) message(WARNING "You need asan or tsan enabled for meaningful fuzz testing") endif() add_subdirectory(fuzz_test) diff --git a/Dependencies.cmake b/Dependencies.cmake index e286b59f..e5008c4a 100644 --- a/Dependencies.cmake +++ b/Dependencies.cmake @@ -9,7 +9,7 @@ function(myproject_setup_dependencies) # already been provided to us by a parent project if(NOT TARGET fmtlib::fmtlib) - cpmaddpackage("gh:fmtlib/fmt#9.1.0") + cpmaddpackage("gh:fmtlib/fmt#11.1.4") endif() if(NOT TARGET spdlog::spdlog) @@ -17,7 +17,7 @@ function(myproject_setup_dependencies) NAME spdlog VERSION - 1.11.0 + 1.15.2 GITHUB_REPOSITORY "gabime/spdlog" OPTIONS @@ -25,15 +25,15 @@ function(myproject_setup_dependencies) endif() if(NOT TARGET Catch2::Catch2WithMain) - cpmaddpackage("gh:catchorg/Catch2@3.3.2") + cpmaddpackage("gh:catchorg/Catch2@3.8.1") endif() if(NOT TARGET CLI11::CLI11) - cpmaddpackage("gh:CLIUtils/CLI11@2.3.2") + cpmaddpackage("gh:CLIUtils/CLI11@2.5.0") endif() if(NOT TARGET ftxui::screen) - cpmaddpackage("gh:ArthurSonzogni/FTXUI@5.0.0") + cpmaddpackage("gh:ArthurSonzogni/FTXUI@6.0.2") endif() if(NOT TARGET tools::tools) diff --git a/ProjectOptions.cmake b/ProjectOptions.cmake index 0b3dfdb1..3d260944 100644 --- a/ProjectOptions.cmake +++ b/ProjectOptions.cmake @@ -4,9 +4,27 @@ include(CMakeDependentOption) include(CheckCXXCompilerFlag) +include(CheckCXXSourceCompiles) + + macro(myproject_supports_sanitizers) if((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND NOT WIN32) - set(SUPPORTS_UBSAN ON) + + message(STATUS "Sanity checking UndefinedBehaviorSanitizer, it should be supported on this platform") + set(TEST_PROGRAM "int main() { return 0; }") + + # Check if UndefinedBehaviorSanitizer works at link time + set(CMAKE_REQUIRED_FLAGS "-fsanitize=undefined") + set(CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=undefined") + check_cxx_source_compiles("${TEST_PROGRAM}" HAS_UBSAN_LINK_SUPPORT) + + if(HAS_UBSAN_LINK_SUPPORT) + message(STATUS "UndefinedBehaviorSanitizer is supported at both compile and link time.") + set(SUPPORTS_UBSAN ON) + else() + message(WARNING "UndefinedBehaviorSanitizer is NOT supported at link time.") + set(SUPPORTS_UBSAN OFF) + endif() else() set(SUPPORTS_UBSAN OFF) endif() @@ -14,7 +32,25 @@ macro(myproject_supports_sanitizers) if((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*" OR CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND WIN32) set(SUPPORTS_ASAN OFF) else() - set(SUPPORTS_ASAN ON) + if (NOT WIN32) + message(STATUS "Sanity checking AddressSanitizer, it should be supported on this platform") + set(TEST_PROGRAM "int main() { return 0; }") + + # Check if AddressSanitizer works at link time + set(CMAKE_REQUIRED_FLAGS "-fsanitize=address") + set(CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=address") + check_cxx_source_compiles("${TEST_PROGRAM}" HAS_ASAN_LINK_SUPPORT) + + if(HAS_ASAN_LINK_SUPPORT) + message(STATUS "AddressSanitizer is supported at both compile and link time.") + set(SUPPORTS_ASAN ON) + else() + message(WARNING "AddressSanitizer is NOT supported at link time.") + set(SUPPORTS_ASAN OFF) + endif() + else() + set(SUPPORTS_ASAN ON) + endif() endif() endmacro() diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index a3086b79..9c27c51c 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -1,4 +1,9 @@ -set(CPM_DOWNLOAD_VERSION 0.38.1) +# SPDX-License-Identifier: MIT +# +# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors + +set(CPM_DOWNLOAD_VERSION 0.40.8) +set(CPM_HASH_SUM "78ba32abdf798bc616bab7c73aac32a17bbd7b06ad9e26a6add69de8f3ae4791") if(CPM_SOURCE_CACHE) set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") @@ -11,23 +16,9 @@ endif() # Expand relative path. This is important if the provided path contains a tilde (~) get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) -function(download_cpm) - message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") - file(DOWNLOAD - https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake - ${CPM_DOWNLOAD_LOCATION} - ) -endfunction() - -if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) - download_cpm() -else() - # resume download if it previously failed - file(READ ${CPM_DOWNLOAD_LOCATION} check) - if("${check}" STREQUAL "") - download_cpm() - endif() - unset(check) -endif() +file(DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake + ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} +) include(${CPM_DOWNLOAD_LOCATION}) diff --git a/cmake/StaticAnalyzers.cmake b/cmake/StaticAnalyzers.cmake index 904aff29..652c538e 100644 --- a/cmake/StaticAnalyzers.cmake +++ b/cmake/StaticAnalyzers.cmake @@ -28,6 +28,8 @@ macro(myproject_enable_cppcheck WARNINGS_AS_ERRORS CPPCHECK_OPTIONS) # ignores code that cppcheck thinks is invalid C++ --suppress=syntaxError --suppress=preprocessorErrorDirective + # ignores static_assert type failures + --suppress=knownConditionTrueFalse --inconclusive --suppress=${SUPPRESS_DIR}) else() diff --git a/fuzz_test/fuzz_tester.cpp b/fuzz_test/fuzz_tester.cpp index ed0fc4ce..46018580 100644 --- a/fuzz_test/fuzz_tester.cpp +++ b/fuzz_test/fuzz_tester.cpp @@ -1,6 +1,7 @@ -#include +#include +#include +#include #include -#include [[nodiscard]] auto sum_values(const uint8_t *Data, size_t Size) { diff --git a/gcovr.cfg b/gcovr.cfg index d248e096..32db8e73 100644 --- a/gcovr.cfg +++ b/gcovr.cfg @@ -9,7 +9,7 @@ exclude-directories = out/*/*/_deps exclude-directories = test exclude-directories = fuzz_test -gcov-ignore-parse-errors = yes +gcov-ignore-parse-errors = all print-summary = yes html-details = ./out/coverage/index.html diff --git a/src/ftxui_sample/main.cpp b/src/ftxui_sample/main.cpp index aa53beaf..4f23ff8d 100644 --- a/src/ftxui_sample/main.cpp +++ b/src/ftxui_sample/main.cpp @@ -1,12 +1,21 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include #include #include #include -#include // for ftxui #include // for Slider #include // for ScreenInteractive #include @@ -17,6 +26,10 @@ // configuration step. It creates a namespace called `myproject`. You can modify // the source template at `configured_files/config.hpp.in`. #include +#include +#include +#include +#include template struct GameBoard { @@ -89,7 +102,7 @@ template struct GameBoard } }; - +namespace { void consequence_game() { auto screen = ftxui::ScreenInteractive::TerminalOutput(); @@ -162,6 +175,7 @@ void consequence_game() screen.Loop(renderer); } +}// namespace struct Color { @@ -177,13 +191,12 @@ struct Bitmap : ftxui::Node : width_(width), height_(height) {} - Color &at(std::size_t cur_x, std::size_t cur_y) { return pixels.at(width_ * cur_y + cur_x); } + Color &at(std::size_t cur_x, std::size_t cur_y) { return pixels.at((width_ * cur_y) + cur_x); } void ComputeRequirement() override { - requirement_ = ftxui::Requirement{ - .min_x = static_cast(width_), .min_y = static_cast(height_ / 2), .selected_box{ 0, 0, 0, 0 } - }; + requirement_.min_x = static_cast(width_); + requirement_.min_y = static_cast(height_ / 2); } void Render(ftxui::Screen &screen) override @@ -193,7 +206,7 @@ struct Bitmap : ftxui::Node auto &pixel = screen.PixelAt(box_.x_min + static_cast(cur_x), box_.y_min + static_cast(cur_y)); pixel.character = "▄"; const auto &top_color = at(cur_x, cur_y * 2); - const auto &bottom_color = at(cur_x, cur_y * 2 + 1); + const auto &bottom_color = at(cur_x, (cur_y * 2) + 1); pixel.background_color = ftxui::Color{ top_color.R.get(), top_color.G.get(), top_color.B.get() }; pixel.foreground_color = ftxui::Color{ bottom_color.R.get(), bottom_color.G.get(), bottom_color.B.get() }; } @@ -213,6 +226,7 @@ struct Bitmap : ftxui::Node std::vector pixels = std::vector(width_ * height_, Color{}); }; +namespace { void game_iteration_canvas() { // this should probably have a `bitmap` helper function that does what cur_you expect @@ -257,6 +271,8 @@ void game_iteration_canvas() case 2: small_bm_pixel.B += 11;// NOLINT Magic Number break; + default:// literally impossible + std::unreachable(); } @@ -308,6 +324,7 @@ void game_iteration_canvas() refresh_ui_continue = false; refresh_ui.join(); } +}// namespace // NOLINTNEXTLINE(bugprone-exception-escape) int main(int argc, const char **argv)