diff --git a/.clang-tidy b/.clang-tidy index 95710ddfbe0..e1032aaa5f3 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,9 +1,84 @@ --- -Checks: '*,-abseil-*,-altera-*,-android-*,-boost-*,-cert-*,-cppcoreguidelines-*,-darwin-*,-fuchsia-*,-google-*,-hicpp-*,-linuxkernel-*,-llvm-*,-llvmlibc-*,-mpi-*,-objc-*,-openmp-*,-zircon-*,google-explicit-constructor,-readability-braces-around-statements,-readability-magic-numbers,-bugprone-macro-parentheses,-readability-isolate-declaration,-readability-function-size,-modernize-use-trailing-return-type,-readability-implicit-bool-conversion,-readability-uppercase-literal-suffix,-modernize-use-auto,-modernize-use-default-member-init,-readability-redundant-member-init,-modernize-avoid-c-arrays,-modernize-use-equals-default,-readability-container-size-empty,-bugprone-branch-clone,-bugprone-narrowing-conversions,-modernize-raw-string-literal,-readability-convert-member-functions-to-static,-modernize-loop-convert,-readability-const-return-type,-modernize-return-braced-init-list,-performance-inefficient-string-concatenation,-misc-throw-by-value-catch-by-reference,-readability-avoid-const-params-in-decls,-misc-non-private-member-variables-in-classes,-clang-analyzer-*,-bugprone-signed-char-misuse,-misc-no-recursion,-readability-use-anyofallof,-performance-no-automatic-move,-readability-function-cognitive-complexity,-readability-redundant-access-specifiers,-concurrency-mt-unsafe,-bugprone-easily-swappable-parameters,-readability-suspicious-call-argument,-readability-identifier-length,-readability-container-data-pointer,-bugprone-assignment-in-if-condition,-misc-const-correctness,-portability-std-allocator-const,-modernize-deprecated-ios-base-aliases,-bugprone-unchecked-optional-access,-modernize-replace-auto-ptr,-readability-identifier-naming,-portability-simd-intrinsics,-misc-use-anonymous-namespace,cert-err34-c' +Checks: > + *, + -abseil-*, + -altera-*, + -android-*, + -boost-*, + -cert-*, + -cppcoreguidelines-*, + -darwin-*, + -fuchsia-*, + -google-*, + -hicpp-*, + -linuxkernel-*, + -llvm-*, + -llvmlibc-*, + -mpi-*, + -objc-*, + -openmp-*, + -zircon-*, + cert-err34-c, + cppcoreguidelines-pro-type-static-cast-downcast, + cppcoreguidelines-rvalue-reference-param-not-moved, + google-explicit-constructor, + -bugprone-assignment-in-if-condition, + -bugprone-branch-clone, + -bugprone-easily-swappable-parameters, + -bugprone-empty-catch, + -bugprone-macro-parentheses, + -bugprone-narrowing-conversions, + -bugprone-signed-char-misuse, + -bugprone-switch-missing-default-case, + -bugprone-unchecked-optional-access, + -clang-analyzer-*, + -concurrency-mt-unsafe, + -misc-const-correctness, + -misc-no-recursion, + -misc-non-private-member-variables-in-classes, + -misc-throw-by-value-catch-by-reference, + -misc-use-anonymous-namespace, + -modernize-avoid-c-arrays, + -modernize-deprecated-ios-base-aliases, + -misc-include-cleaner, + -misc-unused-using-decls, + -modernize-loop-convert, + -modernize-macro-to-enum, + -modernize-raw-string-literal, + -modernize-replace-auto-ptr, + -modernize-return-braced-init-list, + -modernize-type-traits, + -modernize-use-designated-initializers, + -modernize-use-nodiscard, + -modernize-use-scoped-lock, + -modernize-use-trailing-return-type, + -performance-avoid-endl, + -performance-inefficient-string-concatenation, + -performance-no-automatic-move, + -portability-avoid-pragma-once, + -portability-simd-intrinsics, + -portability-std-allocator-const, + -readability-avoid-nested-conditional-operator, + -readability-braces-around-statements, + -readability-container-data-pointer, + -readability-enum-initial-value, + -readability-function-cognitive-complexity, + -readability-function-size, + -readability-identifier-length, + -readability-identifier-naming, + -readability-implicit-bool-conversion, + -readability-isolate-declaration, + -readability-magic-numbers, + -readability-suspicious-call-argument, + -readability-uppercase-literal-suffix, + -readability-use-concise-preprocessor-directives WarningsAsErrors: '*' -HeaderFilterRegex: '(cli|gui|lib|oss-fuzz|test|triage)\/[a-z]+\.h' +HeaderFilterRegex: '(cli|gui|frontend|lib|oss-fuzz|test|triage)\/[a-z_]+\.h' +ExcludeHeaderFilterRegex: 'ui_.*.h' CheckOptions: - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: '1' - key: readability-simplify-boolean-expr.SimplifyDeMorgan value: '0' + - key: modernize-use-trailing-return-type.TransformFunctions + value: false diff --git a/.github/workflows/CI-cygwin.yml b/.github/workflows/CI-cygwin.yml index 31557ecbcc7..445c0953eb5 100644 --- a/.github/workflows/CI-cygwin.yml +++ b/.github/workflows/CI-cygwin.yml @@ -1,10 +1,16 @@ -# Some convenient links: -# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md -# - +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: CI-cygwin -on: [push,pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -14,11 +20,13 @@ defaults: shell: cmd jobs: + # TODO: add CMake build build_cygwin: strategy: matrix: - os: [windows-2022] - arch: [x64] + # only use the latest windows-* as the installed toolchain is identical + os: [windows-2025] + platform: [x86_64] include: - platform: 'x86_64' packages: | @@ -29,18 +37,20 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Cygwin uses: cygwin/cygwin-install-action@master with: - platform: ${{ matrix.arch }} + platform: ${{ matrix.platform }} packages: ${{ matrix.packages }} # Cygwin will always link the binaries even if they already exist. The linking is also extremely slow. So just run the "check" target which includes all the binaries. - name: Build all and run test run: | - C:\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE% && make VERBOSE=1 -j2 check + C:\cygwin\bin\bash.exe -l -c cd %GITHUB_WORKSPACE% && make VERBOSE=1 -j%NUMBER_OF_PROCESSORS% CXXOPTS="-Werror" test - name: Extra test for misra run: | diff --git a/.github/workflows/CI-mingw.yml b/.github/workflows/CI-mingw.yml index 152e84902c2..1b0cf3e5672 100644 --- a/.github/workflows/CI-mingw.yml +++ b/.github/workflows/CI-mingw.yml @@ -1,37 +1,75 @@ -# Some convenient links: -# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md -# - +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: CI-mingw -on: [push,pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read defaults: run: - shell: cmd + shell: msys2 {0} jobs: + # TODO: add CMake build build_mingw: strategy: matrix: - os: [windows-2019] # fails to download with "windows-2022" - arch: [x64] # TODO: fix x86 build? + # only use the latest windows-* as the installed toolchain is identical + os: [windows-2025] fail-fast: false runs-on: ${{ matrix.os }} + timeout-minutes: 19 # max + 3*std of the last 7K runs + steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up MSYS2 + uses: msys2/setup-msys2@v2 + with: + release: false # use pre-installed + # TODO: install mingw-w64-x86_64-make and use mingw32.make instead - currently fails with "Windows Subsystem for Linux has no installed distributions." + install: >- + mingw-w64-x86_64-lld + mingw-w64-x86_64-ccache + make + mingw-w64-x86_64-gcc - - name: Set up MinGW - uses: egor-tensin/setup-mingw@v2 + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 with: - platform: ${{ matrix.arch }} + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Build cppcheck + run: | + export PATH="/mingw64/lib/ccache/bin:$PATH" + # set RDYNAMIC to work around broken MinGW detection + # use lld for faster linking + make VERBOSE=1 RDYNAMIC=-lshlwapi LDOPTS=-fuse-ld=lld -j$(nproc) CXXOPTS="-Werror" cppcheck + + - name: Build test + run: | + export PATH="/mingw64/lib/ccache/bin:$PATH" + # set RDYNAMIC to work around broken MinGW detection + # use lld for faster linking + make VERBOSE=1 RDYNAMIC=-lshlwapi LDOPTS=-fuse-ld=lld -j$(nproc) CXXOPTS="-Werror" testrunner - # MinGW will always link the binaries even if they already exist. The linking is also extremely slow. So just run the "check" target which includes all the binaries. - - name: Build all and run test + - name: Run test run: | - mingw32-make VERBOSE=1 -j2 check + export PATH="/mingw64/lib/ccache/bin:$PATH" + # set RDYNAMIC to work around broken MinGW detection + # use lld for faster linking + make VERBOSE=1 RDYNAMIC=-lshlwapi LDOPTS=-fuse-ld=lld -j$(nproc) CXXOPTS="-Werror" test diff --git a/.github/workflows/CI-unixish-docker.yml b/.github/workflows/CI-unixish-docker.yml index f8dd4bb75fe..4df9b4e9340 100644 --- a/.github/workflows/CI-unixish-docker.yml +++ b/.github/workflows/CI-unixish-docker.yml @@ -2,17 +2,29 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: CI-unixish-docker -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read - + jobs: build_cmake: strategy: matrix: - image: ["centos:7", "ubuntu:14.04", "ubuntu:16.04", "ubuntu:18.04", "ubuntu:23.04"] + image: ["ubuntu:24.04"] + include: + - build_gui: false + - image: "ubuntu:24.04" + build_gui: true fail-fast: false # Prefer quick result runs-on: ubuntu-22.04 @@ -26,14 +38,9 @@ jobs: image: ${{ matrix.image }} steps: - - uses: actions/checkout@v3 - - - name: Install missing software on CentOS 7 - if: matrix.image == 'centos:7' - run: | - yum install -y cmake gcc-c++ make pcre-devel - yum --enablerepo=extras install -y epel-release - yum install -y ccache + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Install missing software on ubuntu if: contains(matrix.image, 'ubuntu') @@ -41,49 +48,33 @@ jobs: apt-get update apt-get install -y cmake g++ make libxml2-utils libpcre3-dev - # required so a default Qt installation is configured - - name: Install missing software on ubuntu 18.04 - if: false # matrix.os == 'ubuntu-18.04' + - name: Install missing software (gui) on latest ubuntu + if: matrix.build_gui run: | - sudo apt-get install qt5-default + apt-get install -y qt6-base-dev qt6-charts-dev qt6-tools-dev # needs to be called after the package installation since # - it doesn't call "apt-get update" - # - it doesn't support centos - name: ccache uses: hendrikmuhs/ccache-action@v1.2 - if: matrix.image != 'ubuntu:14.04' # no support for --set-config with: key: ${{ github.workflow }}-${{ matrix.image }} - # tests require CMake 3.9 - no ccache available - - name: CMake build (no tests / no ccache) - if: matrix.image == 'ubuntu:14.04' - run: | - mkdir cmake.output - cd cmake.output - cmake -G "Unix Makefiles" -DHAVE_RULES=On .. - cmake --build . -- -j$(nproc) - - # tests require CMake 3.9 - ccache available - - name: CMake build (no tests) - if: matrix.image == 'centos:7' || matrix.image == 'ubuntu:16.04' + - name: CMake build + if: ${{ !matrix.build_gui }} run: | mkdir cmake.output cd cmake.output - cmake -G "Unix Makefiles" -DHAVE_RULES=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. + cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. cmake --build . -- -j$(nproc) - - name: CMake build - if: matrix.image != 'centos:7' && matrix.image != 'ubuntu:14.04' && matrix.image != 'ubuntu:16.04' + - name: CMake build (with GUI) + if: matrix.build_gui run: | - mkdir cmake.output - cd cmake.output - cmake -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. - cmake --build . -- -j$(nproc) + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake --build cmake.output -- -j$(nproc) - name: Run CMake test - if: matrix.image != 'centos:7' && matrix.image != 'ubuntu:14.04' && matrix.image != 'ubuntu:16.04' run: | cmake --build cmake.output --target check -- -j$(nproc) @@ -91,7 +82,7 @@ jobs: strategy: matrix: - image: ["centos:7", "ubuntu:14.04", "ubuntu:16.04", "ubuntu:18.04", "ubuntu:22.10"] + image: ["ubuntu:24.04"] fail-fast: false # Prefer quick result runs-on: ubuntu-22.04 @@ -100,14 +91,9 @@ jobs: image: ${{ matrix.image }} steps: - - uses: actions/checkout@v3 - - - name: Install missing software on CentOS 7 - if: matrix.image == 'centos:7' - run: | - yum install -y gcc-c++ make which python3 pcre-devel - yum --enablerepo=extras install -y epel-release - yum install -y ccache + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Install missing software on ubuntu if: contains(matrix.image, 'ubuntu') @@ -117,33 +103,29 @@ jobs: # needs to be called after the package installation since # - it doesn't call "apt-get update" - # - it doesn't support centos - name: ccache uses: hendrikmuhs/ccache-action@v1.2 - if: matrix.image != 'ubuntu:14.04' # no support for --set-config with: key: ${{ github.workflow }}-${{ matrix.image }} - name: Build cppcheck run: | - # "/usr/lib64" for centos / "/usr/lib" for ubuntu - export PATH="/usr/lib64/ccache:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) HAVE_RULES=yes + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) HAVE_RULES=yes CXXOPTS="-Werror" - name: Build test run: | - # "/usr/lib64" for centos / "/usr/lib" for ubuntu - export PATH="/usr/lib64/ccache:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) testrunner HAVE_RULES=yes + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + make -j$(nproc) HAVE_RULES=yes CXXOPTS="-Werror" testrunner - name: Run test run: | - make -j$(nproc) check HAVE_RULES=yes + make -j$(nproc) HAVE_RULES=yes test # requires python3 - name: Run extra tests run: | - tools/generate_and_run_more_tests.sh + test/scripts/generate_and_run_more_tests.sh # requires which - name: Validate @@ -154,10 +136,3 @@ jobs: run: | ./cppcheck --addon=threadsafety addons/test/threadsafety ./cppcheck --addon=threadsafety --std=c++03 addons/test/threadsafety - - - name: Generate Qt help file on ubuntu 18.04 - if: false # matrix.os == 'ubuntu-18.04' - run: | - pushd gui/help - qcollectiongenerator online-help.qhcp -o online-help.qhc - diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml index 902417375a8..e37d88767ec 100644 --- a/.github/workflows/CI-unixish.yml +++ b/.github/workflows/CI-unixish.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: CI-unixish -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -12,7 +20,7 @@ jobs: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, macos-15] fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} @@ -22,7 +30,9 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -33,25 +43,28 @@ jobs: if: contains(matrix.os, 'ubuntu') run: | sudo apt-get update - sudo apt-get install libxml2-utils libtinyxml2-dev qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser + sudo apt-get install libxml2-utils libtinyxml2-dev + # qt6-tools-dev-tools for lprodump + # qt6-l10n-tools for lupdate + sudo apt-get install qt6-base-dev libqt6charts6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libglx-dev libgl1-mesa-dev # coreutils contains "nproc" - name: Install missing software on macos if: contains(matrix.os, 'macos') run: | # pcre was removed from runner images in November 2022 - brew install coreutils qt@5 tinyxml2 pcre + brew install coreutils qt@6 tinyxml2 pcre - name: CMake build on ubuntu (with GUI / system tinyxml2) if: contains(matrix.os, 'ubuntu') run: | - cmake -S . -B cmake.output.tinyxml2 -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output.tinyxml2 -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache cmake --build cmake.output.tinyxml2 -- -j$(nproc) - name: CMake build on macos (with GUI / system tinyxml2) if: contains(matrix.os, 'macos') run: | - cmake -S . -B cmake.output.tinyxml2 -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 + cmake -S . -B cmake.output.tinyxml2 -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 cmake --build cmake.output.tinyxml2 -- -j$(nproc) - name: Run CMake test (system tinyxml2) @@ -62,7 +75,7 @@ jobs: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, macos-15] fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} @@ -72,48 +85,57 @@ jobs: CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} - - name: Install missing software on ubuntu - if: contains(matrix.os, 'ubuntu') - run: | - sudo apt-get update - sudo apt-get install libxml2-utils qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser - + # TODO: move latest compiler to separate step + # TODO: bail out on warnings with latest GCC - name: Set up GCC uses: egor-tensin/setup-gcc@v1 - if: matrix.os == 'ubuntu-22.04' + if: false # matrix.os == 'ubuntu-22.04' with: version: 13 platform: x64 - name: Select compiler + if: false # matrix.os == 'ubuntu-22.04' run: | echo "CXX=g++-13" >> $GITHUB_ENV - if: matrix.os == 'ubuntu-22.04' + + - name: Install missing software on ubuntu + if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install libxml2-utils + # qt6-tools-dev-tools for lprodump + # qt6-l10n-tools for lupdate + sudo apt-get install qt6-base-dev libqt6charts6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libglx-dev libgl1-mesa-dev # coreutils contains "nproc" - name: Install missing software on macos if: contains(matrix.os, 'macos') run: | # pcre was removed from runner images in November 2022 - brew install coreutils qt@5 pcre + brew install coreutils qt@6 pcre - - name: CMake build on ubuntu (with GUI) + - name: Run CMake on ubuntu (with GUI) if: contains(matrix.os, 'ubuntu') run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - cmake --build cmake.output -- -j$(nproc) + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install - - name: CMake build on macos (with GUI) + - name: Run CMake on macos (with GUI) if: contains(matrix.os, 'macos') run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5 + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 + + - name: Run CMake build + run: | cmake --build cmake.output -- -j$(nproc) - name: Run CMake test @@ -125,17 +147,126 @@ jobs: pushd cmake.output ctest --output-on-failure -j$(nproc) + - name: Run CMake install + run: | + cmake --build cmake.output --target install + + - name: Run CMake on ubuntu (no CLI) + if: matrix.os == 'ubuntu-22.04' + run: | + cmake -S . -B cmake.output_nocli -G "Unix Makefiles" -DBUILD_CLI=Off + + - name: Run CMake on ubuntu (no CLI / with tests) + if: matrix.os == 'ubuntu-22.04' + run: | + # the test and CLI code are too intertwined so for now we need to reject that + if cmake -S . -B cmake.output_nocli_tests -G "Unix Makefiles" -DBUILD_TESTS=On -DBUILD_CLI=Off; then + exit 1 + else + exit 0 + fi + + - name: Run CMake on ubuntu (no CLI / with GUI) + if: matrix.os == 'ubuntu-22.04' + run: | + cmake -S . -B cmake.output_nocli_gui -G "Unix Makefiles" -DBUILD_CLI=Off -DBUILD_GUI=On + + - name: Run CMake on ubuntu (no GUI) + if: matrix.os == 'ubuntu-22.04' + run: | + cmake -S . -B cmake.output_nogui -G "Unix Makefiles" -DBUILD_GUI=Off + + - name: Run CMake on ubuntu (no GUI / with triage) + if: matrix.os == 'ubuntu-22.04' + run: | + # cannot build triage without GUI + if cmake -S . -B cmake.output_nogui_triage -G "Unix Makefiles" -DBUILD_GUI=Off -DBUILD_TRIAGE=On; then + exit 1 + else + exit 0 + fi + + - name: Run CMake on ubuntu (no CLI / no GUI) + if: matrix.os == 'ubuntu-22.04' + run: | + cmake -S . -B cmake.output_nocli_nogui -G "Unix Makefiles" -DBUILD_GUI=Off + + build_cmake_cxxstd: + + strategy: + matrix: + os: [ubuntu-22.04, macos-15] + cxxstd: [14, 17, 20] + # FIXME: macos-15 fails to compile with C++20 + # + # /Users/runner/work/cppcheck/cppcheck/cmake.output/gui/test/projectfile/moc_testprojectfile.cpp:84:1: error: 'constinit' specifier is incompatible with C++ standards before C++20 [-Werror,-Wc++20-compat] + # 84 | Q_CONSTINIT const QMetaObject TestProjectFile::staticMetaObject = { { + # | ^ + # /opt/homebrew/opt/qt/lib/QtCore.framework/Headers/qcompilerdetection.h:1409:23: note: expanded from macro 'Q_CONSTINIT' + exclude: + - os: macos-15 + cxxstd: 20 + fail-fast: false # Prefer quick result + + runs-on: ${{ matrix.os }} + + env: + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}-${{ matrix.cxxstd }} + + - name: Install missing software on ubuntu + if: contains(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install libxml2-utils + # qt6-tools-dev-tools for lprodump + # qt6-l10n-tools for lupdate + sudo apt-get install qt6-base-dev libqt6charts6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libglx-dev libgl1-mesa-dev + + # coreutils contains "nproc" + - name: Install missing software on macos + if: contains(matrix.os, 'macos') + run: | + # pcre was removed from runner images in November 2022 + brew install coreutils qt@6 pcre + + - name: Run CMake on ubuntu (with GUI) + if: contains(matrix.os, 'ubuntu') + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + + - name: Run CMake on macos (with GUI) + if: contains(matrix.os, 'macos') + run: | + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6 + + - name: Run CMake build + run: | + cmake --build cmake.output -- -j$(nproc) + build_uchar: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, macos-15] fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -151,23 +282,25 @@ jobs: - name: Build with Unsigned char run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) CXXFLAGS=-funsigned-char testrunner + make -j$(nproc) CXXOPTS="-Werror -funsigned-char" testrunner - name: Test with Unsigned char run: | - ./testrunner TestSymbolDatabase + ./testrunner build_mathlib: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, macos-15] fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -183,23 +316,25 @@ jobs: - name: Build with TEST_MATHLIB_VALUE run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) CPPFLAGS=-DTEST_MATHLIB_VALUE all + make -j$(nproc) CXXOPTS="-Werror" CPPOPTS=-DTEST_MATHLIB_VALUE all - name: Test with TEST_MATHLIB_VALUE run: | - make -j$(nproc) CPPFLAGS=-DTEST_MATHLIB_VALUE check + make -j$(nproc) test check_nonneg: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, macos-15] fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false # coreutils contains "g++" (default is "c++") and "nproc" - name: Install missing software on macos @@ -209,100 +344,87 @@ jobs: - name: Check syntax with NONNEG run: | - ls lib/*.cpp | xargs -n 1 -P $(nproc) g++ -fsyntax-only -std=c++0x -Ilib -Iexternals -Iexternals/picojson -Iexternals/simplecpp -Iexternals/tinyxml2 -DNONNEG + make check-nonneg CXXOPTS="-Werror" - build_qmake: + build_cmake_boost: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [macos-15] # non-macos platforms are already built with Boost in other contexts fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} + env: + # TODO: figure out why there are cache misses with PCH enabled + CCACHE_SLOPPINESS: pch_defines,time_macros + steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - - name: Install missing software on ubuntu - if: contains(matrix.os, 'ubuntu') + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + + - name: Run CMake on macOS (force Boost) run: | - sudo apt-get update - sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser + # make sure we fail when Boost is requested and not available. + # will fail because no package configuration is available. + if cmake -S . -B cmake.output.boost-force-noavail -G "Unix Makefiles" -DUSE_BOOST=On; then + exit 1 + else + exit 0 + fi # coreutils contains "nproc" - - name: Install missing software on macos - if: contains(matrix.os, 'macos') + - name: Install missing software on macOS run: | - brew install coreutils qt@5 - # expose qmake - brew link qt@5 --force + brew install coreutils boost - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} + - name: Run CMake on macOS (force Boost) + run: | + cmake -S . -B cmake.output.boost-force -G "Unix Makefiles" -DUSE_BOOST=On - - name: Build GUI + - name: Run CMake on macOS (no Boost) run: | - export PATH="$(brew --prefix)/opt/ccache/libexec:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - pushd gui - qmake CONFIG+=debug CONFIG+=ccache HAVE_QCHART=yes - make -j$(nproc) + # make sure Boost is not used when disabled even though it is available + cmake -S . -B cmake.output.boost-no -G "Unix Makefiles" -DUSE_BOOST=Off + if grep -q '\-DHAVE_BOOST' ./cmake.output.boost-no/compile_commands.json; then + exit 1 + else + exit 0 + fi - # TODO: binaries are in a different location on macos - - name: Build and Run GUI tests - if: contains(matrix.os, 'ubuntu') + - name: Run CMake on macOS (with Boost) run: | - export PATH="$(brew --prefix)/opt/ccache/libexec:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - pushd gui/test/cppchecklibrarydata - qmake CONFIG+=debug CONFIG+=ccache - make -j$(nproc) - ./test-cppchecklibrarydata - popd - pushd gui/test/filelist - qmake CONFIG+=debug CONFIG+=ccache - make -j$(nproc) - ./test-filelist - popd - pushd gui/test/projectfile - qmake CONFIG+=debug CONFIG+=ccache - make -j$(nproc) - ./test-projectfile - popd - pushd gui/test/translationhandler - qmake CONFIG+=debug CONFIG+=ccache - make -j$(nproc) - # TODO: requires X session because of QApplication dependency in translationhandler.cpp - #./test-translationhandler - popd - pushd gui/test/xmlreportv2 - qmake CONFIG+=debug CONFIG+=ccache - make -j$(nproc) - ./test-xmlreportv2 - - - name: Generate Qt help file - run: | - pushd gui/help - qhelpgenerator online-help.qhcp -o online-help.qhc - - - name: Build triage - run: | - export PATH="$(brew --prefix)/opt/ccache/libexec:/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - pushd tools/triage - qmake CONFIG+=debug CONFIG+=ccache - make -j$(nproc) + cmake -S . -B cmake.output.boost -G "Unix Makefiles" -DBUILD_TESTS=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + grep -q '\-DHAVE_BOOST' ./cmake.output.boost/compile_commands.json + + - name: Build with CMake on macOS (with Boost) + run: | + cmake --build cmake.output.boost -- -j$(nproc) build: strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, macos-15] + include: + - xdist_n: auto + # FIXME: test_color_tty fails with xdist - see #13278 + - os: macos-15 + xdist_n: '1' fail-fast: false # Prefer quick result runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -319,48 +441,95 @@ jobs: - name: Install missing software on ubuntu 22.04 (cfg) if: matrix.os == 'ubuntu-22.04' run: | - sudo apt-get install libcairo2-dev libcurl4-openssl-dev liblua5.3-dev libssl-dev libsqlite3-dev libcppunit-dev libsigc++-2.0-dev libgtk-3-dev libboost-all-dev libwxgtk3.0-gtk3-dev xmlstarlet qtbase5-dev + sudo apt-get install libcairo2-dev libcurl4-openssl-dev liblua5.3-dev libssl-dev libsqlite3-dev libcppunit-dev libsigc++-2.0-dev libgtk-3-dev libboost-all-dev libselinux-dev libwxgtk3.0-gtk3-dev xmlstarlet qtbase5-dev # coreutils contains "nproc" - name: Install missing software on macos if: contains(matrix.os, 'macos') run: | # pcre was removed from runner images in November 2022 - brew install coreutils python3 pcre gnu-sed + brew install coreutils pcre gnu-sed - - name: Install missing Python packages + - name: Install missing Python packages on ubuntu + if: contains(matrix.os, 'ubuntu') run: | python3 -m pip install pip --upgrade python3 -m pip install pytest + python3 -m pip install pytest-timeout + python3 -m pip install pytest-xdist + python3 -m pip install psutil + + # we need to use -break-system-packages --user because the common approaches do not work. + # using pip works but it appears to install the packages into a different Python installation so they are not found later on. + # using python3 -m pip without the additional flags fails since the packages are being managed by a different tool (brew) and that lacks some of the packages. + # using pipx also does not work. + - name: Install missing Python packages on macos + if: contains(matrix.os, 'macos') + run: | + python3 -m pip install --break-system-packages --user pip --upgrade + python3 -m pip install --break-system-packages --user pytest + python3 -m pip install --break-system-packages --user pytest-timeout + python3 -m pip install --break-system-packages --user pytest-xdist + python3 -m pip install --break-system-packages --user psutil - name: Build cppcheck run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) HAVE_RULES=yes + make -j$(nproc) CXXOPTS="-Werror" HAVE_RULES=yes - name: Build test run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) testrunner HAVE_RULES=yes + make -j$(nproc) CXXOPTS="-Werror" HAVE_RULES=yes testrunner - name: Run test run: | - make -j$(nproc) check HAVE_RULES=yes + make -j$(nproc) HAVE_RULES=yes test # requires "gnu-sed" installed on macos - name: Run extra tests run: | - tools/generate_and_run_more_tests.sh + test/scripts/generate_and_run_more_tests.sh - # do not use pushd in this step since we go below the working directory - name: Run test/cli run: | - cd test/cli - python3 -m pytest test-*.py - cd ../../.. + python3 -m pytest -Werror --strict-markers -vv -n ${{ matrix.xdist_n }} test/cli + + # TODO: use the step below instead + # do not use pushd in this step since we go below the working directory + - name: Run test/cli (symlink) + run: | + cd .. ln -s cppcheck 'cpp check' cd 'cpp check/test/cli' - python3 -m pytest test-*.py + python3 -m pytest -Werror --strict-markers -vv -n ${{ matrix.xdist_n }} + + # FIXME: proj2_test.py fails because of the relative path cleanups in ImportProject::setRelativePaths() + # It fails because the application path used as base path has its symlink resolved by getcwd(). + - name: Run test/cli (symlink) + if: false + run: | + ln -s . 'cpp check' + python3 -m pytest -Werror --strict-markers -vv -n ${{ matrix.xdist_n }} 'cpp check/test/cli' + + - name: Run test/cli (-j2) + run: | + python3 -m pytest -Werror --strict-markers -vv -n ${{ matrix.xdist_n }} test/cli + env: + TEST_CPPCHECK_INJECT_J: 2 + + - name: Run test/cli (--clang) + if: false + run: | + python3 -m pytest -Werror --strict-markers -vv -n ${{ matrix.xdist_n }} test/cli + env: + TEST_CPPCHECK_INJECT_CLANG: clang + + - name: Run test/cli (--cppcheck-build-dir) + run: | + python3 -m pytest -Werror --strict-markers -vv -n ${{ matrix.xdist_n }} test/cli + env: + TEST_CPPCHECK_INJECT_BUILDDIR: injected - name: Run cfg tests if: matrix.os != 'ubuntu-22.04' @@ -374,10 +543,6 @@ jobs: env: STRICT: 1 - - name: Run showtimetop5 tests - run: | - ./tools/test_showtimetop5.sh - - name: Run --dump test run: | ./cppcheck test/testpreprocessor.cpp --dump @@ -387,18 +552,50 @@ jobs: run: | make -j$(nproc) checkCWEEntries validateXML + - name: Test install + run: | + # this is only to test the "install" target - since we did not build with FILESDIR it would not work as intended + make DESTDIR=cppcheck-make-install FILESDIR=/share/Cppcheck install + rm -rf cppcheck-make-install + + - name: Test Signalhandler + run: | + cmake -S . -B build.cmake.signal -G "Unix Makefiles" -DBUILD_TESTS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On + cmake --build build.cmake.signal --target test-signalhandler -- -j$(nproc) + # TODO: how to run this without copying the file? + cp build.cmake.signal/bin/test-s* . + python3 -m pytest -Werror --strict-markers -vv test/signal/test-signalhandler.py + rm test-signalhandler + + # no unix backtrace support on MacOs + - name: Test Stacktrace + if: contains(matrix.os, 'ubuntu') + run: | + cmake -S . -B build.cmake.stack -G "Unix Makefiles" -DBUILD_TESTS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On + cmake --build build.cmake.stack --target test-stacktrace -- -j$(nproc) + # TODO: how to run this without copying the file? + cp build.cmake.stack/bin/test-s* . + python3 -m pytest -Werror --strict-markers -vv test/signal/test-stacktrace.py + rm test-stacktrace + # TODO: move to scriptcheck.yml so these are tested with all Python versions? - name: Test addons run: | + set -x ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety addons/test/threadsafety ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety --std=c++03 addons/test/threadsafety ./cppcheck --error-exitcode=1 --inline-suppr --addon=misra addons/test/misra/crash*.c + ./cppcheck --error-exitcode=1 --inline-suppr --addon=misra --enable=information addons/test/misra/config*.c + ./cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c pushd addons/test # We'll force C89 standard to enable an additional verification for # rules 5.4 and 5.5 which have standard-dependent options. ../../cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 python3 ../misra.py -verify misra/misra-test.c.dump + # Test slight MISRA differences in C11 standard + ../../cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test-c11.c --std=c11 --platform=unix64 + python3 ../misra.py -verify misra/misra-test-c11.c.dump # TODO: do we need to verify something here? ../../cppcheck --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.h ../../cppcheck --dump misra/misra-test.cpp @@ -413,8 +610,23 @@ jobs: python3 ../naming.py --var='[a-z].*' --function='[a-z].*' naming_test.c.dump ../../cppcheck --dump naming_test.cpp python3 ../naming.py --var='[a-z].*' --function='[a-z].*' naming_test.cpp.dump - ../../cppcheck --dump namingng_test.c - python3 ../namingng.py --configfile ../naming.json --verify namingng_test.c.dump + + # TODO: run with "-n auto" when misra_test.py can be run in parallel + - name: test addons (Python) + if: matrix.os != 'ubuntu-22.04' + run: | + python3 -m pytest -Werror --strict-markers -vv -n 1 addons/test + env: + PYTHONPATH: ./addons + + # TODO: run with "-n auto" when misra_test.py can be run in parallel + # we cannot specify -Werror since xml/etree/ElementTree.py in Python 3.10 contains an unclosed file + - name: test addons (Python) + if: matrix.os == 'ubuntu-22.04' + run: | + python3 -m pytest --strict-markers -vv -n 1 addons/test + env: + PYTHONPATH: ./addons - name: Build democlient if: matrix.os == 'ubuntu-22.04' @@ -422,13 +634,35 @@ jobs: warnings="-pedantic -Wall -Wextra -Wcast-qual -Wno-deprecated-declarations -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-shadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare -Wno-multichar" g++ $warnings -c -Ilib -Iexternals/tinyxml2 democlient/democlient.cpp + - name: Test disabled executors + if: matrix.os == 'ubuntu-22.04' + run: | + g++ -Ilib -c cli/threadexecutor.cpp -DDISALLOW_THREAD_EXECUTOR + test -z "$(nm threadexecutor.o)" + g++ -Ilib -c cli/processexecutor.cpp -DDISALLOW_PROCESS_EXECUTOR + test -z "$(nm processexecutor.o)" + # TODO: test NO_* defines + + - name: Show all ignored files + if: false # TODO: currently lists all the contents of ignored folders - we only need what actually matched + run: | + git ls-files --others --ignored --exclude-standard + + - name: Check for changed and unversioned files + run: | + # TODO: how to do this with a single command? + git status --ignored=no + git status --ignored=no | grep -q 'working tree clean' + selfcheck: needs: build # wait for all tests to be successful first runs-on: ubuntu-22.04 # run on the latest image only steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -438,44 +672,54 @@ jobs: - name: Install missing software on ubuntu run: | sudo apt-get update - sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev libboost-container-dev + # qt6-tools-dev-tools for lprodump + # qt6-l10n-tools for lupdate + sudo apt-get install qt6-base-dev libqt6charts6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libglx-dev libgl1-mesa-dev + sudo apt-get install libboost-container-dev - name: Self check (build) run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" # compile with verification and ast matchers - make -j$(nproc) -s CPPFLAGS="-DCHECK_INTERNAL" CXXFLAGS="-g -O2 -DHAVE_BOOST" MATCHCOMPILER=yes VERIFY=1 + make -j$(nproc) CXXOPTS="-Werror -g -O2" CPPOPTS="-DCHECK_INTERNAL -DHAVE_BOOST" MATCHCOMPILER=yes VERIFY=1 - - name: Generate UI files + - name: CMake run: | - pushd gui - qmake CONFIG+=debug HAVE_QCHART=yes - make -j$(nproc) compiler_uic_make_all mocables + cmake -S . -B cmake.output -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On - - name: Generate triage UI files + - name: Generate dependencies run: | - pushd tools/triage - qmake CONFIG+=debug - make -j$(nproc) compiler_uic_make_all mocables + # make sure auto-generated GUI files exist + make -C cmake.output autogen + make -C cmake.output gui-build-deps triage-build-ui-deps - name: Self check run: | - selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive" + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=file-total -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,information --exception-handling --debug-warnings --check-level=exhaustive" + cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2" + gui_options="-DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt" ec=0 + # TODO: add --check-config + # early exit if [ $ec -eq 1 ]; then exit $ec fi + # self check externals + ./cppcheck $selfcheck_options externals || ec=1 # self check lib/cli mkdir b1 - ./cppcheck $selfcheck_options --cppcheck-build-dir=b1 --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json frontend || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json -Ifrontend cli || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json --enable=internal lib || ec=1 # check gui with qt settings mkdir b2 - ./cppcheck $selfcheck_options --cppcheck-build-dir=b2 -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Igui/temp -Igui gui/*.cpp gui/temp/*.cpp || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options $gui_options --cppcheck-build-dir=b2 --addon=naming.json --suppress=simplifyUsing:*/moc_*.cpp -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1 # self check test and tools - ./cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options -Ifrontend -Icli test/*.cpp || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1 # triage - ./cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Itools/triage/temp -Igui tools/triage/*.cpp tools/triage/temp/*.cpp || ec=1 + ./cppcheck $selfcheck_options $cppcheck_options $gui_options -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1 exit $ec diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml index 4da98719ded..2b08f18bbf5 100644 --- a/.github/workflows/CI-windows.yml +++ b/.github/workflows/CI-windows.yml @@ -1,10 +1,16 @@ -# Some convenient links: -# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md -# - +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: CI-windows -on: [push,pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -18,56 +24,85 @@ jobs: build_qt: strategy: matrix: - os: [windows-2019, windows-2022] - qt_ver: [5.15.2, 6.2.4, 6.5.0] + os: [windows-2022, windows-2025] + qt_ver: [6.10.0] fail-fast: false runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Visual Studio environment uses: ilammy/msvc-dev-cmd@v1 with: - arch: x64 # no 32-bit Qt available + arch: x64 - name: Install Qt ${{ matrix.qt_ver }} - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ matrix.qt_ver }} modules: 'qtcharts' + setup-python: 'false' cache: true + aqtversion: '==3.1.*' # TODO: remove when aqtinstall 3.2.2 is available - - name: Build GUI release (qmake) - if: startsWith(matrix.qt_ver, '5') + - name: Run CMake run: | - cd gui || exit /b !errorlevel! - qmake HAVE_QCHART=yes || exit /b !errorlevel! - nmake release || exit /b !errorlevel! - env: - CL: /MP + rem TODO: enable rules? + rem specify Release build so matchcompiler is used + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DBUILD_ONLINE_HELP=On -DCMAKE_INSTALL_PREFIX=cppcheck-cmake-install -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + + - name: Build GUI release + run: | + cmake --build build --target cppcheck-gui --config Release || exit /b !errorlevel! - name: Deploy GUI - if: startsWith(matrix.qt_ver, '5') run: | - windeployqt Build\gui || exit /b !errorlevel! - del Build\gui\cppcheck-gui.ilk || exit /b !errorlevel! - del Build\gui\cppcheck-gui.pdb || exit /b !errorlevel! + windeployqt build\bin\Release || exit /b !errorlevel! + del build\bin\Release\cppcheck-gui.ilk || exit /b !errorlevel! + del build\bin\Release\cppcheck-gui.pdb || exit /b !errorlevel! - - name: Build GUI release (CMake) - if: startsWith(matrix.qt_ver, '6') + # TODO: run GUI tests + + - name: Run CMake install run: | - cmake -S . -B build -DBUILD_GUI=On -DWITH_QCHART=On -DUSE_QT6=On || exit /b !errorlevel! - cmake --build build --target cppcheck-gui || exit /b !errorlevel! + cmake --build build --target install - # TODO: deploy with CMake/Qt6 + build_cmake_cxxstd: + strategy: + matrix: + os: [windows-2022, windows-2025] + cxxstd: [14, 17, 20] + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Visual Studio environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: Run CMake + run: | + cmake -S . -B build.cxxstd -G "Visual Studio 17 2022" -A x64 -DCMAKE_CXX_STANDARD=${{ matrix.cxxstd }} -DCMAKE_BUILD_TYPE=Debug -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + + - name: Build + run: | + cmake --build build.cxxstd --config Debug || exit /b !errorlevel! build: strategy: matrix: - os: [windows-2019, windows-2022] - arch: [x64, x86] + os: [windows-2022, windows-2025] + config: [debug, release] fail-fast: false runs-on: ${{ matrix.os }} @@ -77,28 +112,31 @@ jobs: PCRE_VERSION: 8.45 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - - name: Set up Python 3.11 - uses: actions/setup-python@v4 + - name: Set up Python + if: matrix.config == 'release' + uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.14' check-latest: true - name: Set up Visual Studio environment uses: ilammy/msvc-dev-cmd@v1 with: - arch: ${{ matrix.arch }} + arch: x64 - name: Cache PCRE id: cache-pcre - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | externals\pcre.h externals\pcre.lib externals\pcre64.lib - key: pcre-${{ env.PCRE_VERSION }}-${{ matrix.arch }}-bin-win + key: pcre-${{ env.PCRE_VERSION }}-x64-bin-win - name: Download PCRE if: steps.cache-pcre.outputs.cache-hit != 'true' @@ -108,75 +146,101 @@ jobs: - name: Install PCRE if: steps.cache-pcre.outputs.cache-hit != 'true' run: | + @echo on 7z x pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! cd pcre-%PCRE_VERSION% || exit /b !errorlevel! - cmake . -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DPCRE_BUILD_PCRECPP=Off -DPCRE_BUILD_TESTS=Off -DPCRE_BUILD_PCREGREP=Off || exit /b !errorlevel! + git apply --ignore-space-change ..\externals\pcre.patch || exit /b !errorlevel! + cmake . -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DPCRE_BUILD_PCRECPP=Off -DPCRE_BUILD_TESTS=Off -DPCRE_BUILD_PCREGREP=Off -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! nmake || exit /b !errorlevel! copy pcre.h ..\externals || exit /b !errorlevel! - if "${{ matrix.arch }}" == "x86" ( - copy pcre.lib ..\externals\pcre.lib || exit /b !errorlevel! - ) else ( - copy pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! - ) + copy pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! env: CL: /MP - name: Install missing Python packages + if: matrix.config == 'release' run: | python -m pip install pip --upgrade || exit /b !errorlevel! python -m pip install pytest || exit /b !errorlevel! python -m pip install pytest-custom_exit_code || exit /b !errorlevel! - - - name: Run CMake - if: false # TODO: enable - run: | - set ARCH=${{ matrix.arch }} - if "${{ matrix.arch }}" == "x86" ( - set ARCH=Win32 - ) - cmake -S . -B build -DBUILD_TESTS=On || exit /b !errorlevel! + python -m pip install pytest-timeout || exit /b !errorlevel! + python -m pip install pytest-xdist || exit /b !errorlevel! + python -m pip install psutil || exit /b !errorlevel! - name: Build CLI debug configuration using MSBuild + if: matrix.config == 'debug' run: | - set ARCH=${{ matrix.arch }} - if "${{ matrix.arch }}" == "x86" ( - set ARCH=Win32 - ) :: cmake --build build --target check --config Debug || exit /b !errorlevel! - msbuild -m cppcheck.sln /p:Configuration=Debug-PCRE;Platform=%ARCH% -maxcpucount || exit /b !errorlevel! + msbuild -m cppcheck.sln /p:Configuration=Debug-PCRE;Platform=x64 -maxcpucount || exit /b !errorlevel! + env: + _CL_: /WX - name: Run Debug test + if: matrix.config == 'debug' run: .\bin\debug\testrunner.exe || exit /b !errorlevel! - name: Build CLI release configuration using MSBuild + if: matrix.config == 'release' run: | - set ARCH=${{ matrix.arch }} - if "${{ matrix.arch }}" == "x86" ( - set ARCH=Win32 - ) :: cmake --build build --target check --config Release || exit /b !errorlevel! - msbuild -m cppcheck.sln /p:Configuration=Release-PCRE;Platform=%ARCH% -maxcpucount || exit /b !errorlevel! + msbuild -m cppcheck.sln /p:Configuration=Release-PCRE;Platform=x64 -maxcpucount || exit /b !errorlevel! + env: + _CL_: /WX - name: Run Release test + if: matrix.config == 'release' run: .\bin\testrunner.exe || exit /b !errorlevel! - - name: Run test/cli + - name: Prepare test/cli + if: matrix.config == 'release' run: | :: since FILESDIR is not set copy the binary to the root so the addons are found :: copy .\build\bin\Release\cppcheck.exe .\cppcheck.exe || exit /b !errorlevel! copy .\bin\cppcheck.exe .\cppcheck.exe || exit /b !errorlevel! copy .\bin\cppcheck-core.dll .\cppcheck-core.dll || exit /b !errorlevel! - cd test/cli || exit /b !errorlevel! - :: python -m pytest --suppress-no-test-exit-code test-clang-import.py || exit /b !errorlevel! - python -m pytest test-helloworld.py || exit /b !errorlevel! - python -m pytest test-inline-suppress.py || exit /b !errorlevel! - python -m pytest test-more-projects.py || exit /b !errorlevel! - python -m pytest test-other.py || exit /b !errorlevel! - python -m pytest test-proj2.py || exit /b !errorlevel! - python -m pytest test-suppress-syntaxError.py || exit /b !errorlevel! + + - name: Run test/cli + if: matrix.config == 'release' + run: | + python -m pytest -Werror --strict-markers -vv -n auto test/cli || exit /b !errorlevel! + + - name: Run test/cli (-j2) + if: matrix.config == 'release' + run: | + python -m pytest -Werror --strict-markers -vv -n auto test/cli || exit /b !errorlevel! + env: + TEST_CPPCHECK_INJECT_J: 2 + + # TODO: install clang + - name: Run test/cli (--clang) + if: false # matrix.config == 'release' + run: | + python -m pytest -Werror --strict-markers -vv -n auto test/cli || exit /b !errorlevel! + env: + TEST_CPPCHECK_INJECT_CLANG: clang + + - name: Run test/cli (--cppcheck-build-dir) + if: matrix.config == 'release' + run: | + python -m pytest -Werror --strict-markers -vv -n auto test/cli || exit /b !errorlevel! + env: + TEST_CPPCHECK_INJECT_BUILDDIR: injected + + # TODO: test with Release configuration? + - name: Test SEH wrapper + if: matrix.config == 'release' + run: | + cmake -S . -B build.cmake.seh -DBUILD_TESTS=On -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake --build build.cmake.seh --target test-sehwrapper || exit /b !errorlevel! + :: TODO: how to run this without copying the file? + copy build.cmake.seh\bin\Debug\test-sehwrapper.exe . || exit /b !errorlevel! + python3 -m pytest -Werror --strict-markers -vv test/seh/test-sehwrapper.py || exit /b !errorlevel! + del test-sehwrapper.exe || exit /b !errorlevel! - name: Test addons + if: matrix.config == 'release' run: | + echo on .\cppcheck --addon=threadsafety addons\test\threadsafety || exit /b !errorlevel! .\cppcheck --addon=threadsafety --std=c++03 addons\test\threadsafety || exit /b !errorlevel! .\cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons\test\misra\misra-ctu-*-test.c || exit /b !errorlevel! @@ -185,6 +249,9 @@ jobs: rem rules 5.4 and 5.5 which have standard-dependent options. ..\..\cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64 || exit /b !errorlevel! python3 ..\misra.py -verify misra\misra-test.c.dump || exit /b !errorlevel! + rem Test slight MISRA differences in C11 standard + ..\..\cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test-c11.c --std=c11 --platform=unix64 || exit /b !errorlevel! + python3 ..\misra.py -verify misra\misra-test-c11.c.dump || exit /b !errorlevel! rem TODO: do we need to verify something here? ..\..\cppcheck --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra\misra-test.h || exit /b !errorlevel! ..\..\cppcheck --dump misra\misra-test.cpp || exit /b !errorlevel! @@ -200,6 +267,30 @@ jobs: rem python3 ..\naming.py --var='[a-z].*' --function='[a-z].*' naming_test.c.dump || exit /b !errorlevel! ..\..\cppcheck --dump naming_test.cpp || exit /b !errorlevel! python3 ..\naming.py --var='[a-z].*' --function='[a-z].*' naming_test.cpp.dump || exit /b !errorlevel! - ..\..\cppcheck --dump namingng_test.c || exit /b !errorlevel! - python3 ..\namingng.py --configfile ..\naming.json --verify namingng_test.c.dump || exit /b !errorlevel! + # TODO: run with "-n auto" when misra_test.py can be run in parallel + - name: test addons (Python) + if: matrix.config == 'release' + run: | + python -m pytest -Werror --strict-markers -vv -n 1 addons/test || exit /b !errorlevel! + env: + PYTHONPATH: ./addons + + - name: Check Windows test syntax + if: matrix.config == 'debug' + run: | + cd test\cfg + cl.exe windows.cpp -DUNICODE=1 -D_UNICODE=1 /Zs || exit /b !errorlevel! + cl.exe mfc.cpp /EHsc /Zs || exit /b !errorlevel! + + - name: Show all ignored files + if: false # TODO: currently lists all the contents of ignored folders - we only need what actually matched + run: | + git ls-files --others --ignored --exclude-standard || exit /b !errorlevel! + + - name: Check for changed and unversioned files + run: | + :: TODO: how to do this with a single command? + git status --ignored=no + :: TODO: make this work + :: git status --ignored=no | grep -q 'working tree clean' diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml index df2cb0534d4..70b3a30f0ae 100644 --- a/.github/workflows/asan.yml +++ b/.github/workflows/asan.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: address sanitizer -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -13,50 +21,63 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 ASAN_OPTIONS: detect_stack_use_after_return=1 + LSAN_OPTIONS: suppressions=lsan-suppr.txt:print_suppressions=0 # TODO: figure out why there are cache misses with PCH enabled CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} - - name: Set up Python 3.11 - uses: actions/setup-python@v4 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.14' check-latest: true - name: Install missing software on ubuntu run: | sudo apt-get update - sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev + sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev libxml2-utils + sudo apt-get install -y libcups2-dev # required for Qt6PrintSupport in CMake since Qt 6.7.3 - name: Install clang run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 16 + sudo ./llvm.sh 21 - name: Install Qt ${{ env.QT_VERSION }} - if: false - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + setup-python: 'false' cache: true + - name: Install missing Python packages + run: | + python3 -m pip install pip --upgrade + python3 -m pip install pytest + python3 -m pip install pytest-timeout + python3 -m pip install pytest-xdist + python3 -m pip install psutil + - name: CMake run: | - cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_ADDRESS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DANALYZE_ADDRESS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DFILESDIR= -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache env: - CC: clang-16 - CXX: clang++-16 + CC: clang-21 + CXX: clang++-21 - name: Build cppcheck run: | @@ -66,9 +87,49 @@ jobs: run: | cmake --build cmake.output --target testrunner -- -j $(nproc) + - name: Build GUI tests + run: | + cmake --build cmake.output --target gui-tests -- -j $(nproc) + - name: Run tests run: ./cmake.output/bin/testrunner + - name: Run cfg tests + run: | + cmake --build cmake.output --target checkcfg -- -j $(nproc) + + - name: Run CTest + run: | + cp lsan-suppr.txt cmake.output/bin + ctest --test-dir cmake.output --output-on-failure -j$(nproc) + + - name: Run test/cli + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + + - name: Run test/cli (-j2) + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_J: 2 + + - name: Run test/cli (--clang) + if: false + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_CLANG: clang + + - name: Run test/cli (--cppcheck-build-dir) + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_BUILDDIR: injected + - name: Generate dependencies if: false run: | @@ -81,10 +142,17 @@ jobs: - name: Self check if: false run: | - selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=file-total -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,information --exception-handling --debug-warnings --check-level=exhaustive" + cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2" + gui_options="-DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt" + gui_options="$gui_options --suppress=autoNoType:*/moc_*.cpp --suppress=symbolDatabaseWarning:*/moc_*.cpp" ec=0 - ./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json cli lib || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options externals || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json frontend || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json -Ifrontend cli || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json --enable=internal lib || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options $gui_options --addon=naming.json --suppress=constVariablePointer:*/moc_*.cpp -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli -Ifrontend test/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options $gui_options -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1 exit $ec diff --git a/.github/workflows/buildman.yml b/.github/workflows/buildman.yml index 4bbdf779661..b0b399dd851 100644 --- a/.github/workflows/buildman.yml +++ b/.github/workflows/buildman.yml @@ -1,28 +1,65 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: Build manual -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read jobs: convert_via_pandoc: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - run: | mkdir output - - uses: docker://pandoc/latex:2.9 + - uses: docker://pandoc/latex:3.6.3 with: args: --output=output/manual.html man/manual.md - - - uses: docker://pandoc/latex:2.9 + + - uses: docker://pandoc/latex:3.6.3 with: - args: --output=output/manual.pdf man/manual.md - - - uses: actions/upload-artifact@v3 + args: --output=output/manual.pdf man/manual.md + + - uses: docker://pandoc/latex:3.6.3 + with: + args: --output=output/manual-premium.pdf man/manual-premium.md + + - uses: actions/upload-artifact@v4 with: name: output path: output + + manpage: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install -y xsltproc docbook-xsl + + - name: build manpage + run: | + make man + + - uses: actions/upload-artifact@v4 + with: + name: cppcheck.1 + path: cppcheck.1 diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 19c40de61c9..7b462c688f0 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -1,8 +1,16 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: CIFuzz + on: [pull_request] + +permissions: + contents: read + jobs: Fuzzing: runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'danmar' }} steps: - name: Build Fuzzers id: build @@ -19,7 +27,7 @@ jobs: dry-run: false language: c++ - name: Upload Crash - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() && steps.build.outcome == 'success' with: name: artifacts diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 5352c28118a..7b2c4f4e2c7 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -2,7 +2,18 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: clang-tidy -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: permissions: contents: read @@ -13,53 +24,70 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Install missing software run: | sudo apt-get update sudo apt-get install -y cmake make sudo apt-get install -y libpcre3-dev - sudo apt-get install -y libffi7 # work around missing dependency for Qt install step + sudo apt-get install -y libgl-dev # fixes missing dependency for Qt in CMake - name: Install clang run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 16 - sudo apt-get install -y clang-tidy-16 + sudo ./llvm.sh 21 + sudo apt-get install -y clang-tidy-21 - name: Install Qt ${{ env.QT_VERSION }} - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + setup-python: 'false' + install-deps: false cache: true - name: Verify clang-tidy configuration run: | - clang-tidy-16 --verify-config + clang-tidy-21 --verify-config - name: Prepare CMake run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCPPCHK_GLIBCXX_DEBUG=Off + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off -DWARNINGS_ARE_ERRORS=On env: - CC: clang-16 - CXX: clang++-16 + CC: clang-21 + CXX: clang++-21 - name: Prepare CMake dependencies run: | + # make sure the auto-generated GUI sources exist + make -C cmake.output autogen # make sure the precompiled headers exist make -C cmake.output/cli cmake_pch.hxx.pch make -C cmake.output/gui cmake_pch.hxx.pch make -C cmake.output/lib cmake_pch.hxx.pch make -C cmake.output/test cmake_pch.hxx.pch - # make sure the auto-generated GUI sources exist - make -C cmake.output autogen - name: Clang-Tidy + if: ${{ github.event.schedule == '' && github.event_name != 'workflow_dispatch' }} run: | cmake --build cmake.output --target run-clang-tidy 2> /dev/null + + - name: Clang Static Analyzer + if: ${{ github.event.schedule != '' || github.event_name == 'workflow_dispatch' }} + run: | + cmake --build cmake.output --target run-clang-tidy-csa 2> /dev/null + + - uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: Compilation Database + path: ./cmake.output/compile_commands.json diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 12d15855527..12e758d2c9e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,15 +1,26 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: "CodeQL" -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read - security-events: write jobs: analyze: name: Analyze runs-on: ubuntu-22.04 + permissions: + security-events: write strategy: fail-fast: false @@ -22,26 +33,20 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + persist-credentials: false - - name: Install missing software on ubuntu - run: | - sudo apt-get update - sudo apt-get install libxml2-utils - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - setup-python-dependencies: false - - run: | - make -j$(nproc) HAVE_RULES=yes cppcheck + - name: Build cppcheck + if: matrix.language == 'cpp' + run: | + make -j$(nproc) CXXOPTS="-Werror" HAVE_RULES=yes CPPCHK_GLIBCXX_DEBUG= cppcheck - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b07c15811cd..13f56172a80 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: Coverage -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -13,7 +21,9 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -33,7 +43,7 @@ jobs: - name: Compile instrumented run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) all CXXFLAGS="-g -fprofile-arcs -ftest-coverage" HAVE_RULES=yes + make -j$(nproc) CXXOPTS="-Werror -g -fprofile-arcs -ftest-coverage" HAVE_RULES=yes CPPCHK_GLIBCXX_DEBUG= all - name: Run instrumented tests run: | @@ -47,14 +57,14 @@ jobs: lcov --extract lcov_tmp.info "$(pwd)/*" --output-file lcov.info genhtml lcov.info -o coverage_report --frame --legend --demangle-cpp - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Coverage results path: coverage_report - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v4 with: - # token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos + token: ${{ secrets.CODECOV_TOKEN }} # file: ./coverage.xml # optional flags: unittests # optional name: ${{ github.repository }} # optional diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 00000000000..3c07b61d7c7 --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,41 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: Coverity + +on: + schedule: + - cron: "0 0 * * *" + +permissions: + contents: read + +jobs: + scan: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'danmar' }} + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Install missing software on ubuntu + run: | + sudo apt-get update + sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev libboost-container-dev + - name: Download Coverity build tool + run: | + wget -c -N https://scan.coverity.com/download/linux64 --post-data "token=${{ secrets.COVERITY_SCAN_TOKEN }}&project=cppcheck" -O coverity_tool.tar.gz + mkdir coverity_tool + tar xzf coverity_tool.tar.gz --strip 1 -C coverity_tool + - name: Build with Coverity build tool + run: | + export PATH=`pwd`/coverity_tool/bin:$PATH + cov-build --dir cov-int make CPPCHK_GLIBCXX_DEBUG= + - name: Submit build result to Coverity Scan + run: | + tar czvf cov.tar.gz cov-int + curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \ + --form email=daniel.marjamaki@gmail.com \ + --form file=@cov.tar.gz \ + --form version="Commit $GITHUB_SHA" \ + --form description="Development" \ + https://scan.coverity.com/builds?project=cppcheck diff --git a/.github/workflows/cppcheck-premium.yml b/.github/workflows/cppcheck-premium.yml new file mode 100644 index 00000000000..5cb63ca4d5e --- /dev/null +++ b/.github/workflows/cppcheck-premium.yml @@ -0,0 +1,72 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: cppcheck-premium + +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: + workflow_dispatch: + inputs: + premium_version: + description: 'Cppcheck Premium version' + +permissions: + contents: read + security-events: write + +jobs: + + build: + runs-on: ubuntu-24.04 # run on the latest image only + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Download cppcheckpremium release + run: | + premium_version=${{ inputs.premium_version }} + if [ -z $premium_version ]; then + premium_version=25.8.3 + #wget https://files.cppchecksolutions.com/devdrop/cppcheckpremium-$premium_version-amd64.tar.gz -O cppcheckpremium.tar.gz + wget https://files.cppchecksolutions.com/$premium_version/ubuntu-24.04/cppcheckpremium-$premium_version-amd64.tar.gz -O cppcheckpremium.tar.gz + else + wget https://files.cppchecksolutions.com/$premium_version/ubuntu-24.04/cppcheckpremium-$premium_version-amd64.tar.gz -O cppcheckpremium.tar.gz + fi + tar xzf cppcheckpremium.tar.gz + mv cppcheckpremium-$premium_version cppcheckpremium + + - name: Generate a license file + run: | + echo cppcheck > cppcheck.lic + echo 261231 >> cppcheck.lic + echo 80000 >> cppcheck.lic + echo 4b64673f03fb6230 >> cppcheck.lic + echo path:lib >> cppcheck.lic + + - name: Check + run: | + cppcheckpremium/premiumaddon --check-loc-license cppcheck.lic > cppcheck-premium-loc + cppcheckpremium/cppcheck --premium=safety-off -j$(nproc) -D__GNUC__ -D__CPPCHECK__ --suppressions-list=cppcheckpremium-suppressions --platform=unix64 --enable=style --premium=misra-c++-2023 --premium=cert-c++-2016 --inline-suppr lib --error-exitcode=0 --output-format=sarif 2> results.sarif + + - name: Cat results + run: | + #sed -i 's|"security-severity":.*||' results.sarif + cat results.sarif + + - uses: actions/upload-artifact@v4 + with: + name: results + path: results.sarif + + - name: Upload report + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif + category: cppcheckpremium diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index ff3134b7ed5..fd491c0ec0e 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: format -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -12,29 +20,36 @@ jobs: runs-on: ubuntu-22.04 + env: + UNCRUSTIFY_VERSION: 0.80.1 + steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Cache uncrustify - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache-uncrustify with: path: | ~/uncrustify - key: ${{ runner.os }}-uncrustify + key: ${{ runner.os }}-uncrustify-${{ env.UNCRUSTIFY_VERSION }} - name: build uncrustify if: steps.cache-uncrustify.outputs.cache-hit != 'true' run: | - wget https://github.com/uncrustify/uncrustify/archive/refs/tags/uncrustify-0.72.0.tar.gz - tar xzvf uncrustify-0.72.0.tar.gz && cd uncrustify-uncrustify-0.72.0 + set -x + wget https://github.com/uncrustify/uncrustify/archive/refs/tags/uncrustify-${{ env.UNCRUSTIFY_VERSION }}.tar.gz + tar xzvf uncrustify-${{ env.UNCRUSTIFY_VERSION }}.tar.gz + cd uncrustify-uncrustify-${{ env.UNCRUSTIFY_VERSION }} cmake -S . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -- -j$(nproc) -s mkdir ~/uncrustify - cd build && cp uncrustify ~/uncrustify/ + cp build/uncrustify ~/uncrustify/ - name: Uncrustify check run: | - ~/uncrustify/uncrustify -c .uncrustify.cfg -l CPP --no-backup --replace */*.cpp */*.h + UNCRUSTIFY=~/uncrustify/uncrustify ./runformat git diff git diff | diff - /dev/null &> /dev/null diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml index 01c705b9da5..649991f9373 100644 --- a/.github/workflows/iwyu.yml +++ b/.github/workflows/iwyu.yml @@ -2,7 +2,10 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: include-what-you-use -on: workflow_dispatch +on: + schedule: + - cron: '0 0 * * 0' + workflow_dispatch: permissions: contents: read @@ -10,32 +13,57 @@ permissions: jobs: iwyu: - runs-on: ubuntu-22.04 + strategy: + matrix: + # "opensuse/tumbleweed:latest" / "fedora:latest" / "debian:unstable" / "archlinux:latest" + include: + - os: ubuntu-22.04 + image: "fedora:latest" + stdlib: libstdc++ + clang_inc: '-isystem/usr/lib/clang/20/include' + # TODO: disable because it currently fails with "error: tried including but didn't find libc++'s header." + #- os: ubuntu-22.04 + # image: "fedora:latest" + # stdlib: libc++ + # clang_inc: '-isystem/usr/lib/clang/20/include' + - os: macos-13 + image: "" + stdlib: libc++ # no libstdc++ on macOS + mapping_file_opt: '-Xiwyu --mapping_file=$(realpath ./macos.imp)' + fail-fast: false + + runs-on: ${{ matrix.os }} + if: ${{ github.repository_owner == 'danmar' }} container: - image: "archlinux:latest" + image: ${{ matrix.image }} + + env: + QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - # TODO: the necessary packages are excessive - mostly because of Qt - use a pre-built image - name: Install missing software on debian/ubuntu - if: false + if: contains(matrix.image, 'debian') run: | apt-get update - apt-get install -y cmake g++ make libpcre3-dev - apt-get install -y qtbase5-dev qttools5-dev libqt5charts5-dev - apt-get install -y wget iwyu - ln -s ../x86_64-linux-gnu/qt5 /usr/include/qt + apt-get install -y cmake clang make libpcre3-dev + apt-get install -y libgl-dev # fixes missing dependency for Qt in CMake + apt-get install -y iwyu - name: Install missing software on archlinux + if: contains(matrix.image, 'archlinux') run: | set -x pacman -Sy - pacman -S cmake make gcc qt5-base qt5-tools qt5-charts pcre wget --noconfirm + pacman -S cmake make clang pcre --noconfirm + pacman -S libglvnd --noconfirm # fixes missing dependency for Qt in CMake pacman-key --init - pacman-key --recv-key FBA220DFC880C036 --keyserver keyserver.ubuntu.com - pacman-key --lsign-key FBA220DFC880C036 + pacman-key --recv-key 3056513887B78AEB --keyserver keyserver.ubuntu.com + pacman-key --lsign-key 3056513887B78AEB pacman -U 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-keyring.pkg.tar.zst' 'https://cdn-mirror.chaotic.cx/chaotic-aur/chaotic-mirrorlist.pkg.tar.zst' --noconfirm echo "[chaotic-aur]" >> /etc/pacman.conf echo "Include = /etc/pacman.d/chaotic-mirrorlist" >> /etc/pacman.conf @@ -43,107 +71,198 @@ jobs: pacman -S include-what-you-use --noconfirm ln -s iwyu-tool /usr/sbin/iwyu_tool + - name: Install missing software on Fedora + if: contains(matrix.image, 'fedora') + run: | + dnf install -y cmake clang pcre-devel + dnf install -y libglvnd-devel # fixes missing dependency for Qt in CMake + dnf install -y p7zip-plugins # required as fallback for py7zr in Qt installation + dnf install -y python3-pip # fixes missing pip module in jurplel/install-qt-action + dnf install -y python3-devel # fixes building of wheels for jurplel/install-qt-action + dnf install -y cairo-devel gtk3-devel libcurl-devel lua-devel openssl-devel python3-devel sqlite-devel boost-devel cppunit-devel libsigc++20-devel # for strict cfg checks + dnf install -y iwyu + ln -s iwyu_tool.py /usr/bin/iwyu_tool + + - name: Install missing software on Fedora (libc++) + if: contains(matrix.image, 'fedora') && matrix.stdlib == 'libc++' + run: | + dnf install -y libcxx-devel + + - name: Install missing software on OpenSUSE + if: contains(matrix.image, 'opensuse') + run: | + zypper install -y cmake clang pcre-devel + zypper install -y include-what-you-use-tools + ln -s iwyu_tool.py /usr/bin/iwyu_tool + + # coreutils contains "nproc" + - name: Install missing software on macOS + if: contains(matrix.os, 'macos') + run: | + brew install include-what-you-use pcre coreutils + ln -s iwyu_tool.py /usr/local/bin/iwyu_tool + + # Fails on OpenSUSE: + # Warning: Failed to restore: Tar failed with error: Unable to locate executable file: tar. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable. + # Also the shell is broken afterwards: + # OCI runtime exec failed: exec failed: unable to start container process: exec: "sh": executable file not found in $PATH: unknown + - name: Install Qt ${{ env.QT_VERSION }} + uses: jurplel/install-qt-action@v4 + with: + version: ${{ env.QT_VERSION }} + modules: 'qtcharts' + setup-python: 'false' + install-deps: false + cache: true + + - name: Generate macOS mappings + if: contains(matrix.os, 'macos') + run: | + set -x + + wget https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/master/mapgen/iwyu-mapgen-apple-libc.py + python3 iwyu-mapgen-apple-libc.py $(xcrun --show-sdk-path)/usr/include > macos.imp + - name: Prepare CMake run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.stdlib == 'libc++' }} + env: + CC: clang + CXX: clang++ + # Fails on Debian: + # /__w/cppcheck/Qt/6.7.0/gcc_64/libexec/rcc: error while loading shared libraries: libglib-2.0.so.0: cannot open shared object file: No such file or directory - name: Prepare CMake dependencies run: | + # make sure the auto-generated GUI sources exist + make -C cmake.output autogen # make sure the precompiled headers exist #make -C cmake.output/cli cmake_pch.hxx.pch #make -C cmake.output/gui cmake_pch.hxx.pch #make -C cmake.output/lib cmake_pch.hxx.pch #make -C cmake.output/test cmake_pch.hxx.pch - # make sure the auto-generated GUI sources exist - make -C cmake.output autogen # make sure the auto-generated GUI dependencies exist make -C cmake.output gui-build-deps make -C cmake.output triage-build-ui-deps - - name: Build Qt mappings + - name: iwyu_tool run: | - wget https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/master/mapgen/iwyu-mapgen-qt.py - python3 iwyu-mapgen-qt.py /usr/include/qt/ > qt5.imp + # TODO: remove -stdlib= - it should have been taken from the compilation database + iwyu_tool -p cmake.output -j $(nproc) -- -w -Xiwyu --max_line_length=1024 -Xiwyu --comment_style=long -Xiwyu --quoted_includes_first -Xiwyu --update_comments -stdlib=${{ matrix.stdlib }} ${{ matrix.mapping_file_opt }} ${{ matrix.clang_inc }} > iwyu.log - - name: iwyu_tool + # TODO: run with all configurations + - name: test/cfg + if: matrix.stdlib == 'libstdc++' run: | - PWD=$(pwd) - iwyu_tool -p cmake.output -j $(nproc) -- -w -Xiwyu --mapping_file=$PWD/qt5.imp > iwyu.log + # TODO: redirect to log + ./test/cfg/runtests.sh + env: + IWYU: include-what-you-use + IWYU_CLANG_INC: ${{ matrix.clang_inc }} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: success() || failure() with: - name: Compilation Database + name: Compilation Database (include-what-you-use - ${{ matrix.os }} ${{ matrix.stdlib }}) path: ./cmake.output/compile_commands.json - - uses: actions/upload-artifact@v3 - if: success() || failure() + - uses: actions/upload-artifact@v4 + if: ${{ contains(matrix.os, 'macos') && (success() || failure()) }} with: - name: Qt Mappings - path: ./qt5.imp + name: macOS Mappings + path: | + ./iwyu-mapgen-apple-libc.py + ./macos.imp - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: success() || failure() with: - name: Logs (include-what-you-use) + name: Logs (include-what-you-use - ${{ matrix.os }} ${{ matrix.stdlib }}) path: ./*.log clang-include-cleaner: + strategy: + matrix: + stdlib: [libstdc++, libc++] + include: + - stdlib: libstdc++ + use_libcxx: Off + - stdlib: libc++ + use_libcxx: On + fail-fast: false + runs-on: ubuntu-22.04 + if: ${{ github.repository_owner == 'danmar' }} env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Install missing software run: | sudo apt-get update - sudo apt-get install -y cmake make - sudo apt-get install -y libpcre3-dev - sudo apt-get install -y libffi7 # work around missing dependency for Qt install step + sudo apt-get install -y cmake make libpcre3-dev + sudo apt-get install -y libgl-dev # missing dependency for using Qt in CMake - name: Install clang run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 17 - sudo apt-get install -y clang-tools-17 + sudo ./llvm.sh 21 + sudo apt-get install -y clang-tools-21 + + - name: Install libc++ + if: matrix.stdlib == 'libc++' + run: | + sudo apt-get install -y libc++-21-dev - name: Install Qt ${{ env.QT_VERSION }} - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + setup-python: 'false' + install-deps: false cache: true - name: Prepare CMake run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off + cmake -S . -B cmake.output -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCPPCHK_GLIBCXX_DEBUG=Off -DUSE_MATCHCOMPILER=Off -DEXTERNALS_AS_SYSTEM=On -DUSE_LIBCXX=${{ matrix.use_libcxx }} env: - CC: clang-17 - CXX: clang++-17 + CC: clang-21 + CXX: clang++-21 - name: Prepare CMake dependencies run: | + # make sure the auto-generated GUI sources exist + make -C cmake.output autogen # make sure the precompiled headers exist #make -C cmake.output/cli cmake_pch.hxx.pch #make -C cmake.output/gui cmake_pch.hxx.pch #make -C cmake.output/lib cmake_pch.hxx.pch #make -C cmake.output/test cmake_pch.hxx.pch - # make sure the auto-generated GUI sources exist - make -C cmake.output autogen # make sure the auto-generated GUI dependencies exist make -C cmake.output gui-build-deps - name: clang-include-cleaner run: | # TODO: run multi-threaded - find $PWD/cli $PWD/lib $PWD/test -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-17 --print=changes --extra-arg=-w -p cmake.output > clang-include-cleaner.log 2>&1 + find $PWD/cli $PWD/lib $PWD/test $PWD/gui -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-21 --print=changes --extra-arg=-w --extra-arg=-stdlib=${{ matrix.stdlib }} -p cmake.output > clang-include-cleaner.log 2>&1 - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 + if: success() || failure() with: - name: Logs (clang-include-cleaner) - path: ./*.log \ No newline at end of file + name: Compilation Database (clang-include-cleaner - ${{ matrix.stdlib }}) + path: ./cmake.output/compile_commands.json + + - uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: Logs (clang-include-cleaner - ${{ matrix.stdlib }}) + path: ./*.log diff --git a/.github/workflows/release-windows-mingw.yml b/.github/workflows/release-windows-mingw.yml new file mode 100644 index 00000000000..3b9b836347f --- /dev/null +++ b/.github/workflows/release-windows-mingw.yml @@ -0,0 +1,69 @@ +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners +name: release-windows-mingw + +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: + +permissions: + contents: read + +defaults: + run: + shell: msys2 {0} + +jobs: + # TODO: add CMake build + build_mingw: + strategy: + matrix: + # only use the latest windows-* as the installed toolchain is identical + os: [windows-2025] + fail-fast: false + + runs-on: ${{ matrix.os }} + + timeout-minutes: 19 # max + 3*std of the last 7K runs + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up MSYS2 + uses: msys2/setup-msys2@v2 + with: + release: false # use pre-installed + # TODO: install mingw-w64-x86_64-make and use mingw32.make instead - currently fails with "Windows Subsystem for Linux has no installed distributions." + install: >- + mingw-w64-x86_64-lld + make + mingw-w64-x86_64-gcc + python + + - name: Build cppcheck + run: | + export PATH="/mingw64/lib/ccache/bin:$PATH" + # set RDYNAMIC to work around broken MinGW detection + make VERBOSE=1 RDYNAMIC=-lshlwapi -j$(nproc) CXXFLAGS=-O2 MATCHCOMPILER=yes cppcheck + + - name: Package + run: | + mkdir cppcheck-mingw + cp cppcheck.exe cppcheck-mingw/ + cp -R cfg platforms cppcheck-mingw/ + cp /mingw64/bin/libgcc_s_seh-1.dll cppcheck-mingw/ + cp /mingw64/bin/libstdc*.dll cppcheck-mingw/ + cp /mingw64/bin/libwinpthread-1.dll cppcheck-mingw/ + + - uses: actions/upload-artifact@v4 + with: + name: cppcheck-mingw + path: cppcheck-mingw diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index ab6836c9559..2836000acc5 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -1,7 +1,5 @@ -# Some convenient links: -# - https://github.com/actions/virtual-environments/blob/master/images/win/Windows2019-Readme.md -# - +# Syntax reference https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: release-windows on: @@ -23,123 +21,189 @@ jobs: build: - runs-on: windows-2022 + runs-on: windows-2025 + if: ${{ github.repository_owner == 'danmar' }} env: # see https://www.pcre.org/original/changelog.txt PCRE_VERSION: 8.45 - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 + BOOST_MINOR_VERSION: 89 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Set up Visual Studio environment uses: ilammy/msvc-dev-cmd@v1 - - name: Cache PCRE - id: cache-pcre - uses: actions/cache@v3 - with: - path: | - externals\pcre.h - externals\pcre64.lib - key: pcre-${{ env.PCRE_VERSION }}-bin-x64-win-release-job - - name: Download PCRE - if: steps.cache-pcre.outputs.cache-hit != 'true' run: | curl -fsSL https://github.com/pfultz2/pcre/archive/refs/tags/%PCRE_VERSION%.zip -o pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! - name: Install PCRE - if: steps.cache-pcre.outputs.cache-hit != 'true' run: | + @echo on 7z x pcre-%PCRE_VERSION%.zip || exit /b !errorlevel! cd pcre-%PCRE_VERSION% || exit /b !errorlevel! - cmake . -G "Visual Studio 17 2022" -A x64 -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF || exit /b !errorlevel! + git apply --ignore-space-change ..\externals\pcre.patch || exit /b !errorlevel! + cmake . -G "Visual Studio 17 2022" -A x64 -DPCRE_BUILD_PCRECPP=OFF -DPCRE_BUILD_PCREGREP=OFF -DPCRE_BUILD_TESTS=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! msbuild -m PCRE.sln -p:Configuration=Release -p:Platform=x64 || exit /b !errorlevel! copy pcre.h ..\externals || exit /b !errorlevel! copy Release\pcre.lib ..\externals\pcre64.lib || exit /b !errorlevel! + - name: Download Boost + run: | + curl -fsSL https://archives.boost.io/release/1.%BOOST_MINOR_VERSION%.0/source/boost_1_%BOOST_MINOR_VERSION%_0.7z -o boost.zip || exit /b !errorlevel! + + - name: Install Boost + run: | + @echo on + 7z x boost.zip boost_1_%BOOST_MINOR_VERSION%_0/boost || exit /b !errorlevel! + ren boost_1_%BOOST_MINOR_VERSION%_0 boost || exit /b !errorlevel! + # available modules: https://github.com/miurahr/aqtinstall/blob/master/docs/getting_started.rst#installing-modules # available tools: https://github.com/miurahr/aqtinstall/blob/master/docs/getting_started.rst#installing-tools - name: Install Qt ${{ env.QT_VERSION }} - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' - tools: 'tools_openssl_x64,qt.tools.openssl.win_x64' - cache: true + setup-python: 'false' + tools: 'tools_opensslv3_x64' + aqtversion: '==3.1.*' # TODO: remove when aqtinstall 3.2.2 is available - - name: Create .qm + # TODO: build with multiple threads + - name: Build x64 release GUI run: | - cd gui || exit /b !errorlevel! - lupdate gui.pro -no-obsolete || exit /b !errorlevel! - lrelease gui.pro -removeidentical || exit /b !errorlevel! + :: TODO: enable rules? + :: specify Release build so matchcompiler is used + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_ONLINE_HELP=On -DUSE_BOOST=ON -DBOOST_INCLUDEDIR=%GITHUB_WORKSPACE%\boost -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel! + cmake --build build --target cppcheck-gui --config Release || exit /b !errorlevel! + + # TODO: package PDBs + - name: Deploy app + run: | + windeployqt build\bin\Release || exit /b !errorlevel! + del build\bin\Release\cppcheck-gui.ilk || exit /b !errorlevel! + del build\bin\Release\cppcheck-gui.pdb || exit /b !errorlevel! + + - uses: actions/upload-artifact@v4 + with: + name: deploy + path: build\bin\Release - name: Matchcompiler run: python tools\matchcompiler.py --write-dir lib || exit /b !errorlevel! - - name: Build x64 release GUI - run: | - cd gui || exit /b !errorlevel! - qmake HAVE_QCHART=yes || exit /b !errorlevel! - nmake release || exit /b !errorlevel! + # TODO: build with multiple threads + - name: Build CLI x64 release configuration using MSBuild + run: msbuild -m cppcheck.sln -t:cli -p:Configuration=Release-PCRE -p:Platform=x64 -p:HaveBoost=HAVE_BOOST -p:BoostInclude=%GITHUB_WORKSPACE%\boost || exit /b !errorlevel! env: - CL: /MP + _CL_: /WX - - name: Deploy app - run: | - windeployqt Build\gui || exit /b !errorlevel! - del Build\gui\cppcheck-gui.ilk || exit /b !errorlevel! - del Build\gui\cppcheck-gui.pdb || exit /b !errorlevel! + - uses: actions/upload-artifact@v4 + with: + name: bin + path: bin - # TODO: build with boost enabled - - name: Build CLI x64 release configuration using MSBuild - run: msbuild -m cppcheck.sln -t:cli -p:Configuration=Release-PCRE -p:Platform=x64 || exit /b !errorlevel! + - name: Install missing Python packages + run: | + pip install -U pyinstaller || exit /b !errorlevel! + # TODO: include in installer? - name: Compile misra.py executable run: | - pip install -U pyinstaller || exit /b !errorlevel! cd addons || exit /b !errorlevel! pyinstaller --hidden-import xml --hidden-import xml.etree --hidden-import xml.etree.ElementTree misra.py || exit /b !errorlevel! del *.spec || exit /b !errorlevel! + # TODO: include in installer? + - name: Compile cppcheck-htmlreport executable + run: | + cd htmlreport || exit /b !errorlevel! + pyinstaller cppcheck-htmlreport || exit /b !errorlevel! + del *.spec || exit /b !errorlevel! + + # TODO: test the compiled Python files + - name: Collect files run: | - move Build\gui win_installer\files || exit /b !errorlevel! - mkdir win_installer\files\addons || exit /b !errorlevel! - copy addons\*.* win_installer\files\addons || exit /b !errorlevel! + @echo on + move build\bin\Release win_installer\files || exit /b !errorlevel! + copy AUTHORS win_installer\files\authors.txt || exit /b !errorlevel! + copy win_installer\GPLv3.txt win_installer\files\ || exit /b !errorlevel! + copy externals\picojson\LICENSE win_installer\files\picojson-license.txt || exit /b !errorlevel! + copy externals\simplecpp\LICENSE win_installer\files\simplecpp-license.txt || exit /b !errorlevel! + copy externals\tinyxml2\LICENSE win_installer\files\tinyxml2-license.txt || exit /b !errorlevel! copy addons\dist\misra\*.* win_installer\files\addons || exit /b !errorlevel! - mkdir win_installer\files\cfg || exit /b !errorlevel! - copy cfg\*.cfg win_installer\files\cfg || exit /b !errorlevel! - :: "platforms" is a folder used by Qt as well so it already exists - :: mkdir win_installer\files\platforms || exit /b !errorlevel! - copy platforms\*.xml win_installer\files\platforms || exit /b !errorlevel! copy bin\cppcheck.exe win_installer\files || exit /b !errorlevel! copy bin\cppcheck-core.dll win_installer\files || exit /b !errorlevel! - mkdir win_installer\files\help || exit /b !errorlevel! + :: mkdir win_installer\files\help || exit /b !errorlevel! xcopy /s gui\help win_installer\files\help || exit /b !errorlevel! + copy gui\help\online-help.qhc win_installer\files\ || exit /b !errorlevel! + copy gui\help\online-help.qch win_installer\files\ || exit /b !errorlevel! + del win_installer\files\cfg\*.rng || exit /b !errorlevel! + del win_installer\files\platforms\*.rng || exit /b !errorlevel! del win_installer\files\translations\*.qm || exit /b !errorlevel! - move gui\*.qm win_installer\files\translations || exit /b !errorlevel! - :: copy libcrypto-1_1-x64.dll and libssl-1_1-x64.dll - copy %RUNNER_WORKSPACE%\Qt\Tools\OpenSSL\Win_x64\bin\lib*.dll win_installer\files || exit /b !errorlevel! + move build\gui\*.qm win_installer\files\translations || exit /b !errorlevel! + copy htmlreport\dist\cppcheck-htmlreport\*.* win_installer\files || exit /b !errorlevel! + :: copy libcrypto-3-x64.dll and libssl-3-x64.dll + copy %RUNNER_WORKSPACE%\Qt\Tools\OpenSSLv3\Win_x64\bin\lib*.dll win_installer\files || exit /b !errorlevel! + + - uses: actions/upload-artifact@v4 + with: + name: collect + path: win_installer\files - name: Build Installer run: | cd win_installer || exit /b !errorlevel! - REM Read ProductVersion + :: Read ProductVersion for /f "tokens=4 delims= " %%a in ('find "ProductVersion" productInfo.wxi') do set PRODUCTVER=%%a - REM Remove double quotes + :: Remove double quotes set PRODUCTVER=%PRODUCTVER:"=% - echo ProductVersion="%PRODUCTVER%" || exit /b !errorlevel! + @echo ProductVersion="%PRODUCTVER%" || exit /b !errorlevel! msbuild -m cppcheck.wixproj -p:Platform=x64,ProductVersion=%PRODUCTVER%.${{ github.run_number }} || exit /b !errorlevel! - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: installer path: win_installer/Build/ - - uses: actions/upload-artifact@v3 + - name: Clean up deploy + run: | + @echo on + :: del win_installer\files\addons\*.dll || exit /b !errorlevel! + del win_installer\files\addons\*.doxyfile || exit /b !errorlevel! + del win_installer\files\addons\*.md || exit /b !errorlevel! + :: del win_installer\files\addons\*.pyd || exit /b !errorlevel! + :: del win_installer\files\addons\base_library.zip || exit /b !errorlevel! + rmdir /s /q win_installer\files\addons\test || exit /b !errorlevel! + rmdir /s /q win_installer\files\addons\doc || exit /b !errorlevel! + :: rmdir /s /q win_installer\files\bearer || exit /b !errorlevel! + rmdir /s /q win_installer\files\generic || exit /b !errorlevel! + rmdir /s /q win_installer\files\help || exit /b !errorlevel! + rmdir /s /q win_installer\files\iconengines || exit /b !errorlevel! + rmdir /s /q win_installer\files\imageformats || exit /b !errorlevel! + rmdir /s /q win_installer\files\networkinformation || exit /b !errorlevel! + :: rmdir /s /q win_installer\files\printsupport || exit /b !errorlevel! + rmdir /s /q win_installer\files\sqldrivers || exit /b !errorlevel! + rmdir /s /q win_installer\files\tls || exit /b !errorlevel! + ren win_installer\files\translations lang || exit /b !errorlevel! + del win_installer\files\d3dcompiler_47.dll || exit /b !errorlevel! + del win_installer\files\dxcompiler.dll || exit /b !errorlevel! + del win_installer\files\dxil.dll || exit /b !errorlevel! + del win_installer\files\dmake.exe || exit /b !errorlevel! + del win_installer\files\dmake.pdb || exit /b !errorlevel! + :: del win_installer\files\libEGL.dll || exit /b !errorlevel! + :: del win_installer\files\libGLESv2.dll || exit /b !errorlevel! + del win_installer\files\opengl32sw.dll || exit /b !errorlevel! + del win_installer\files\Qt6Svg.dll || exit /b !errorlevel! + del win_installer\files\vc_redist.x64.exe || exit /b !errorlevel! + + - uses: actions/upload-artifact@v4 with: - name: deploy + name: portable path: win_installer\files diff --git a/.github/workflows/scriptcheck.yml b/.github/workflows/scriptcheck.yml index 13b87c37ff5..844b1d5c2f3 100644 --- a/.github/workflows/scriptcheck.yml +++ b/.github/workflows/scriptcheck.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: scriptcheck -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -10,11 +18,12 @@ permissions: jobs: build: - # 'ubuntu-22.04' removes Python 2.7, 3.6 and 3.6 so keep the previous LTS version - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -22,7 +31,7 @@ jobs: key: ${{ github.workflow }}-${{ runner.os }} - name: Cache Cppcheck - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: cppcheck key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }} @@ -30,32 +39,36 @@ jobs: - name: build cppcheck run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - make -j$(nproc) -s + make -j$(nproc) CXXOPTS="-Werror" strip -s ./cppcheck scriptcheck: needs: build - # 'ubuntu-22.04' removes Python 2.7, 3.5 and 3.6 so keep the previous LTS version - runs-on: ubuntu-20.04 - container: - image: python:2.7.18-buster + runs-on: ubuntu-22.04 strategy: matrix: - python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11'] + python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12', '3.13', '3.14'] + include: + - python-version: '3.14' + python-latest: true + fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false + # TODO: bailout on error - name: Restore Cppcheck - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: cppcheck key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }} - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} check-latest: true @@ -65,16 +78,7 @@ jobs: sudo apt-get update sudo apt-get install tidy libxml2-utils - - name: Install missing software on ubuntu (Python 2) - if: matrix.python-version == '2.7' - run: | - python -m pip install pip --upgrade - python -m pip install pathlib - python -m pip install pytest - python -m pip install pygments - - name: Install missing software on ubuntu (Python 3) - if: matrix.python-version != '2.7' run: | # shellcheck cannot be installed via pip # ERROR: Could not find a version that satisfies the requirement shellcheck (from versions: none) @@ -83,43 +87,44 @@ jobs: python -m pip install pip --upgrade python -m pip install natsort python -m pip install pexpect - python -m pip install pylint + python -m pip install 'pylint<4.1.0' python -m pip install unittest2 python -m pip install pytest + python -m pip install pytest-xdist python -m pip install pygments python -m pip install requests python -m pip install psutil + python -m pip install setuptools - name: run Shellcheck - if: matrix.python-version == '3.11' + if: matrix.python-latest run: | find . -name "*.sh" | xargs shellcheck --exclude SC2002,SC2013,SC2034,SC2035,SC2043,SC2046,SC2086,SC2089,SC2090,SC2129,SC2211,SC2231 - name: run pylint - if: matrix.python-version == '3.11' + if: matrix.python-latest run: | - echo "FIXME pylint is disabled for now because it fails to import files:" - echo "FIXME addons/runaddon.py:1:0: E0401: Unable to import 'cppcheckdata' (import-error)" - echo "FIXME addons/runaddon.py:1:0: E0401: Unable to import 'cppcheck' (import-error)" - # pylint --rcfile=pylintrc_travis --jobs $(nproc) addons/*.py htmlreport/cppcheck-htmlreport htmlreport/*.py tools/*.py + shopt -s globstar + pylint --jobs $(nproc) --py-version 3.7 addons/**/*.py htmlreport/cppcheck-htmlreport htmlreport/**/*.py test/**/*.py tools/**/*.py - name: check .json files - if: matrix.python-version == '3.11' + if: matrix.python-latest run: | find . -name '*.json' | xargs -n 1 python -m json.tool > /dev/null - name: Validate - if: matrix.python-version == '3.11' + if: matrix.python-latest run: | make -j$(nproc) validateCFG validatePlatforms validateRules - name: check python syntax - if: matrix.python-version != '2.7' run: | - python -m py_compile addons/*.py + shopt -s globstar + python -m py_compile addons/**/*.py python -m py_compile htmlreport/cppcheck-htmlreport - python -m py_compile htmlreport/*.py - python -m py_compile tools/*.py + python -m py_compile htmlreport/**/*.py + python -m py_compile test/**/*.py + python -m py_compile tools/**/*.py - name: compile addons run: | @@ -127,42 +132,91 @@ jobs: - name: test matchcompiler run: | - python tools/test_matchcompiler.py + python test/tools/test_matchcompiler.py + env: + PYTHONPATH: ./tools + + # TODO: run with "-n auto" when misra_test.py can be run in parallel + # we cannot specify -Werror since xml/etree/ElementTree.py in Python 3.9/3.10 contains an unclosed file + - name: test addons + if: matrix.python-version == '3.9' || matrix.python-version == '3.10' + run: | + python -m pytest --strict-markers -vv -n 1 addons/test + env: + PYTHONPATH: ./addons + # TODO: run with "-n auto" when misra_test.py can be run in parallel - name: test addons + if: matrix.python-version != '3.9' && matrix.python-version != '3.10' run: | - python -m pytest -v addons/test/test-*.py + python -m pytest -Werror --strict-markers -vv -n 1 addons/test env: PYTHONPATH: ./addons - - name: test htmlreport + - name: test htmlreport (standalone) run: | - htmlreport/test_htmlreport.py - cd htmlreport - ./check.sh + test/tools/htmlreport/test_htmlreport.py + test/tools/htmlreport/check.sh + + - name: test htmlreport (pip) + run: | + python -m venv venv + source venv/bin/activate + python -m pip install -U pip + pip install ./htmlreport/ + which cppcheck-htmlreport + PIP_PACKAGE_TEST=1 test/tools/htmlreport/test_htmlreport.py + # TODO: does not test the pip binary + test/tools/htmlreport/check.sh - name: test reduce run: | - python -m pytest -v tools/test_reduce.py + python -m pytest -Werror --strict-markers -vv test/tools/reduce_test.py env: PYTHONPATH: ./tools - name: test donate_cpu_lib - if: matrix.python-version != '2.7' run: | - python -m pytest -v tools/test_donate_cpu_lib.py + python -m pytest -Werror --strict-markers -vv test/tools/donate_cpu_lib_test.py env: PYTHONPATH: ./tools - name: test donate_cpu_server - if: matrix.python-version != '2.7' run: | - python -m pytest -v tools/test_donate_cpu_server.py + python -m pytest -Werror --strict-markers -vv test/tools/donate_cpu_server_test.py + # TODO: why is this file generated? also should be in a temporary folder if possible + rm -f test/tools/donate-cpu-server.log env: PYTHONPATH: ./tools - - name: dmake - if: matrix.python-version == '3.11' + - name: Show all ignored files + if: false # TODO: currently lists all the contents of ignored folders - we only need what actually matched + run: | + git ls-files --others --ignored --exclude-standard + + - name: Check for changed and unversioned files + run: | + # TODO: how to do this with a single command? + git status --ignored=no + git status --ignored=no | grep -q 'working tree clean' + + dmake: + strategy: + matrix: + os: [ubuntu-22.04, macos-15, windows-2025] + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: run dmake + run: | + make -j3 CXXOPTS="-Werror" run-dmake + + - name: check diff run: | - make -j$(nproc) run-dmake git diff --exit-code diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml index 8cd028f9af9..3a2fd2fffc0 100644 --- a/.github/workflows/selfcheck.yml +++ b/.github/workflows/selfcheck.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: selfcheck -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -13,15 +21,12 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 steps: - - uses: actions/checkout@v3 - - - name: Install missing software - run: | - sudo apt-get update - sudo apt-get install libboost-container-dev + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -31,13 +36,18 @@ jobs: - name: Install missing software run: | sudo apt-get update - sudo apt-get install clang-14 valgrind + sudo apt-get install clang-14 + sudo apt-get install libboost-container-dev + sudo apt-get install valgrind + sudo apt-get install -y libgl-dev # fixes missing dependency for Qt in CMake - name: Install Qt ${{ env.QT_VERSION }} - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + setup-python: 'false' + install-deps: false cache: true # TODO: cache this - perform same build as for the other self check @@ -46,53 +56,119 @@ jobs: export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" # valgrind cannot handle DWARF 5 yet so force version 4 # work around performance regression with -inline-deferral - make -j$(nproc) -s CXXFLAGS="-O2 -w -DHAVE_BOOST -gdwarf-4 -mllvm -inline-deferral" MATCHCOMPILER=yes + make -j$(nproc) CXXOPTS="-Werror -O2 -gdwarf-4" CPPOPTS="-DHAVE_BOOST -mllvm -inline-deferral" MATCHCOMPILER=yes CPPCHK_GLIBCXX_DEBUG= env: CC: clang-14 CXX: clang++-14 + # unusedFunction - start - name: CMake run: | - cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies run: | + # make sure auto-generated GUI files exist + make -C cmake.output autogen # make sure the precompiled headers exist make -C cmake.output lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx make -C cmake.output test/CMakeFiles/testrunner.dir/cmake_pch.hxx.cxx - # make sure auto-generated GUI files exist - make -C cmake.output autogen + # make sure the auto-generated GUI dependencies exist make -C cmake.output gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction) if: false # TODO: fails with preprocessorErrorDirective - see #10667 run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 + # unusedFunction - end # the following steps are duplicated from above since setting up the build node in a parallel step takes longer than the actual steps + + # unusedFunction notest - start - name: CMake (no test) run: | - cmake -S . -B cmake.output.notest -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + cmake -S . -B cmake.output.notest -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DBUILD_TRIAGE=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off - name: Generate dependencies (no test) run: | - # make sure the precompiled headers exist - make -C cmake.output.notest lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx # make sure auto-generated GUI files exist make -C cmake.output.notest autogen + # make sure the precompiled headers exist + make -C cmake.output.notest lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + # make sure the auto-generated GUI dependencies exist make -C cmake.output.notest gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / no test) run: | - ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest - end + + # unusedFunction notest nogui - start + - name: CMake (no test / no gui) + run: | + cmake -S . -B cmake.output.notest_nogui -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off + + - name: Generate dependencies (no test / no gui) + run: | + # make sure the precompiled headers exist + make -C cmake.output.notest_nogui lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + + - name: Self check (unusedFunction / no test / no gui) + run: | + supprs="--suppress=unusedFunction:lib/errorlogger.h:196 --suppress=unusedFunction:lib/importproject.cpp:1516 --suppress=unusedFunction:lib/importproject.cpp:1540" + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr $supprs env: DISABLE_VALUEFLOW: 1 UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest nogui - end + + # unusedFunction notest nocli - start + - name: CMake (no test / no cli) + run: | + cmake -S . -B cmake.output.notest_nocli -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_CLI=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DBUILD_TRIAGE=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off + + - name: Generate dependencies (no test / no cli) + run: | + # make sure auto-generated GUI files exist + make -C cmake.output.notest_nocli autogen + # make sure the precompiled headers exist + make -C cmake.output.notest_nocli lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + # make sure the auto-generated GUI dependencies exist + make -C cmake.output.notest_nocli gui-build-deps + + - name: Self check (unusedFunction / no test / no cli) + if: false # TODO: the findings are currently too intrusive + run: | + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nocli/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest nocli - end + + # unusedFunction notest nocli nogui - start + - name: CMake (no test / no cli / no gui) + run: | + cmake -S . -B cmake.output.notest_nocli_nogui -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_CLI=Off -DBUILD_GUI=Off -DENABLE_CHECK_INTERNAL=On -DCPPCHK_GLIBCXX_DEBUG=Off + + - name: Generate dependencies (no test / no cli / no gui) + run: | + # make sure the precompiled headers exist + make -C cmake.output.notest_nocli_nogui lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx + + - name: Self check (unusedFunction / no test / no cli / no gui) + if: false # TODO: the findings are currently too intrusive + run: | + ./cppcheck -q --template=selfcheck --error-exitcode=1 --library=cppcheck-lib --library=qt -D__CPPCHECK__ -D__GNUC__ --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.notest_nocli_nogui/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr + env: + DISABLE_VALUEFLOW: 1 + UNUSEDFUNCTION_ONLY: 1 + # unusedFunction notest nocli nogui - end - name: Fetch corpus run: | @@ -101,28 +177,28 @@ jobs: - name: CMake (corpus / no test) run: | - cmake -S cppcheck-2.8 -B cmake.output.corpus -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On + cmake -S cppcheck-2.8 -B cmake.output.corpus -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=Off -DBUILD_GUI=ON -DUSE_QT6=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - name: Generate dependencies (corpus) run: | - # make sure the precompiled headers exist - make -C cmake.output.notest lib/CMakeFiles/cppcheck-core.dir/cmake_pch.hxx.cxx # make sure auto-generated GUI files exist make -C cmake.output.corpus autogen + # make sure the precompiled headers exist + make -C cmake.output.corpus lib/CMakeFiles/lib_objs.dir/cmake_pch.hxx.cxx + # make sure the auto-generated GUI dependencies exist make -C cmake.output.corpus gui-build-deps - # TODO: find a way to report unmatched suppressions without need to add information checks - name: Self check (unusedFunction / corpus / no test / callgrind) run: | # TODO: fix -rp so the suppressions actually work - valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) + valgrind --tool=callgrind ./cppcheck --template=selfcheck --error-exitcode=0 --library=cppcheck-lib --library=qt -D__GNUC__ -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction,information --exception-handling -rp=. --project=cmake.output.corpus/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr 2>callgrind.log || (cat callgrind.log && false) cat callgrind.log callgrind_annotate --auto=no > callgrind.annotated.log head -50 callgrind.annotated.log env: DISABLE_VALUEFLOW: 1 - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Callgrind Output path: ./callgrind.* diff --git a/.github/workflows/tsan.yml b/.github/workflows/tsan.yml index fc3af112481..27ed6606386 100644 --- a/.github/workflows/tsan.yml +++ b/.github/workflows/tsan.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: thread sanitizer -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -13,50 +21,62 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 TSAN_OPTIONS: halt_on_error=1 # TODO: figure out why there are cache misses with PCH enabled CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} - - name: Set up Python 3.11 - uses: actions/setup-python@v4 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.14' check-latest: true - name: Install missing software on ubuntu run: | sudo apt-get update - sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev + sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev libxml2-utils + sudo apt-get install -y libcups2-dev # required for Qt6PrintSupport in CMake since Qt 6.7.3 - name: Install clang run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 16 + sudo ./llvm.sh 21 - name: Install Qt ${{ env.QT_VERSION }} - if: false - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + setup-python: 'false' cache: true + - name: Install missing Python packages + run: | + python3 -m pip install pip --upgrade + python3 -m pip install pytest + python3 -m pip install pytest-timeout + python3 -m pip install pytest-xdist + python3 -m pip install psutil + - name: CMake run: | - cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=Off -DWITH_QCHART=Off -DUSE_MATCHCOMPILER=Verify -DANALYZE_THREAD=On -DUSE_THREADS=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DANALYZE_THREAD=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=Off -DDISABLE_DMAKE=On -DFILESDIR= -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache env: - CC: clang-16 - CXX: clang++-16 + CC: clang-21 + CXX: clang++-21 - name: Build cppcheck run: | @@ -66,9 +86,51 @@ jobs: run: | cmake --build cmake.output --target testrunner -- -j $(nproc) + - name: Build GUI tests + run: | + cmake --build cmake.output --target gui-tests -- -j $(nproc) + - name: Run tests run: ./cmake.output/bin/testrunner + - name: Run cfg tests + run: | + cmake --build cmake.output --target checkcfg -- -j $(nproc) + + - name: Run CTest + if: false # TODO: test-filelist fails with data race in pthread_cond_destroy + run: | + ctest --test-dir cmake.output --output-on-failure -j$(nproc) + + - name: Run test/cli + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_EXECUTOR: thread + + - name: Run test/cli (-j2) + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_J: 2 + + - name: Run test/cli (--clang) + if: false + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_CLANG: clang + + - name: Run test/cli (--cppcheck-build-dir) + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_BUILDDIR: injected + - name: Generate dependencies if: false run: | @@ -81,10 +143,18 @@ jobs: - name: Self check if: false run: | - selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=0 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=file-total -D__GNUC__ --error-exitcode=0 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,information --exception-handling --debug-warnings --check-level=exhaustive" + selfcheck_options="$selfcheck_options --executor=thread" + cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2" + gui_options="-DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt" + gui_options="$gui_options --suppress=autoNoType:*/moc_*.cpp --suppress=symbolDatabaseWarning:*/moc_*.cpp" ec=0 - ./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options externals || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json frontend || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json -Ifrontend cli || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json --enable=internal lib || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options $gui_options --addon=naming.json --suppress=constVariablePointer:*/moc_*.cpp -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli -Ifrontend test/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options $gui_options -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1 exit $ec diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml index 1de89f66ff5..64eb02a4b25 100644 --- a/.github/workflows/ubsan.yml +++ b/.github/workflows/ubsan.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: undefined behaviour sanitizers -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -13,49 +21,62 @@ jobs: runs-on: ubuntu-22.04 env: - QT_VERSION: 5.15.2 + QT_VERSION: 6.10.0 UBSAN_OPTIONS: print_stacktrace=1:halt_on_error=1:report_error_type=1 # TODO: figure out why there are cache misses with PCH enabled CCACHE_SLOPPINESS: pch_defines,time_macros steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }} - - name: Set up Python 3.11 - uses: actions/setup-python@v4 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.14' check-latest: true - name: Install missing software on ubuntu run: | sudo apt-get update - sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev + sudo apt-get install -y cmake make libpcre3-dev libboost-container-dev libxml2-utils + sudo apt-get install -y libcups2-dev # required for Qt6PrintSupport in CMake since Qt 6.7.3 - name: Install clang run: | + sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 16 + sudo ./llvm.sh 21 - name: Install Qt ${{ env.QT_VERSION }} - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: version: ${{ env.QT_VERSION }} modules: 'qtcharts' + setup-python: 'false' cache: true + - name: Install missing Python packages + run: | + python3 -m pip install pip --upgrade + python3 -m pip install pytest + python3 -m pip install pytest-timeout + python3 -m pip install pytest-xdist + python3 -m pip install psutil + - name: CMake run: | - cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DWITH_QCHART=ON -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + cmake -S . -B cmake.output -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=On -DBUILD_TRIAGE=On -DUSE_MATCHCOMPILER=Verify -DANALYZE_UNDEFINED=On -DENABLE_CHECK_INTERNAL=On -DUSE_BOOST=On -DCPPCHK_GLIBCXX_DEBUG=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DDISABLE_DMAKE=On -DFILESDIR= -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache env: - CC: clang-16 - CXX: clang++-16 + CC: clang-21 + CXX: clang++-21 - name: Build cppcheck run: | @@ -65,9 +86,48 @@ jobs: run: | cmake --build cmake.output --target testrunner -- -j $(nproc) + - name: Build GUI tests + run: | + cmake --build cmake.output --target gui-tests -- -j $(nproc) + - name: Run tests run: ./cmake.output/bin/testrunner + - name: Run cfg tests + run: | + cmake --build cmake.output --target checkcfg -- -j $(nproc) + + - name: Run CTest + run: | + ctest --test-dir cmake.output --output-on-failure -j$(nproc) + + - name: Run test/cli + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + + - name: Run test/cli (-j2) + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_J: 2 + + - name: Run test/cli (--clang) + if: false + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_CLANG: clang + + - name: Run test/cli (--cppcheck-build-dir) + run: | + pwd=$(pwd) + TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv -n auto test/cli + env: + TEST_CPPCHECK_INJECT_BUILDDIR: injected + - name: Generate dependencies run: | # make sure auto-generated GUI files exist @@ -77,10 +137,17 @@ jobs: # TODO: only fail the step on sanitizer issues - since we use processes it will only fail the underlying process which will result in an cppcheckError - name: Self check run: | - selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5 -D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2/ --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings" + selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=file-total -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,information --exception-handling --debug-warnings --check-level=exhaustive" + cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2" + gui_options="-DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=69 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt" + gui_options="$gui_options --suppress=autoNoType:*/moc_*.cpp --suppress=symbolDatabaseWarning:*/moc_*.cpp" ec=0 - ./cmake.output/bin/cppcheck $selfcheck_options --addon=naming.json cli lib || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -DQT_VERSION=0x050000 -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -Icli test/*.cpp tools/*.cpp || ec=1 - ./cmake.output/bin/cppcheck $selfcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options externals || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json frontend || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json -Ifrontend cli || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json --enable=internal lib || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options $gui_options --addon=naming.json --suppress=constVariablePointer:*/moc_*.cpp -Icmake.output/gui -Ifrontend -Igui gui/*.cpp cmake.output/gui || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli -Ifrontend test/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli tools/dmake/*.cpp || ec=1 + ./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options $gui_options -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1 exit $ec diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml index 1753e6f0acd..9a6026aa25b 100644 --- a/.github/workflows/valgrind.yml +++ b/.github/workflows/valgrind.yml @@ -2,7 +2,15 @@ # Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners name: valgrind -on: [push, pull_request] +on: + push: + branches: + - 'main' + - 'releases/**' + - '2.*' + tags: + - '2.*' + pull_request: permissions: contents: read @@ -13,7 +21,9 @@ jobs: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + persist-credentials: false - name: ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -31,12 +41,12 @@ jobs: - name: Build cppcheck run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - CXXFLAGS="-O1 -g -DHAVE_BOOST" make -j$(nproc) HAVE_RULES=yes MATCHCOMPILER=yes + make -j$(nproc) CXXOPTS="-Werror -O1 -g" CPPOPTS="-DHAVE_BOOST" HAVE_RULES=yes MATCHCOMPILER=yes CPPCHK_GLIBCXX_DEBUG= - name: Build test run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - CXXFLAGS="-O1 -g -DHAVE_BOOST" make -j$(nproc) testrunner HAVE_RULES=yes MATCHCOMPILER=yes + make -j$(nproc) CXXOPTS="-Werror -O1 -g" CPPOPTS="-DHAVE_BOOST" HAVE_RULES=yes MATCHCOMPILER=yes CPPCHK_GLIBCXX_DEBUG= testrunner - name: Run valgrind run: | @@ -44,10 +54,11 @@ jobs: valgrind --error-limit=yes --leak-check=full --num-callers=50 --show-reachable=yes --track-origins=yes --suppressions=valgrind/testrunner.supp --gen-suppressions=all --log-fd=9 --error-exitcode=42 ./testrunner TestGarbage TestOther TestSimplifyTemplate 9>memcheck.log || ec=1 cat memcheck.log exit $ec - env: - DEBUGINFOD_URLS: https://debuginfod.ubuntu.com + # TODO: debuginfod.ubuntu.com is currently not responding to any requests causing it to run into a 40(!) minute timeout + #env: + # DEBUGINFOD_URLS: https://debuginfod.ubuntu.com - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: success() || failure() with: name: Logs diff --git a/.gitignore b/.gitignore index af691695934..434203fe2a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.bak *.gcno +*.gch *.o *.pyc /cppcheck @@ -13,9 +14,9 @@ tags /testrunner /testrunner.exe tools/daca2*.html -tools/dmake tools/errmsg tools/extracttests +.DS_Store # dump files generated by Cppcheck *.*.dump @@ -51,42 +52,13 @@ ipch/ *.pbxuser build/ -# GUI build folders -/gui/debug/ -/gui/release/ -/gui/temp/ -/triage/temp - # Other (generated) GUI files -/gui/*.qm -/gui/cppcheck-gui -/gui/cppcheck-gui.exe -/gui/gui.sln -/gui/gui.vcproj /gui/help/online-help.qch /gui/help/online-help.qhc -/gui/Makefile -/gui/Makefile.debug -/gui/Makefile.release -/gui/qrc_gui.cpp -/gui/test/Makefile -/gui/test/*/Makefile -/gui/test/*/*/Makefile -/gui/test/benchmark/simple/benchmark-simple -/gui/test/cppchecklibrarydata/qrc_resources.cpp -/gui/test/cppchecklibrarydata/test-cppchecklibrarydata -/gui/test/filelist/test-filelist -/gui/test/projectfile/test-projectfile -/gui/test/translationhandler/test-translationhandler -/gui/test/xmlreportv2/test-xmlreportv2 # Doxygen output folder doxyoutput/ -# qmake generated -htmlreport/.tox/ -htmlreport/MANIFEST - # Backup files and stuff from patches *.rej *~ @@ -121,12 +93,38 @@ stage /.run # clang tooling temporary files -.clangd/ -.cache/ -compile_commands.json - -# qmake -.qmake.stash +/.clangd/ +/.cache/ +/compile_commands.json #vs code /.vscode + +# fuzzing output +/oss-fuzz/corpus +/oss-fuzz/corpus_ +/oss-fuzz/samples + +# Python +/.venv/ +/venv/ +**/*.egg-info/ + +# cppcheck-htmlreport auto files +/htmlreport/cppcheck_htmlreport/run.py + +# GDB configuration +.gdbinit + +# pyinstaller output +/addons/dist +/addons/misra.spec +/htmlreport/cppcheck-htmlreport.spec +/htmlreport/dist + +# ccache folder in CI +/.ccache + +# PCRE Windows files +/externals/pcre.h +/externals/pcre64.lib diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000000..0ca3480c06f --- /dev/null +++ b/.pylintrc @@ -0,0 +1,65 @@ +[MESSAGES CONTROL] +disable= + # W start + redefined-builtin, + broad-exception-caught, + fixme, + bare-except, + redefined-outer-name, + attribute-defined-outside-init, + unspecified-encoding, + global-statement, + protected-access, + broad-exception-raised, + subprocess-popen-preexec-fn, + logging-not-lazy, + unknown-option-value, + unused-wildcard-import, + wildcard-import, + unused-argument, + pointless-string-statement, + arguments-renamed, + duplicate-string-formatting-argument, + # C start + consider-using-f-string, + invalid-name, + line-too-long, + missing-module-docstring, + missing-function-docstring, + import-outside-toplevel, + missing-class-docstring, + superfluous-parens, + too-many-lines, + trailing-newlines, + missing-final-newline, + use-implicit-booleaness-not-len, + wrong-import-order, + use-implicit-booleaness-not-comparison, + consider-using-enumerate, + unnecessary-lambda-assignment, + consider-using-dict-items, + consider-iterating-dictionary, + # R start + duplicate-code, + consider-using-with, + too-many-statements, + too-many-branches, + too-many-locals, + too-many-arguments, + too-few-public-methods, + too-many-return-statements, + consider-using-in, + too-many-nested-blocks, + too-many-public-methods, + chained-comparison, + too-many-instance-attributes, + too-many-boolean-expressions, + use-a-generator, + too-many-positional-arguments +[REPORTS] +reports=no +[TYPECHECK] +# See https://stackoverflow.com/questions/10300082/how-to-prevent-python-pylint-complaining-about-socket-class-sendall-method +ignored-classes=SQLObject,_socketobject +[MASTER] +init-hook='import sys; sys.path.append("./addons")' diff --git a/.selfcheck_suppressions b/.selfcheck_suppressions index 1f9a8d9aa0d..7728225cd44 100644 --- a/.selfcheck_suppressions +++ b/.selfcheck_suppressions @@ -1,26 +1,44 @@ missingIncludeSystem -shadowFunction -bitwiseOnBoolean - -# temporary suppressions - fix the warnings! -simplifyUsing:lib/valueptr.h -varid0:gui/projectfile.cpp -templateInstantiation +# should not be reported - see #13387 +checkersReport +# false positive - see #14308 +nullPointerRedundantCheck:externals/simplecpp/simplecpp.cpp:3246 # warnings in Qt generated code we cannot fix -symbolDatabaseWarning:gui/temp/moc_*.cpp -simplifyUsing:gui/temp/moc_*.cpp -funcArgNamesDifferent:gui/temp/moc_*.cpp -symbolDatabaseWarning:tools/triage/temp/moc_*.cpp -naming-varname:gui/temp/ui_*.h -naming-varname:cmake.output/gui/ui_*.h -functionStatic:gui/temp/ui_fileview.h -functionStatic:cmake.output/gui/ui_fileview.h +funcArgNamesDifferent:*/moc_checkthread.cpp +funcArgNamesDifferent:*/moc_codeeditstylecontrols.cpp +funcArgNamesDifferent:*/moc_resultstree.cpp +funcArgNamesDifferent:*/moc_resultsview.cpp +funcArgNamesDifferent:*/moc_threadhandler.cpp +funcArgNamesDifferent:*/moc_threadresult.cpp +naming-varname:*/gui/ui_*.h +functionStatic:*/ui_fileview.h # --debug-warnings suppressions valueFlowBailout valueFlowBailoutIncompleteVar -autoNoType -bailoutUninitVar +valueFlowMaxIterations:gui/resultstree.cpp +autoNoType:externals/simplecpp/simplecpp.cpp +autoNoType:cli/*.cpp +autoNoType:lib/*.cpp +autoNoType:lib/library.h +autoNoType:gui/*.cpp +autoNoType:test/*.cpp +autoNoType:tools/triage/mainwindow.cpp +# ticket 11631 +templateInstantiation:test/testutils.cpp + +naming-varname:externals/simplecpp/simplecpp.h +naming-privateMemberVariable:externals/simplecpp/simplecpp.h -*:externals/*/* +# TODO: these warnings need to be addressed upstream +uninitMemberVar:externals/tinyxml2/tinyxml2.h +noExplicitConstructor:externals/tinyxml2/tinyxml2.h +missingOverride:externals/tinyxml2/tinyxml2.h +invalidPrintfArgType_sint:externals/tinyxml2/tinyxml2.h +naming-privateMemberVariable:externals/tinyxml2/tinyxml2.h +functionStatic:externals/tinyxml2/tinyxml2.cpp +funcArgNamesDifferent:externals/tinyxml2/tinyxml2.cpp +nullPointerRedundantCheck:externals/tinyxml2/tinyxml2.cpp +useStlAlgorithm:externals/simplecpp/simplecpp.cpp +missingMemberCopy:externals/simplecpp/simplecpp.h diff --git a/.selfcheck_unused_suppressions b/.selfcheck_unused_suppressions index f66bcc905c0..5da7c225dfa 100644 --- a/.selfcheck_unused_suppressions +++ b/.selfcheck_unused_suppressions @@ -1,13 +1,8 @@ +# should not be reported - see #13387 +checkersReport + # we are not using all methods of their interfaces -unusedFunction:externals/tinyxml2/tinyxml2.cpp -unusedFunction:externals/simplecpp/simplecpp.cpp +unusedFunction:externals/*/* -# TODO: fix these -# false positive - # 10660 -unusedFunction:gui/mainwindow.cpp -unusedFunction:gui/resultstree.cpp -unusedFunction:gui/codeeditor.cpp -# usage is disabled -unusedFunction:lib/symboldatabase.cpp -# false positive - #10661 -unusedFunction:oss-fuzz/main.cpp \ No newline at end of file +# Q_OBJECT functions which are not called in our code +unusedFunction:cmake.output.notest/gui/cppcheck-gui_autogen/*/moc_aboutdialog.cpp diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 46b471c0aff..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,43 +0,0 @@ -language: cpp -dist: xenial - -compiler: - - gcc - - clang - -env: - global: - - ORIGINAL_CXXFLAGS="-pedantic -Wall -Wextra -Wcast-qual -Wno-deprecated-declarations -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-shadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare -Wno-multichar -D_GLIBCXX_DEBUG -g" -# unfortunately we need this to stay within 50min timelimit given by travis. - - CXXFLAGS="${ORIGINAL_CXXFLAGS} -O2 -march=native -Wstrict-aliasing=2 -Werror=strict-aliasing" - - CPPCHECK=${TRAVIS_BUILD_DIR}/cppcheck - matrix: - - CXXFLAGS="${CXXFLAGS} -DCHECK_INTERNAL" - - CXXFLAGS="${CXXFLAGS} -DCHECK_INTERNAL" MAKEFLAGS="HAVE_RULES=yes" MATCHCOMPILER=yes VERIFY=1 - -before_install: -# install needed deps - - travis_retry sudo apt-get update -qq - - travis_retry sudo apt-get install -qq libxml2-utils libpcre3 gdb unzip wx-common xmlstarlet liblua5.3-dev libcurl3 libcairo2-dev libsigc++-2.0-dev tidy libopencv-dev - -matrix: -# do notify immediately about it when a job of a build fails. - fast_finish: true -# defined extra jobs that run besides what is configured in the build matrix - include: - -# check a lot of stuff that only needs to be checked in a single configuration - - name: "misc" - compiler: clang - script: - - make -j$(nproc) -s -# check if DESTDIR works TODO: actually execute this - - mkdir install_test - - echo $CXXFLAGS - - make -s DESTDIR=install_test FILESDIR=/usr/share/cppcheck install -# rm everything - - git clean -dfx -# check what happens if we want to install it to some other dir, - - echo $CXXFLAGS - - make -s MATCHCOMPILER=yes FILESDIR=/usr/share/cppcheck -j$(nproc) - - sudo make MATCHCOMPILER=yes FILESDIR=/usr/share/cppcheck install diff --git a/.uncrustify.cfg b/.uncrustify.cfg index 074811b05b7..81722ff7249 100644 --- a/.uncrustify.cfg +++ b/.uncrustify.cfg @@ -1,13 +1,4 @@ -# Uncrustify-0.72.0_f - -# -# General options -# - -# The type of line endings. -# -# Default: auto -newlines = auto # lf/crlf/cr/auto +# Uncrustify-0.80.1_f # The original size of tabs in the input. # @@ -19,274 +10,36 @@ input_tab_size = 4 # unsigned number # Default: 8 output_tab_size = 4 # unsigned number -# The ASCII value of the string escape char, usually 92 (\) or (Pawn) 94 (^). -# -# Default: 92 -string_escape_char = 92 # unsigned number - -# Alternate string escape char (usually only used for Pawn). -# Only works right before the quote char. -string_escape_char2 = 0 # unsigned number - -# Replace tab characters found in string literals with the escape sequence \t -# instead. -string_replace_tab_chars = false # true/false - -# Allow interpreting '>=' and '>>=' as part of a template in code like -# 'void f(list>=val);'. If true, 'assert(x<0 && y>=3)' will be broken. -# Improvements to template detection may make this option obsolete. -tok_split_gte = false # true/false - -# Disable formatting of NL_CONT ('\\n') ended lines (e.g. multiline macros) -disable_processing_nl_cont = false # true/false - -# Specify the marker used in comments to disable processing of part of the -# file. -# The comment should be used alone in one line. -# -# Default: *INDENT-OFF* -disable_processing_cmt = " *INDENT-OFF*" # string - -# Specify the marker used in comments to (re)enable processing in a file. -# The comment should be used alone in one line. -# -# Default: *INDENT-ON* -enable_processing_cmt = " *INDENT-ON*" # string - -# Enable parsing of digraphs. -enable_digraphs = false # true/false - -# Add or remove the UTF-8 BOM (recommend 'remove'). -utf8_bom = ignore # ignore/add/remove/force - -# If the file contains bytes with values between 128 and 255, but is not -# UTF-8, then output as UTF-8. -utf8_byte = false # true/false - -# Force the output encoding to UTF-8. -utf8_force = false # true/false - -# Add or remove space between 'do' and '{'. -sp_do_brace_open = ignore # ignore/add/remove/force - -# Add or remove space between '}' and 'while'. -sp_brace_close_while = ignore # ignore/add/remove/force - # Add or remove space between 'while' and '('. sp_while_paren_open = add # ignore/add/remove/force -# -# Spacing options -# - -# Add or remove space around non-assignment symbolic operators ('+', '/', '%', -# '<<', and so forth). -sp_arith = ignore # ignore/add/remove/force - -# Add or remove space around arithmetic operators '+' and '-'. -# -# Overrides sp_arith. -sp_arith_additive = ignore # ignore/add/remove/force - -# Add or remove space around assignment operator '=', '+=', etc. -sp_assign = ignore # ignore/add/remove/force - -# Add or remove space around '=' in C++11 lambda capture specifications. -# -# Overrides sp_assign. -sp_cpp_lambda_assign = ignore # ignore/add/remove/force - -# Add or remove space after the capture specification of a C++11 lambda when -# an argument list is present, as in '[] (int x){ ... }'. -sp_cpp_lambda_square_paren = ignore # ignore/add/remove/force - -# Add or remove space after the capture specification of a C++11 lambda with -# no argument list is present, as in '[] { ... }'. -sp_cpp_lambda_square_brace = ignore # ignore/add/remove/force - -# Add or remove space after the argument list of a C++11 lambda, as in -# '[](int x) { ... }'. -sp_cpp_lambda_paren_brace = ignore # ignore/add/remove/force - -# Add or remove space between a lambda body and its call operator of an -# immediately invoked lambda, as in '[]( ... ){ ... } ( ... )'. -sp_cpp_lambda_fparen = ignore # ignore/add/remove/force - -# Add or remove space around assignment operator '=' in a prototype. -# -# If set to ignore, use sp_assign. -sp_assign_default = ignore # ignore/add/remove/force - -# Add or remove space before assignment operator '=', '+=', etc. -# -# Overrides sp_assign. -sp_before_assign = ignore # ignore/add/remove/force - -# Add or remove space after assignment operator '=', '+=', etc. -# -# Overrides sp_assign. -sp_after_assign = ignore # ignore/add/remove/force - -# Add or remove space in 'NS_ENUM ('. -sp_enum_paren = ignore # ignore/add/remove/force - -# Add or remove space around assignment '=' in enum. -sp_enum_assign = ignore # ignore/add/remove/force - -# Add or remove space before assignment '=' in enum. -# -# Overrides sp_enum_assign. -sp_enum_before_assign = ignore # ignore/add/remove/force - -# Add or remove space after assignment '=' in enum. -# -# Overrides sp_enum_assign. -sp_enum_after_assign = ignore # ignore/add/remove/force - -# Add or remove space around assignment ':' in enum. -sp_enum_colon = ignore # ignore/add/remove/force - -# Add or remove space around preprocessor '##' concatenation operator. -# -# Default: add -sp_pp_concat = add # ignore/add/remove/force - -# Add or remove space after preprocessor '#' stringify operator. -# Also affects the '#@' charizing operator. -sp_pp_stringify = ignore # ignore/add/remove/force - -# Add or remove space before preprocessor '#' stringify operator -# as in '#define x(y) L#y'. -sp_before_pp_stringify = ignore # ignore/add/remove/force - # Add or remove space around boolean operators '&&' and '||'. sp_bool = force # ignore/add/remove/force -# Add or remove space around compare operator '<', '>', '==', etc. -sp_compare = ignore # ignore/add/remove/force - # Add or remove space inside '(' and ')'. sp_inside_paren = remove # ignore/add/remove/force # Add or remove space between nested parentheses, i.e. '((' vs. ') )'. sp_paren_paren = remove # ignore/add/remove/force -# Add or remove space between back-to-back parentheses, i.e. ')(' vs. ') ('. -sp_cparen_oparen = ignore # ignore/add/remove/force - -# Whether to balance spaces inside nested parentheses. -sp_balance_nested_parens = false # true/false - # Add or remove space between ')' and '{'. sp_paren_brace = force # ignore/add/remove/force -# Add or remove space between nested braces, i.e. '{{' vs '{ {'. -sp_brace_brace = ignore # ignore/add/remove/force - -# Add or remove space before pointer star '*'. -sp_before_ptr_star = ignore # ignore/add/remove/force - -# Add or remove space before pointer star '*' that isn't followed by a -# variable name. If set to ignore, sp_before_ptr_star is used instead. -sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force - # Add or remove space between pointer stars '*'. sp_between_ptr_star = remove # ignore/add/remove/force -# Add or remove space after pointer star '*', if followed by a word. -# -# Overrides sp_type_func. -sp_after_ptr_star = ignore # ignore/add/remove/force - -# Add or remove space after pointer caret '^', if followed by a word. -sp_after_ptr_block_caret = ignore # ignore/add/remove/force - -# Add or remove space after pointer star '*', if followed by a qualifier. -sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force - -# Add or remove space after a pointer star '*', if followed by a function -# prototype or function definition. -# -# Overrides sp_after_ptr_star and sp_type_func. -sp_after_ptr_star_func = ignore # ignore/add/remove/force - -# Add or remove space after a pointer star '*', if followed by an open -# parenthesis, as in 'void* (*)(). -sp_ptr_star_paren = ignore # ignore/add/remove/force - -# Add or remove space before a pointer star '*', if followed by a function -# prototype or function definition. -sp_before_ptr_star_func = ignore # ignore/add/remove/force - -# Add or remove space before a reference sign '&'. -sp_before_byref = ignore # ignore/add/remove/force - -# Add or remove space before a reference sign '&' that isn't followed by a -# variable name. If set to ignore, sp_before_byref is used instead. -sp_before_unnamed_byref = ignore # ignore/add/remove/force - -# Add or remove space after reference sign '&', if followed by a word. -# -# Overrides sp_type_func. -sp_after_byref = ignore # ignore/add/remove/force - -# Add or remove space after a reference sign '&', if followed by a function -# prototype or function definition. -# -# Overrides sp_after_byref and sp_type_func. -sp_after_byref_func = ignore # ignore/add/remove/force - -# Add or remove space before a reference sign '&', if followed by a function -# prototype or function definition. -sp_before_byref_func = ignore # ignore/add/remove/force - -# Add or remove space between type and word. In cases where total removal of -# whitespace would be a syntax error, a value of 'remove' is treated the same -# as 'force'. -# -# This also affects some other instances of space following a type that are -# not covered by other options; for example, between the return type and -# parenthesis of a function type template argument, between the type and -# parenthesis of an array parameter, or between 'decltype(...)' and the -# following word. -# -# Default: force -sp_after_type = force # ignore/add/remove/force - -# Add or remove space between 'decltype(...)' and word. -# -# Overrides sp_after_type. -sp_after_decltype = ignore # ignore/add/remove/force - -# (D) Add or remove space before the parenthesis in the D constructs -# 'template Foo(' and 'class Foo('. -sp_before_template_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'template' and '<'. -# If set to ignore, sp_before_angle is used. -sp_template_angle = ignore # ignore/add/remove/force - # Add or remove space before '<'. sp_before_angle = remove # ignore/add/remove/force # Add or remove space inside '<' and '>'. sp_inside_angle = remove # ignore/add/remove/force -# Add or remove space inside '<>'. -sp_inside_angle_empty = ignore # ignore/add/remove/force - -# Add or remove space between '>' and ':'. -sp_angle_colon = ignore # ignore/add/remove/force - # Add or remove space after '>'. sp_after_angle = add # ignore/add/remove/force # Add or remove space between '>' and '(' as found in 'new List(foo);'. sp_angle_paren = remove # ignore/add/remove/force -# Add or remove space between '>' and '()' as found in 'new List();'. -sp_angle_paren_empty = ignore # ignore/add/remove/force - # Add or remove space between '>' and a word as in 'List m;' or # 'template static ...'. sp_angle_word = add # ignore/add/remove/force @@ -307,67 +60,19 @@ sp_before_sparen = force # ignore/add/remove/force # Add or remove space inside '(' and ')' of control statements. sp_inside_sparen = remove # ignore/add/remove/force -# Add or remove space after '(' of control statements. -# -# Overrides sp_inside_sparen. -sp_inside_sparen_open = ignore # ignore/add/remove/force - -# Add or remove space before ')' of control statements. -# -# Overrides sp_inside_sparen. -sp_inside_sparen_close = ignore # ignore/add/remove/force - # Add or remove space after ')' of control statements. sp_after_sparen = force # ignore/add/remove/force # Add or remove space between ')' and '{' of of control statements. sp_sparen_brace = force # ignore/add/remove/force -# (D) Add or remove space between 'invariant' and '('. -sp_invariant_paren = ignore # ignore/add/remove/force - -# (D) Add or remove space after the ')' in 'invariant (C) c'. -sp_after_invariant_paren = ignore # ignore/add/remove/force - -# Add or remove space before empty statement ';' on 'if', 'for' and 'while'. -sp_special_semi = ignore # ignore/add/remove/force - -# Add or remove space before ';'. -# -# Default: remove -sp_before_semi = remove # ignore/add/remove/force - # Add or remove space before ';' in non-empty 'for' statements. sp_before_semi_for = remove # ignore/add/remove/force -# Add or remove space before a semicolon of an empty part of a for statement. -sp_before_semi_for_empty = ignore # ignore/add/remove/force - -# Add or remove space after ';', except when followed by a comment. -# -# Default: add -sp_after_semi = add # ignore/add/remove/force - -# Add or remove space after ';' in non-empty 'for' statements. -# -# Default: force -sp_after_semi_for = force # ignore/add/remove/force - # Add or remove space after the final semicolon of an empty part of a for # statement, as in 'for ( ; ; )'. sp_after_semi_for_empty = remove # ignore/add/remove/force -# Add or remove space before '[' (except '[]'). -sp_before_square = ignore # ignore/add/remove/force - -# Add or remove space before '[' for a variable definition. -# -# Default: remove -sp_before_vardef_square = remove # ignore/add/remove/force - -# Add or remove space before '[' for asm block. -sp_before_square_asm_block = ignore # ignore/add/remove/force - # Add or remove space before '[]'. sp_before_squares = remove # ignore/add/remove/force @@ -377,2752 +82,89 @@ sp_cpp_before_struct_binding = ignore # ignore/add/remove/force # Add or remove space inside a non-empty '[' and ']'. sp_inside_square = remove # ignore/add/remove/force -# Add or remove space inside '[]'. -sp_inside_square_empty = ignore # ignore/add/remove/force - -# (OC) Add or remove space inside a non-empty Objective-C boxed array '@[' and -# ']'. If set to ignore, sp_inside_square is used. -sp_inside_square_oc_array = ignore # ignore/add/remove/force - -# Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. -sp_after_comma = ignore # ignore/add/remove/force - -# Add or remove space before ','. -# -# Default: remove -sp_before_comma = remove # ignore/add/remove/force - -# (C#) Add or remove space between ',' and ']' in multidimensional array type -# like 'int[,,]'. -sp_after_mdatype_commas = ignore # ignore/add/remove/force - -# (C#) Add or remove space between '[' and ',' in multidimensional array type -# like 'int[,,]'. -sp_before_mdatype_commas = ignore # ignore/add/remove/force - -# (C#) Add or remove space between ',' in multidimensional array type -# like 'int[,,]'. -sp_between_mdatype_commas = ignore # ignore/add/remove/force - -# Add or remove space between an open parenthesis and comma, -# i.e. '(,' vs. '( ,'. -# -# Default: force -sp_paren_comma = force # ignore/add/remove/force - -# Add or remove space before the variadic '...' when preceded by a -# non-punctuator. -sp_before_ellipsis = ignore # ignore/add/remove/force - -# Add or remove space between a type and '...'. -sp_type_ellipsis = ignore # ignore/add/remove/force - -# (D) Add or remove space between a type and '?'. -sp_type_question = ignore # ignore/add/remove/force - -# Add or remove space between ')' and '...'. -sp_paren_ellipsis = ignore # ignore/add/remove/force - -# Add or remove space between ')' and a qualifier such as 'const'. -sp_paren_qualifier = ignore # ignore/add/remove/force - -# Add or remove space between ')' and 'noexcept'. -sp_paren_noexcept = ignore # ignore/add/remove/force - # Add or remove space after class ':'. sp_after_class_colon = force # ignore/add/remove/force # Add or remove space before class ':'. sp_before_class_colon = force # ignore/add/remove/force -# Add or remove space after class constructor ':'. -sp_after_constr_colon = ignore # ignore/add/remove/force - -# Add or remove space before class constructor ':'. -sp_before_constr_colon = ignore # ignore/add/remove/force - -# Add or remove space before case ':'. -# -# Default: remove -sp_before_case_colon = remove # ignore/add/remove/force - -# Add or remove space between 'operator' and operator sign. -sp_after_operator = ignore # ignore/add/remove/force - -# Add or remove space between the operator symbol and the open parenthesis, as -# in 'operator ++('. -sp_after_operator_sym = ignore # ignore/add/remove/force - -# Overrides sp_after_operator_sym when the operator has no arguments, as in -# 'operator *()'. -sp_after_operator_sym_empty = ignore # ignore/add/remove/force - -# Add or remove space after C/D cast, i.e. 'cast(int)a' vs. 'cast(int) a' or -# '(int)a' vs. '(int) a'. -sp_after_cast = ignore # ignore/add/remove/force - -# Add or remove spaces inside cast parentheses. -sp_inside_paren_cast = ignore # ignore/add/remove/force - -# Add or remove space between the type and open parenthesis in a C++ cast, -# i.e. 'int(exp)' vs. 'int (exp)'. -sp_cpp_cast_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'sizeof' and '('. -sp_sizeof_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'sizeof' and '...'. -sp_sizeof_ellipsis = ignore # ignore/add/remove/force - -# Add or remove space between 'sizeof...' and '('. -sp_sizeof_ellipsis_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'decltype' and '('. -sp_decltype_paren = ignore # ignore/add/remove/force - -# (Pawn) Add or remove space after the tag keyword. -sp_after_tag = ignore # ignore/add/remove/force - -# Add or remove space inside enum '{' and '}'. -sp_inside_braces_enum = ignore # ignore/add/remove/force - -# Add or remove space inside struct/union '{' and '}'. -sp_inside_braces_struct = ignore # ignore/add/remove/force - -# (OC) Add or remove space inside Objective-C boxed dictionary '{' and '}' -sp_inside_braces_oc_dict = ignore # ignore/add/remove/force - -# Add or remove space after open brace in an unnamed temporary -# direct-list-initialization. -sp_after_type_brace_init_lst_open = ignore # ignore/add/remove/force - -# Add or remove space before close brace in an unnamed temporary -# direct-list-initialization. -sp_before_type_brace_init_lst_close = ignore # ignore/add/remove/force - -# Add or remove space inside an unnamed temporary direct-list-initialization. -sp_inside_type_brace_init_lst = ignore # ignore/add/remove/force - -# Add or remove space inside '{' and '}'. -sp_inside_braces = ignore # ignore/add/remove/force - # Add or remove space inside '{}'. sp_inside_braces_empty = remove # ignore/add/remove/force -# Add or remove space around trailing return operator '->'. -sp_trailing_return = ignore # ignore/add/remove/force - -# Add or remove space between return type and function name. A minimum of 1 -# is forced except for pointer return types. -sp_type_func = ignore # ignore/add/remove/force - -# Add or remove space between type and open brace of an unnamed temporary -# direct-list-initialization. -sp_type_brace_init_lst = ignore # ignore/add/remove/force - -# Add or remove space between function name and '(' on function declaration. -sp_func_proto_paren = ignore # ignore/add/remove/force - -# Add or remove space between function name and '()' on function declaration -# without parameters. -sp_func_proto_paren_empty = ignore # ignore/add/remove/force - -# Add or remove space between function name and '(' with a typedef specifier. -sp_func_type_paren = ignore # ignore/add/remove/force - -# Add or remove space between alias name and '(' of a non-pointer function type typedef. -sp_func_def_paren = ignore # ignore/add/remove/force - -# Add or remove space between function name and '()' on function definition -# without parameters. -sp_func_def_paren_empty = ignore # ignore/add/remove/force - -# Add or remove space inside empty function '()'. -# Overrides sp_after_angle unless use_sp_after_angle_always is set to true. -sp_inside_fparens = ignore # ignore/add/remove/force - -# Add or remove space inside function '(' and ')'. -sp_inside_fparen = ignore # ignore/add/remove/force - -# Add or remove space inside the first parentheses in a function type, as in -# 'void (*x)(...)'. -sp_inside_tparen = ignore # ignore/add/remove/force - -# Add or remove space between the ')' and '(' in a function type, as in -# 'void (*x)(...)'. -sp_after_tparen_close = ignore # ignore/add/remove/force - -# Add or remove space between ']' and '(' when part of a function call. -sp_square_fparen = ignore # ignore/add/remove/force - -# Add or remove space between ')' and '{' of function. -sp_fparen_brace = ignore # ignore/add/remove/force - -# Add or remove space between ')' and '{' of a function call in object -# initialization. -# -# Overrides sp_fparen_brace. -sp_fparen_brace_initializer = ignore # ignore/add/remove/force - -# (Java) Add or remove space between ')' and '{{' of double brace initializer. -sp_fparen_dbrace = ignore # ignore/add/remove/force - -# Add or remove space between function name and '(' on function calls. -sp_func_call_paren = ignore # ignore/add/remove/force - -# Add or remove space between function name and '()' on function calls without -# parameters. If set to ignore (the default), sp_func_call_paren is used. -sp_func_call_paren_empty = ignore # ignore/add/remove/force - -# Add or remove space between the user function name and '(' on function -# calls. You need to set a keyword to be a user function in the config file, -# like: -# set func_call_user tr _ i18n -sp_func_call_user_paren = ignore # ignore/add/remove/force - -# Add or remove space inside user function '(' and ')'. -sp_func_call_user_inside_fparen = ignore # ignore/add/remove/force - -# Add or remove space between nested parentheses with user functions, -# i.e. '((' vs. '( ('. -sp_func_call_user_paren_paren = ignore # ignore/add/remove/force - -# Add or remove space between a constructor/destructor and the open -# parenthesis. -sp_func_class_paren = ignore # ignore/add/remove/force - -# Add or remove space between a constructor without parameters or destructor -# and '()'. -sp_func_class_paren_empty = ignore # ignore/add/remove/force - -# Add or remove space between 'return' and '('. -sp_return_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'return' and '{'. -sp_return_brace = ignore # ignore/add/remove/force - -# Add or remove space between '__attribute__' and '('. -sp_attribute_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'defined' and '(' in '#if defined (FOO)'. -sp_defined_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'throw' and '(' in 'throw (something)'. -sp_throw_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'throw' and anything other than '(' as in -# '@throw [...];'. -sp_after_throw = ignore # ignore/add/remove/force - -# Add or remove space between 'catch' and '(' in 'catch (something) { }'. -# If set to ignore, sp_before_sparen is used. -sp_catch_paren = ignore # ignore/add/remove/force - -# (OC) Add or remove space between '@catch' and '(' -# in '@catch (something) { }'. If set to ignore, sp_catch_paren is used. -sp_oc_catch_paren = ignore # ignore/add/remove/force - -# (OC) Add or remove space before Objective-C protocol list -# as in '@protocol Protocol' or '@interface MyClass : NSObject'. -sp_before_oc_proto_list = ignore # ignore/add/remove/force - -# (OC) Add or remove space between class name and '(' -# in '@interface className(categoryName):BaseClass' -sp_oc_classname_paren = ignore # ignore/add/remove/force - -# (D) Add or remove space between 'version' and '(' -# in 'version (something) { }'. If set to ignore, sp_before_sparen is used. -sp_version_paren = ignore # ignore/add/remove/force - -# (D) Add or remove space between 'scope' and '(' -# in 'scope (something) { }'. If set to ignore, sp_before_sparen is used. -sp_scope_paren = ignore # ignore/add/remove/force - -# Add or remove space between 'super' and '(' in 'super (something)'. -# -# Default: remove -sp_super_paren = remove # ignore/add/remove/force - -# Add or remove space between 'this' and '(' in 'this (something)'. -# -# Default: remove -sp_this_paren = remove # ignore/add/remove/force - -# Add or remove space between a macro name and its definition. -sp_macro = ignore # ignore/add/remove/force - -# Add or remove space between a macro function ')' and its definition. -sp_macro_func = ignore # ignore/add/remove/force - # Add or remove space between 'else' and '{' if on the same line. sp_else_brace = force # ignore/add/remove/force # Add or remove space between '}' and 'else' if on the same line. sp_brace_else = force # ignore/add/remove/force -# Add or remove space between '}' and the name of a typedef on the same line. -sp_brace_typedef = ignore # ignore/add/remove/force - # Add or remove space before the '{' of a 'catch' statement, if the '{' and # 'catch' are on the same line, as in 'catch (decl) {'. sp_catch_brace = force # ignore/add/remove/force -# (OC) Add or remove space before the '{' of a '@catch' statement, if the '{' -# and '@catch' are on the same line, as in '@catch (decl) {'. -# If set to ignore, sp_catch_brace is used. -sp_oc_catch_brace = ignore # ignore/add/remove/force - # Add or remove space between '}' and 'catch' if on the same line. sp_brace_catch = force # ignore/add/remove/force -# (OC) Add or remove space between '}' and '@catch' if on the same line. -# If set to ignore, sp_brace_catch is used. -sp_oc_brace_catch = ignore # ignore/add/remove/force - -# Add or remove space between 'finally' and '{' if on the same line. -sp_finally_brace = ignore # ignore/add/remove/force - -# Add or remove space between '}' and 'finally' if on the same line. -sp_brace_finally = ignore # ignore/add/remove/force - -# Add or remove space between 'try' and '{' if on the same line. -sp_try_brace = ignore # ignore/add/remove/force - -# Add or remove space between get/set and '{' if on the same line. -sp_getset_brace = ignore # ignore/add/remove/force - -# Add or remove space between a variable and '{' for C++ uniform -# initialization. -sp_word_brace_init_lst = ignore # ignore/add/remove/force - -# Add or remove space between a variable and '{' for a namespace. -# -# Default: add -sp_word_brace_ns = add # ignore/add/remove/force - -# Add or remove space before the '::' operator. -sp_before_dc = ignore # ignore/add/remove/force - -# Add or remove space after the '::' operator. -sp_after_dc = ignore # ignore/add/remove/force - -# (D) Add or remove around the D named array initializer ':' operator. -sp_d_array_colon = ignore # ignore/add/remove/force - -# Add or remove space after the '!' (not) unary operator. -# -# Default: remove -sp_not = remove # ignore/add/remove/force - -# Add or remove space after the '~' (invert) unary operator. +# The number of columns to indent per level. Usually 2, 3, 4, or 8. # -# Default: remove -sp_inv = remove # ignore/add/remove/force +# Default: 8 +indent_columns = 4 # unsigned number -# Add or remove space after the '&' (address-of) unary operator. This does not -# affect the spacing after a '&' that is part of a type. +# How to use tabs when indenting code. # -# Default: remove -sp_addr = remove # ignore/add/remove/force - -# Add or remove space around the '.' or '->' operators. +# 0: Spaces only +# 1: Indent with tabs to brace level, align with spaces (default) +# 2: Indent and align with tabs, using spaces when not on a tabstop # -# Default: remove -sp_member = remove # ignore/add/remove/force +# Default: 1 +indent_with_tabs = 0 # unsigned number -# Add or remove space after the '*' (dereference) unary operator. This does -# not affect the spacing after a '*' that is part of a type. -# -# Default: remove -sp_deref = remove # ignore/add/remove/force +# Whether to indent the body of a 'namespace'. +indent_namespace = true # true/false -# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. -# -# Default: remove -sp_sign = remove # ignore/add/remove/force +# Whether the 'class' body is indented. +indent_class = true # true/false -# Add or remove space between '++' and '--' the word to which it is being -# applied, as in '(--x)' or 'y++;'. +# How to indent access specifiers that are followed by a +# colon. # -# Default: remove -sp_incdec = remove # ignore/add/remove/force - -# Add or remove space before a backslash-newline at the end of a line. +# >0: Absolute column where 1 is the leftmost column +# <=0: Subtract from brace indent # -# Default: add -sp_before_nl_cont = add # ignore/add/remove/force - -# (OC) Add or remove space after the scope '+' or '-', as in '-(void) foo;' -# or '+(int) bar;'. -sp_after_oc_scope = ignore # ignore/add/remove/force - -# (OC) Add or remove space after the colon in message specs, -# i.e. '-(int) f:(int) x;' vs. '-(int) f: (int) x;'. -sp_after_oc_colon = ignore # ignore/add/remove/force - -# (OC) Add or remove space before the colon in message specs, -# i.e. '-(int) f: (int) x;' vs. '-(int) f : (int) x;'. -sp_before_oc_colon = ignore # ignore/add/remove/force - -# (OC) Add or remove space after the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};'. -sp_after_oc_dict_colon = ignore # ignore/add/remove/force - -# (OC) Add or remove space before the colon in immutable dictionary expression -# 'NSDictionary *test = @{@"foo" :@"bar"};'. -sp_before_oc_dict_colon = ignore # ignore/add/remove/force - -# (OC) Add or remove space after the colon in message specs, -# i.e. '[object setValue:1];' vs. '[object setValue: 1];'. -sp_after_send_oc_colon = ignore # ignore/add/remove/force - -# (OC) Add or remove space before the colon in message specs, -# i.e. '[object setValue:1];' vs. '[object setValue :1];'. -sp_before_send_oc_colon = ignore # ignore/add/remove/force - -# (OC) Add or remove space after the (type) in message specs, -# i.e. '-(int)f: (int) x;' vs. '-(int)f: (int)x;'. -sp_after_oc_type = ignore # ignore/add/remove/force - -# (OC) Add or remove space after the first (type) in message specs, -# i.e. '-(int) f:(int)x;' vs. '-(int)f:(int)x;'. -sp_after_oc_return_type = ignore # ignore/add/remove/force - -# (OC) Add or remove space between '@selector' and '(', -# i.e. '@selector(msgName)' vs. '@selector (msgName)'. -# Also applies to '@protocol()' constructs. -sp_after_oc_at_sel = ignore # ignore/add/remove/force - -# (OC) Add or remove space between '@selector(x)' and the following word, -# i.e. '@selector(foo) a:' vs. '@selector(foo)a:'. -sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force - -# (OC) Add or remove space inside '@selector' parentheses, -# i.e. '@selector(foo)' vs. '@selector( foo )'. -# Also applies to '@protocol()' constructs. -sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force - -# (OC) Add or remove space before a block pointer caret, -# i.e. '^int (int arg){...}' vs. ' ^int (int arg){...}'. -sp_before_oc_block_caret = ignore # ignore/add/remove/force - -# (OC) Add or remove space after a block pointer caret, -# i.e. '^int (int arg){...}' vs. '^ int (int arg){...}'. -sp_after_oc_block_caret = ignore # ignore/add/remove/force - -# (OC) Add or remove space between the receiver and selector in a message, -# as in '[receiver selector ...]'. -sp_after_oc_msg_receiver = ignore # ignore/add/remove/force - -# (OC) Add or remove space after '@property'. -sp_after_oc_property = ignore # ignore/add/remove/force +# Default: 1 +indent_access_spec = -4 # number -# (OC) Add or remove space between '@synchronized' and the open parenthesis, -# i.e. '@synchronized(foo)' vs. '@synchronized (foo)'. -sp_after_oc_synchronized = ignore # ignore/add/remove/force +# Whether to collapse empty blocks between '{' and '}' except for functions. +# Use nl_collapse_empty_body_functions to specify how empty function braces +# should be formatted. +nl_collapse_empty_body = true # true/false -# Add or remove space around the ':' in 'b ? t : f'. -sp_cond_colon = ignore # ignore/add/remove/force +# Whether to collapse empty blocks between '{' and '}' for functions only. +# If true, overrides nl_inside_empty_func. +nl_collapse_empty_body_functions = true # true/false -# Add or remove space before the ':' in 'b ? t : f'. -# -# Overrides sp_cond_colon. -sp_cond_colon_before = ignore # ignore/add/remove/force +# Whether to convert all tabs to spaces in comments. If false, tabs in +# comments are left alone, unless used for indenting. +cmt_convert_tab_to_spaces = true # true/false -# Add or remove space after the ':' in 'b ? t : f'. +# An offset value that controls the indentation of the body of a multiline #define. +# 'body' refers to all the lines of a multiline #define except the first line. +# Requires 'pp_ignore_define_body = false'. # -# Overrides sp_cond_colon. -sp_cond_colon_after = ignore # ignore/add/remove/force - -# Add or remove space around the '?' in 'b ? t : f'. -sp_cond_question = ignore # ignore/add/remove/force - -# Add or remove space before the '?' in 'b ? t : f'. +# <0: Absolute column: the body indentation starts off at the specified column +# (ex. -3 ==> the body is indented starting from column 3) +# >=0: Relative to the column of the '#' of '#define' +# (ex. 3 ==> the body is indented starting 3 columns at the right of '#') # -# Overrides sp_cond_question. -sp_cond_question_before = ignore # ignore/add/remove/force +# Default: 8 +pp_multiline_define_body_indent = 4 # number -# Add or remove space after the '?' in 'b ? t : f'. +# The value might be used twice: +# - at the assignment +# - at the opening brace # -# Overrides sp_cond_question. -sp_cond_question_after = ignore # ignore/add/remove/force - -# In the abbreviated ternary form '(a ?: b)', add or remove space between '?' -# and ':'. -# -# Overrides all other sp_cond_* options. -sp_cond_ternary_short = ignore # ignore/add/remove/force - -# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make -# sense here. -sp_case_label = ignore # ignore/add/remove/force - -# (D) Add or remove space around the D '..' operator. -sp_range = ignore # ignore/add/remove/force - -# Add or remove space after ':' in a Java/C++11 range-based 'for', -# as in 'for (Type var : expr)'. -sp_after_for_colon = ignore # ignore/add/remove/force - -# Add or remove space before ':' in a Java/C++11 range-based 'for', -# as in 'for (Type var : expr)'. -sp_before_for_colon = ignore # ignore/add/remove/force - -# (D) Add or remove space between 'extern' and '(' as in 'extern (C)'. -sp_extern_paren = ignore # ignore/add/remove/force - -# Add or remove space after the opening of a C++ comment, -# i.e. '// A' vs. '//A'. -sp_cmt_cpp_start = ignore # ignore/add/remove/force - -# If true, space is added with sp_cmt_cpp_start will be added after doxygen -# sequences like '///', '///<', '//!' and '//!<'. -sp_cmt_cpp_doxygen = false # true/false - -# If true, space is added with sp_cmt_cpp_start will be added after Qt -# translator or meta-data comments like '//:', '//=', and '//~'. -sp_cmt_cpp_qttr = false # true/false - -# Add or remove space between #else or #endif and a trailing comment. -sp_endif_cmt = ignore # ignore/add/remove/force - -# Add or remove space after 'new', 'delete' and 'delete[]'. -sp_after_new = ignore # ignore/add/remove/force - -# Add or remove space between 'new' and '(' in 'new()'. -sp_between_new_paren = ignore # ignore/add/remove/force - -# Add or remove space between ')' and type in 'new(foo) BAR'. -sp_after_newop_paren = ignore # ignore/add/remove/force - -# Add or remove space inside parenthesis of the new operator -# as in 'new(foo) BAR'. -sp_inside_newop_paren = ignore # ignore/add/remove/force - -# Add or remove space after the open parenthesis of the new operator, -# as in 'new(foo) BAR'. -# -# Overrides sp_inside_newop_paren. -sp_inside_newop_paren_open = ignore # ignore/add/remove/force - -# Add or remove space before the close parenthesis of the new operator, -# as in 'new(foo) BAR'. -# -# Overrides sp_inside_newop_paren. -sp_inside_newop_paren_close = ignore # ignore/add/remove/force - -# Add or remove space before a trailing or embedded comment. -sp_before_tr_emb_cmt = ignore # ignore/add/remove/force - -# Number of spaces before a trailing or embedded comment. -sp_num_before_tr_emb_cmt = 0 # unsigned number - -# (Java) Add or remove space between an annotation and the open parenthesis. -sp_annotation_paren = ignore # ignore/add/remove/force - -# If true, vbrace tokens are dropped to the previous token and skipped. -sp_skip_vbrace_tokens = false # true/false - -# Add or remove space after 'noexcept'. -sp_after_noexcept = ignore # ignore/add/remove/force - -# Add or remove space after '_'. -sp_vala_after_translation = ignore # ignore/add/remove/force - -# If true, a is inserted after #define. -force_tab_after_define = false # true/false - -# -# Indenting options -# - -# The number of columns to indent per level. Usually 2, 3, 4, or 8. -# -# Default: 8 -indent_columns = 4 # unsigned number - -# The continuation indent. If non-zero, this overrides the indent of '(', '[' -# and '=' continuation indents. Negative values are OK; negative value is -# absolute and not increased for each '(' or '[' level. -# -# For FreeBSD, this is set to 4. -indent_continue = 0 # number - -# The continuation indent, only for class header line(s). If non-zero, this -# overrides the indent of 'class' continuation indents. -indent_continue_class_head = 0 # unsigned number - -# Whether to indent empty lines (i.e. lines which contain only spaces before -# the newline character). -indent_single_newlines = false # true/false - -# The continuation indent for func_*_param if they are true. If non-zero, this -# overrides the indent. -indent_param = 0 # unsigned number - -# How to use tabs when indenting code. -# -# 0: Spaces only -# 1: Indent with tabs to brace level, align with spaces (default) -# 2: Indent and align with tabs, using spaces when not on a tabstop -# -# Default: 1 -indent_with_tabs = 0 # unsigned number - -# Whether to indent comments that are not at a brace level with tabs on a -# tabstop. Requires indent_with_tabs=2. If false, will use spaces. -indent_cmt_with_tabs = false # true/false - -# Whether to indent strings broken by '\' so that they line up. -indent_align_string = false # true/false - -# The number of spaces to indent multi-line XML strings. -# Requires indent_align_string=true. -indent_xml_string = 0 # unsigned number - -# Spaces to indent '{' from level. -indent_brace = 0 # unsigned number - -# Whether braces are indented to the body level. -indent_braces = false # true/false - -# Whether to disable indenting function braces if indent_braces=true. -indent_braces_no_func = false # true/false - -# Whether to disable indenting class braces if indent_braces=true. -indent_braces_no_class = false # true/false - -# Whether to disable indenting struct braces if indent_braces=true. -indent_braces_no_struct = false # true/false - -# Whether to indent based on the size of the brace parent, -# i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. -indent_brace_parent = false # true/false - -# Whether to indent based on the open parenthesis instead of the open brace -# in '({\n'. -indent_paren_open_brace = false # true/false - -# (C#) Whether to indent the brace of a C# delegate by another level. -indent_cs_delegate_brace = false # true/false - -# (C#) Whether to indent a C# delegate (to handle delegates with no brace) by -# another level. -indent_cs_delegate_body = false # true/false - -# Whether to indent the body of a 'namespace'. -indent_namespace = true # true/false - -# Whether to indent only the first namespace, and not any nested namespaces. -# Requires indent_namespace=true. -indent_namespace_single_indent = false # true/false - -# The number of spaces to indent a namespace block. -# If set to zero, use the value indent_columns -indent_namespace_level = 0 # unsigned number - -# If the body of the namespace is longer than this number, it won't be -# indented. Requires indent_namespace=true. 0 means no limit. -indent_namespace_limit = 0 # unsigned number - -# Whether the 'extern "C"' body is indented. -indent_extern = false # true/false - -# Whether the 'class' body is indented. -indent_class = true # true/false - -# Whether to indent the stuff after a leading base class colon. -indent_class_colon = false # true/false - -# Whether to indent based on a class colon instead of the stuff after the -# colon. Requires indent_class_colon=true. -indent_class_on_colon = false # true/false - -# Whether to indent the stuff after a leading class initializer colon. -indent_constr_colon = false # true/false - -# Virtual indent from the ':' for member initializers. -# -# Default: 2 -indent_ctor_init_leading = 2 # unsigned number - -# Additional indent for constructor initializer list. -# Negative values decrease indent down to the first column. -indent_ctor_init = 0 # number - -# Whether to indent 'if' following 'else' as a new block under the 'else'. -# If false, 'else\nif' is treated as 'else if' for indenting purposes. -indent_else_if = false # true/false - -# Amount to indent variable declarations after a open brace. -# -# <0: Relative -# >=0: Absolute -indent_var_def_blk = 0 # number - -# Whether to indent continued variable declarations instead of aligning. -indent_var_def_cont = false # true/false - -# Whether to indent continued shift expressions ('<<' and '>>') instead of -# aligning. Set align_left_shift=false when enabling this. -indent_shift = false # true/false - -# Whether to force indentation of function definitions to start in column 1. -indent_func_def_force_col1 = false # true/false - -# Whether to indent continued function call parameters one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_call_param = false # true/false - -# Whether to indent continued function definition parameters one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_def_param = false # true/false - -# for function definitions, only if indent_func_def_param is false -# Allows to align params when appropriate and indent them when not -# behave as if it was true if paren position is more than this value -# if paren position is more than the option value -indent_func_def_param_paren_pos_threshold = 0 # unsigned number - -# Whether to indent continued function call prototype one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_proto_param = false # true/false - -# Whether to indent continued function call declaration one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_class_param = false # true/false - -# Whether to indent continued class variable constructors one indent level, -# rather than aligning parameters under the open parenthesis. -indent_func_ctor_var_param = false # true/false - -# Whether to indent continued template parameter list one indent level, -# rather than aligning parameters under the open parenthesis. -indent_template_param = false # true/false - -# Double the indent for indent_func_xxx_param options. -# Use both values of the options indent_columns and indent_param. -indent_func_param_double = false # true/false - -# Indentation column for standalone 'const' qualifier on a function -# prototype. -indent_func_const = 0 # unsigned number - -# Indentation column for standalone 'throw' qualifier on a function -# prototype. -indent_func_throw = 0 # unsigned number - -# How to indent within a macro followed by a brace on the same line -# This allows reducing the indent in macros that have (for example) -# `do { ... } while (0)` blocks bracketing them. -# -# true: add an indent for the brace on the same line as the macro -# false: do not add an indent for the brace on the same line as the macro -# -# Default: true -indent_macro_brace = true # true/false - -# The number of spaces to indent a continued '->' or '.'. -# Usually set to 0, 1, or indent_columns. -indent_member = 0 # unsigned number - -# Whether lines broken at '.' or '->' should be indented by a single indent. -# The indent_member option will not be effective if this is set to true. -indent_member_single = false # true/false - -# Spaces to indent single line ('//') comments on lines before code. -indent_sing_line_comments = 0 # unsigned number - -# When opening a paren for a control statement (if, for, while, etc), increase -# the indent level by this value. Negative values decrease the indent level. -indent_sparen_extra = 0 # number - -# Whether to indent trailing single line ('//') comments relative to the code -# instead of trying to keep the same absolute column. -indent_relative_single_line_comments = false # true/false - -# Spaces to indent 'case' from 'switch'. Usually 0 or indent_columns. -indent_switch_case = 0 # unsigned number - -# indent 'break' with 'case' from 'switch'. -indent_switch_break_with_case = false # true/false - -# Whether to indent preprocessor statements inside of switch statements. -# -# Default: true -indent_switch_pp = true # true/false - -# Spaces to shift the 'case' line, without affecting any other lines. -# Usually 0. -indent_case_shift = 0 # unsigned number - -# Spaces to indent '{' from 'case'. By default, the brace will appear under -# the 'c' in case. Usually set to 0 or indent_columns. Negative values are OK. -indent_case_brace = 0 # number - -# Whether to indent comments found in first column. -indent_col1_comment = false # true/false - -# Whether to indent multi string literal in first column. -indent_col1_multi_string_literal = false # true/false - -# How to indent goto labels. -# -# >0: Absolute column where 1 is the leftmost column -# <=0: Subtract from brace indent -# -# Default: 1 -indent_label = 1 # number - -# How to indent access specifiers that are followed by a -# colon. -# -# >0: Absolute column where 1 is the leftmost column -# <=0: Subtract from brace indent -# -# Default: 1 -indent_access_spec = -4 # number - -# Whether to indent the code after an access specifier by one level. -# If true, this option forces 'indent_access_spec=0'. -indent_access_spec_body = false # true/false - -# If an open parenthesis is followed by a newline, whether to indent the next -# line so that it lines up after the open parenthesis (not recommended). -indent_paren_nl = false # true/false - -# How to indent a close parenthesis after a newline. -# -# 0: Indent to body level (default) -# 1: Align under the open parenthesis -# 2: Indent to the brace level -indent_paren_close = 0 # unsigned number - -# Whether to indent the open parenthesis of a function definition, -# if the parenthesis is on its own line. -indent_paren_after_func_def = false # true/false - -# Whether to indent the open parenthesis of a function declaration, -# if the parenthesis is on its own line. -indent_paren_after_func_decl = false # true/false - -# Whether to indent the open parenthesis of a function call, -# if the parenthesis is on its own line. -indent_paren_after_func_call = false # true/false - -# Whether to indent a comma when inside a parenthesis. -# If true, aligns under the open parenthesis. -indent_comma_paren = false # true/false - -# Whether to indent a Boolean operator when inside a parenthesis. -# If true, aligns under the open parenthesis. -indent_bool_paren = false # true/false - -# Whether to indent a semicolon when inside a for parenthesis. -# If true, aligns under the open for parenthesis. -indent_semicolon_for_paren = false # true/false - -# Whether to align the first expression to following ones -# if indent_bool_paren=true. -indent_first_bool_expr = false # true/false - -# Whether to align the first expression to following ones -# if indent_semicolon_for_paren=true. -indent_first_for_expr = false # true/false - -# If an open square is followed by a newline, whether to indent the next line -# so that it lines up after the open square (not recommended). -indent_square_nl = false # true/false - -# (ESQL/C) Whether to preserve the relative indent of 'EXEC SQL' bodies. -indent_preserve_sql = false # true/false - -# Whether to align continued statements at the '='. If false or if the '=' is -# followed by a newline, the next line is indent one tab. -# -# Default: true -indent_align_assign = true # true/false - -# If true, the indentation of the chunks after a '=' sequence will be set at -# LHS token indentation column before '='. -indent_off_after_assign = false # true/false - -# Whether to align continued statements at the '('. If false or the '(' is -# followed by a newline, the next line indent is one tab. -# -# Default: true -indent_align_paren = true # true/false - -# (OC) Whether to indent Objective-C code inside message selectors. -indent_oc_inside_msg_sel = false # true/false - -# (OC) Whether to indent Objective-C blocks at brace level instead of usual -# rules. -indent_oc_block = false # true/false - -# (OC) Indent for Objective-C blocks in a message relative to the parameter -# name. -# -# =0: Use indent_oc_block rules -# >0: Use specified number of spaces to indent -indent_oc_block_msg = 0 # unsigned number - -# (OC) Minimum indent for subsequent parameters -indent_oc_msg_colon = 0 # unsigned number - -# (OC) Whether to prioritize aligning with initial colon (and stripping spaces -# from lines, if necessary). -# -# Default: true -indent_oc_msg_prioritize_first_colon = true # true/false - -# (OC) Whether to indent blocks the way that Xcode does by default -# (from the keyword if the parameter is on its own line; otherwise, from the -# previous indentation level). Requires indent_oc_block_msg=true. -indent_oc_block_msg_xcode_style = false # true/false - -# (OC) Whether to indent blocks from where the brace is, relative to a -# message keyword. Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_keyword = false # true/false - -# (OC) Whether to indent blocks from where the brace is, relative to a message -# colon. Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_colon = false # true/false - -# (OC) Whether to indent blocks from where the block caret is. -# Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_caret = false # true/false - -# (OC) Whether to indent blocks from where the brace caret is. -# Requires indent_oc_block_msg=true. -indent_oc_block_msg_from_brace = false # true/false - -# When indenting after virtual brace open and newline add further spaces to -# reach this minimum indent. -indent_min_vbrace_open = 0 # unsigned number - -# Whether to add further spaces after regular indent to reach next tabstop -# when indenting after virtual brace open and newline. -indent_vbrace_open_on_tabstop = false # true/false - -# How to indent after a brace followed by another token (not a newline). -# true: indent all contained lines to match the token -# false: indent all contained lines to match the brace -# -# Default: true -indent_token_after_brace = true # true/false - -# Whether to indent the body of a C++11 lambda. -indent_cpp_lambda_body = false # true/false - -# How to indent compound literals that are being returned. -# true: add both the indent from return & the compound literal open brace (ie: -# 2 indent levels) -# false: only indent 1 level, don't add the indent for the open brace, only add -# the indent for the return. -# -# Default: true -indent_compound_literal_return = true # true/false - -# (C#) Whether to indent a 'using' block if no braces are used. -# -# Default: true -indent_using_block = true # true/false - -# How to indent the continuation of ternary operator. -# -# 0: Off (default) -# 1: When the `if_false` is a continuation, indent it under `if_false` -# 2: When the `:` is a continuation, indent it under `?` -indent_ternary_operator = 0 # unsigned number - -# Whether to indent the statments inside ternary operator. -indent_inside_ternary_operator = false # true/false - -# If true, the indentation of the chunks after a `return` sequence will be set at return indentation column. -indent_off_after_return = false # true/false - -# If true, the indentation of the chunks after a `return new` sequence will be set at return indentation column. -indent_off_after_return_new = false # true/false - -# If true, the tokens after return are indented with regular single indentation. By default (false) the indentation is after the return token. -indent_single_after_return = false # true/false - -# Whether to ignore indent and alignment for 'asm' blocks (i.e. assume they -# have their own indentation). -indent_ignore_asm_block = false # true/false - -# Don't indent the close parenthesis of a function definition, -# if the parenthesis is on its own line. -donot_indent_func_def_close_paren = false # true/false - -# -# Newline adding and removing options -# - -# Whether to collapse empty blocks between '{' and '}'. -# If true, overrides nl_inside_empty_func -nl_collapse_empty_body = true # true/false - -# Don't split one-line braced assignments, as in 'foo_t f = { 1, 2 };'. -nl_assign_leave_one_liners = false # true/false - -# Don't split one-line braced statements inside a 'class xx { }' body. -nl_class_leave_one_liners = false # true/false - -# Don't split one-line enums, as in 'enum foo { BAR = 15 };' -nl_enum_leave_one_liners = false # true/false - -# Don't split one-line get or set functions. -nl_getset_leave_one_liners = false # true/false - -# (C#) Don't split one-line property get or set functions. -nl_cs_property_leave_one_liners = false # true/false - -# Don't split one-line function definitions, as in 'int foo() { return 0; }'. -# might modify nl_func_type_name -nl_func_leave_one_liners = false # true/false - -# Don't split one-line C++11 lambdas, as in '[]() { return 0; }'. -nl_cpp_lambda_leave_one_liners = false # true/false - -# Don't split one-line if/else statements, as in 'if(...) b++;'. -nl_if_leave_one_liners = false # true/false - -# Don't split one-line while statements, as in 'while(...) b++;'. -nl_while_leave_one_liners = false # true/false - -# Don't split one-line for statements, as in 'for(...) b++;'. -nl_for_leave_one_liners = false # true/false - -# (OC) Don't split one-line Objective-C messages. -nl_oc_msg_leave_one_liner = false # true/false - -# (OC) Add or remove newline between method declaration and '{'. -nl_oc_mdef_brace = ignore # ignore/add/remove/force - -# (OC) Add or remove newline between Objective-C block signature and '{'. -nl_oc_block_brace = ignore # ignore/add/remove/force - -# (OC) Add or remove blank line before '@interface' statement. -nl_oc_before_interface = ignore # ignore/add/remove/force - -# (OC) Add or remove blank line before '@implementation' statement. -nl_oc_before_implementation = ignore # ignore/add/remove/force - -# (OC) Add or remove blank line before '@end' statement. -nl_oc_before_end = ignore # ignore/add/remove/force - -# (OC) Add or remove newline between '@interface' and '{'. -nl_oc_interface_brace = ignore # ignore/add/remove/force - -# (OC) Add or remove newline between '@implementation' and '{'. -nl_oc_implementation_brace = ignore # ignore/add/remove/force - -# Add or remove newlines at the start of the file. -nl_start_of_file = ignore # ignore/add/remove/force - -# The minimum number of newlines at the start of the file (only used if -# nl_start_of_file is 'add' or 'force'). -nl_start_of_file_min = 0 # unsigned number - -# Add or remove newline at the end of the file. -nl_end_of_file = ignore # ignore/add/remove/force - -# The minimum number of newlines at the end of the file (only used if -# nl_end_of_file is 'add' or 'force'). -nl_end_of_file_min = 0 # unsigned number - -# Add or remove newline between '=' and '{'. -nl_assign_brace = ignore # ignore/add/remove/force - -# (D) Add or remove newline between '=' and '['. -nl_assign_square = ignore # ignore/add/remove/force - -# Add or remove newline between '[]' and '{'. -nl_tsquare_brace = ignore # ignore/add/remove/force - -# (D) Add or remove newline after '= ['. Will also affect the newline before -# the ']'. -nl_after_square_assign = ignore # ignore/add/remove/force - -# Add or remove newline between a function call's ')' and '{', as in -# 'list_for_each(item, &list) { }'. -nl_fcall_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'enum' and '{'. -nl_enum_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'enum' and 'class'. -nl_enum_class = ignore # ignore/add/remove/force - -# Add or remove newline between 'enum class' and the identifier. -nl_enum_class_identifier = ignore # ignore/add/remove/force - -# Add or remove newline between 'enum class' type and ':'. -nl_enum_identifier_colon = ignore # ignore/add/remove/force - -# Add or remove newline between 'enum class identifier :' and type. -nl_enum_colon_type = ignore # ignore/add/remove/force - -# Add or remove newline between 'struct and '{'. -nl_struct_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'union' and '{'. -nl_union_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'if' and '{'. -nl_if_brace = ignore # ignore/add/remove/force - -# Add or remove newline between '}' and 'else'. -nl_brace_else = ignore # ignore/add/remove/force - -# Add or remove newline between 'else if' and '{'. If set to ignore, -# nl_if_brace is used instead. -nl_elseif_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'else' and '{'. -nl_else_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'else' and 'if'. -nl_else_if = ignore # ignore/add/remove/force - -# Add or remove newline before '{' opening brace -nl_before_opening_brace_func_class_def = ignore # ignore/add/remove/force - -# Add or remove newline before 'if'/'else if' closing parenthesis. -nl_before_if_closing_paren = ignore # ignore/add/remove/force - -# Add or remove newline between '}' and 'finally'. -nl_brace_finally = ignore # ignore/add/remove/force - -# Add or remove newline between 'finally' and '{'. -nl_finally_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'try' and '{'. -nl_try_brace = ignore # ignore/add/remove/force - -# Add or remove newline between get/set and '{'. -nl_getset_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'for' and '{'. -nl_for_brace = ignore # ignore/add/remove/force - -# Add or remove newline before the '{' of a 'catch' statement, as in -# 'catch (decl) {'. -nl_catch_brace = ignore # ignore/add/remove/force - -# (OC) Add or remove newline before the '{' of a '@catch' statement, as in -# '@catch (decl) {'. If set to ignore, nl_catch_brace is used. -nl_oc_catch_brace = ignore # ignore/add/remove/force - -# Add or remove newline between '}' and 'catch'. -nl_brace_catch = ignore # ignore/add/remove/force - -# (OC) Add or remove newline between '}' and '@catch'. If set to ignore, -# nl_brace_catch is used. -nl_oc_brace_catch = ignore # ignore/add/remove/force - -# Add or remove newline between '}' and ']'. -nl_brace_square = ignore # ignore/add/remove/force - -# Add or remove newline between '}' and ')' in a function invocation. -nl_brace_fparen = ignore # ignore/add/remove/force - -# Add or remove newline between 'while' and '{'. -nl_while_brace = ignore # ignore/add/remove/force - -# (D) Add or remove newline between 'scope (x)' and '{'. -nl_scope_brace = ignore # ignore/add/remove/force - -# (D) Add or remove newline between 'unittest' and '{'. -nl_unittest_brace = ignore # ignore/add/remove/force - -# (D) Add or remove newline between 'version (x)' and '{'. -nl_version_brace = ignore # ignore/add/remove/force - -# (C#) Add or remove newline between 'using' and '{'. -nl_using_brace = ignore # ignore/add/remove/force - -# Add or remove newline between two open or close braces. Due to general -# newline/brace handling, REMOVE may not work. -nl_brace_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'do' and '{'. -nl_do_brace = ignore # ignore/add/remove/force - -# Add or remove newline between '}' and 'while' of 'do' statement. -nl_brace_while = ignore # ignore/add/remove/force - -# Add or remove newline between 'switch' and '{'. -nl_switch_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'synchronized' and '{'. -nl_synchronized_brace = ignore # ignore/add/remove/force - -# Add a newline between ')' and '{' if the ')' is on a different line than the -# if/for/etc. -# -# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch and -# nl_catch_brace. -nl_multi_line_cond = false # true/false - -# Add a newline after '(' if an if/for/while/switch condition spans multiple -# lines -nl_multi_line_sparen_open = ignore # ignore/add/remove/force - -# Add a newline before ')' if an if/for/while/switch condition spans multiple -# lines. Overrides nl_before_if_closing_paren if both are specified. -nl_multi_line_sparen_close = ignore # ignore/add/remove/force - -# Force a newline in a define after the macro name for multi-line defines. -nl_multi_line_define = false # true/false - -# Whether to add a newline before 'case', and a blank line before a 'case' -# statement that follows a ';' or '}'. -nl_before_case = false # true/false - -# Whether to add a newline after a 'case' statement. -nl_after_case = false # true/false - -# Add or remove newline between a case ':' and '{'. -# -# Overrides nl_after_case. -nl_case_colon_brace = ignore # ignore/add/remove/force - -# Add or remove newline between ')' and 'throw'. -nl_before_throw = ignore # ignore/add/remove/force - -# Add or remove newline between 'namespace' and '{'. -nl_namespace_brace = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template class. -nl_template_class = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template class declaration. -# -# Overrides nl_template_class. -nl_template_class_decl = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<>' of a specialized class declaration. -# -# Overrides nl_template_class_decl. -nl_template_class_decl_special = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template class definition. -# -# Overrides nl_template_class. -nl_template_class_def = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<>' of a specialized class definition. -# -# Overrides nl_template_class_def. -nl_template_class_def_special = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template function. -nl_template_func = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template function -# declaration. -# -# Overrides nl_template_func. -nl_template_func_decl = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<>' of a specialized function -# declaration. -# -# Overrides nl_template_func_decl. -nl_template_func_decl_special = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template function -# definition. -# -# Overrides nl_template_func. -nl_template_func_def = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<>' of a specialized function -# definition. -# -# Overrides nl_template_func_def. -nl_template_func_def_special = ignore # ignore/add/remove/force - -# Add or remove newline after 'template<...>' of a template variable. -nl_template_var = ignore # ignore/add/remove/force - -# Add or remove newline between 'template<...>' and 'using' of a templated -# type alias. -nl_template_using = ignore # ignore/add/remove/force - -# Add or remove newline between 'class' and '{'. -nl_class_brace = ignore # ignore/add/remove/force - -# Add or remove newline before or after (depending on pos_class_comma, -# may not be IGNORE) each',' in the base class list. -nl_class_init_args = ignore # ignore/add/remove/force - -# Add or remove newline after each ',' in the constructor member -# initialization. Related to nl_constr_colon, pos_constr_colon and -# pos_constr_comma. -nl_constr_init_args = ignore # ignore/add/remove/force - -# Add or remove newline before first element, after comma, and after last -# element, in 'enum'. -nl_enum_own_lines = ignore # ignore/add/remove/force - -# Add or remove newline between return type and function name in a function -# definition. -# might be modified by nl_func_leave_one_liners -nl_func_type_name = ignore # ignore/add/remove/force - -# Add or remove newline between return type and function name inside a class -# definition. If set to ignore, nl_func_type_name or nl_func_proto_type_name -# is used instead. -nl_func_type_name_class = ignore # ignore/add/remove/force - -# Add or remove newline between class specification and '::' -# in 'void A::f() { }'. Only appears in separate member implementation (does -# not appear with in-line implementation). -nl_func_class_scope = ignore # ignore/add/remove/force - -# Add or remove newline between function scope and name, as in -# 'void A :: f() { }'. -nl_func_scope_name = ignore # ignore/add/remove/force - -# Add or remove newline between return type and function name in a prototype. -nl_func_proto_type_name = ignore # ignore/add/remove/force - -# Add or remove newline between a function name and the opening '(' in the -# declaration. -nl_func_paren = ignore # ignore/add/remove/force - -# Overrides nl_func_paren for functions with no parameters. -nl_func_paren_empty = ignore # ignore/add/remove/force - -# Add or remove newline between a function name and the opening '(' in the -# definition. -nl_func_def_paren = ignore # ignore/add/remove/force - -# Overrides nl_func_def_paren for functions with no parameters. -nl_func_def_paren_empty = ignore # ignore/add/remove/force - -# Add or remove newline between a function name and the opening '(' in the -# call. -nl_func_call_paren = ignore # ignore/add/remove/force - -# Overrides nl_func_call_paren for functions with no parameters. -nl_func_call_paren_empty = ignore # ignore/add/remove/force - -# Add or remove newline after '(' in a function declaration. -nl_func_decl_start = ignore # ignore/add/remove/force - -# Add or remove newline after '(' in a function definition. -nl_func_def_start = ignore # ignore/add/remove/force - -# Overrides nl_func_decl_start when there is only one parameter. -nl_func_decl_start_single = ignore # ignore/add/remove/force - -# Overrides nl_func_def_start when there is only one parameter. -nl_func_def_start_single = ignore # ignore/add/remove/force - -# Whether to add a newline after '(' in a function declaration if '(' and ')' -# are in different lines. If false, nl_func_decl_start is used instead. -nl_func_decl_start_multi_line = false # true/false - -# Whether to add a newline after '(' in a function definition if '(' and ')' -# are in different lines. If false, nl_func_def_start is used instead. -nl_func_def_start_multi_line = false # true/false - -# Add or remove newline after each ',' in a function declaration. -nl_func_decl_args = ignore # ignore/add/remove/force - -# Add or remove newline after each ',' in a function definition. -nl_func_def_args = ignore # ignore/add/remove/force - -# Add or remove newline after each ',' in a function call. -nl_func_call_args = ignore # ignore/add/remove/force - -# Whether to add a newline after each ',' in a function declaration if '(' -# and ')' are in different lines. If false, nl_func_decl_args is used instead. -nl_func_decl_args_multi_line = false # true/false - -# Whether to add a newline after each ',' in a function definition if '(' -# and ')' are in different lines. If false, nl_func_def_args is used instead. -nl_func_def_args_multi_line = false # true/false - -# Add or remove newline before the ')' in a function declaration. -nl_func_decl_end = ignore # ignore/add/remove/force - -# Add or remove newline before the ')' in a function definition. -nl_func_def_end = ignore # ignore/add/remove/force - -# Overrides nl_func_decl_end when there is only one parameter. -nl_func_decl_end_single = ignore # ignore/add/remove/force - -# Overrides nl_func_def_end when there is only one parameter. -nl_func_def_end_single = ignore # ignore/add/remove/force - -# Whether to add a newline before ')' in a function declaration if '(' and ')' -# are in different lines. If false, nl_func_decl_end is used instead. -nl_func_decl_end_multi_line = false # true/false - -# Whether to add a newline before ')' in a function definition if '(' and ')' -# are in different lines. If false, nl_func_def_end is used instead. -nl_func_def_end_multi_line = false # true/false - -# Add or remove newline between '()' in a function declaration. -nl_func_decl_empty = ignore # ignore/add/remove/force - -# Add or remove newline between '()' in a function definition. -nl_func_def_empty = ignore # ignore/add/remove/force - -# Add or remove newline between '()' in a function call. -nl_func_call_empty = ignore # ignore/add/remove/force - -# Whether to add a newline after '(' in a function call, -# has preference over nl_func_call_start_multi_line. -nl_func_call_start = ignore # ignore/add/remove/force - -# Whether to add a newline before ')' in a function call. -nl_func_call_end = ignore # ignore/add/remove/force - -# Whether to add a newline after '(' in a function call if '(' and ')' are in -# different lines. -nl_func_call_start_multi_line = false # true/false - -# Whether to add a newline after each ',' in a function call if '(' and ')' -# are in different lines. -nl_func_call_args_multi_line = false # true/false - -# Whether to add a newline before ')' in a function call if '(' and ')' are in -# different lines. -nl_func_call_end_multi_line = false # true/false - -# Whether to respect nl_func_call_XXX option incase of closure args. -nl_func_call_args_multi_line_ignore_closures = false # true/false - -# Whether to add a newline after '<' of a template parameter list. -nl_template_start = false # true/false - -# Whether to add a newline after each ',' in a template parameter list. -nl_template_args = false # true/false - -# Whether to add a newline before '>' of a template parameter list. -nl_template_end = false # true/false - -# (OC) Whether to put each Objective-C message parameter on a separate line. -# See nl_oc_msg_leave_one_liner. -nl_oc_msg_args = false # true/false - -# Add or remove newline between function signature and '{'. -nl_fdef_brace = ignore # ignore/add/remove/force - -# Add or remove newline between function signature and '{', -# if signature ends with ')'. Overrides nl_fdef_brace. -nl_fdef_brace_cond = ignore # ignore/add/remove/force - -# Add or remove newline between C++11 lambda signature and '{'. -nl_cpp_ldef_brace = ignore # ignore/add/remove/force - -# Add or remove newline between 'return' and the return expression. -nl_return_expr = ignore # ignore/add/remove/force - -# Whether to add a newline after semicolons, except in 'for' statements. -nl_after_semicolon = false # true/false - -# (Java) Add or remove newline between the ')' and '{{' of the double brace -# initializer. -nl_paren_dbrace_open = ignore # ignore/add/remove/force - -# Whether to add a newline after the type in an unnamed temporary -# direct-list-initialization. -nl_type_brace_init_lst = ignore # ignore/add/remove/force - -# Whether to add a newline after the open brace in an unnamed temporary -# direct-list-initialization. -nl_type_brace_init_lst_open = ignore # ignore/add/remove/force - -# Whether to add a newline before the close brace in an unnamed temporary -# direct-list-initialization. -nl_type_brace_init_lst_close = ignore # ignore/add/remove/force - -# Whether to add a newline after '{'. This also adds a newline before the -# matching '}'. -nl_after_brace_open = false # true/false - -# Whether to add a newline between the open brace and a trailing single-line -# comment. Requires nl_after_brace_open=true. -nl_after_brace_open_cmt = false # true/false - -# Whether to add a newline after a virtual brace open with a non-empty body. -# These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open = false # true/false - -# Whether to add a newline after a virtual brace open with an empty body. -# These occur in un-braced if/while/do/for statement bodies. -nl_after_vbrace_open_empty = false # true/false - -# Whether to add a newline after '}'. Does not apply if followed by a -# necessary ';'. -nl_after_brace_close = false # true/false - -# Whether to add a newline after a virtual brace close, -# as in 'if (foo) a++; return;'. -nl_after_vbrace_close = false # true/false - -# Add or remove newline between the close brace and identifier, -# as in 'struct { int a; } b;'. Affects enumerations, unions and -# structures. If set to ignore, uses nl_after_brace_close. -nl_brace_struct_var = ignore # ignore/add/remove/force - -# Whether to alter newlines in '#define' macros. -nl_define_macro = false # true/false - -# Whether to alter newlines between consecutive parenthesis closes. The number -# of closing parentheses in a line will depend on respective open parenthesis -# lines. -nl_squeeze_paren_close = false # true/false - -# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and -# '#endif'. Does not affect top-level #ifdefs. -nl_squeeze_ifdef = false # true/false - -# Makes the nl_squeeze_ifdef option affect the top-level #ifdefs as well. -nl_squeeze_ifdef_top_level = false # true/false - -# Add or remove blank line before 'if'. -nl_before_if = ignore # ignore/add/remove/force - -# Add or remove blank line after 'if' statement. Add/Force work only if the -# next token is not a closing brace. -nl_after_if = ignore # ignore/add/remove/force - -# Add or remove blank line before 'for'. -nl_before_for = ignore # ignore/add/remove/force - -# Add or remove blank line after 'for' statement. -nl_after_for = ignore # ignore/add/remove/force - -# Add or remove blank line before 'while'. -nl_before_while = ignore # ignore/add/remove/force - -# Add or remove blank line after 'while' statement. -nl_after_while = ignore # ignore/add/remove/force - -# Add or remove blank line before 'switch'. -nl_before_switch = ignore # ignore/add/remove/force - -# Add or remove blank line after 'switch' statement. -nl_after_switch = ignore # ignore/add/remove/force - -# Add or remove blank line before 'synchronized'. -nl_before_synchronized = ignore # ignore/add/remove/force - -# Add or remove blank line after 'synchronized' statement. -nl_after_synchronized = ignore # ignore/add/remove/force - -# Add or remove blank line before 'do'. -nl_before_do = ignore # ignore/add/remove/force - -# Add or remove blank line after 'do/while' statement. -nl_after_do = ignore # ignore/add/remove/force - -# Whether to put a blank line before 'return' statements, unless after an open -# brace. -nl_before_return = false # true/false - -# Whether to put a blank line after 'return' statements, unless followed by a -# close brace. -nl_after_return = false # true/false - -# Whether to put a blank line before a member '.' or '->' operators. -nl_before_member = ignore # ignore/add/remove/force - -# (Java) Whether to put a blank line after a member '.' or '->' operators. -nl_after_member = ignore # ignore/add/remove/force - -# Whether to double-space commented-entries in 'struct'/'union'/'enum'. -nl_ds_struct_enum_cmt = false # true/false - -# Whether to force a newline before '}' of a 'struct'/'union'/'enum'. -# (Lower priority than eat_blanks_before_close_brace.) -nl_ds_struct_enum_close_brace = false # true/false - -# Add or remove newline before or after (depending on pos_class_colon) a class -# colon, as in 'class Foo : public Bar'. -nl_class_colon = ignore # ignore/add/remove/force - -# Add or remove newline around a class constructor colon. The exact position -# depends on nl_constr_init_args, pos_constr_colon and pos_constr_comma. -nl_constr_colon = ignore # ignore/add/remove/force - -# Whether to collapse a two-line namespace, like 'namespace foo\n{ decl; }' -# into a single line. If true, prevents other brace newline rules from turning -# such code into four lines. -nl_namespace_two_to_one_liner = false # true/false - -# Whether to remove a newline in simple unbraced if statements, turning them -# into one-liners, as in 'if(b)\n i++;' => 'if(b) i++;'. -nl_create_if_one_liner = false # true/false - -# Whether to remove a newline in simple unbraced for statements, turning them -# into one-liners, as in 'for (...)\n stmt;' => 'for (...) stmt;'. -nl_create_for_one_liner = false # true/false - -# Whether to remove a newline in simple unbraced while statements, turning -# them into one-liners, as in 'while (expr)\n stmt;' => 'while (expr) stmt;'. -nl_create_while_one_liner = false # true/false - -# Whether to collapse a function definition whose body (not counting braces) -# is only one line so that the entire definition (prototype, braces, body) is -# a single line. -nl_create_func_def_one_liner = false # true/false - -# Whether to collapse a function definition whose body (not counting braces) -# is only one line so that the entire definition (prototype, braces, body) is -# a single line. -nl_create_list_one_liner = false # true/false - -# Whether to split one-line simple unbraced if statements into two lines by -# adding a newline, as in 'if(b) i++;'. -nl_split_if_one_liner = false # true/false - -# Whether to split one-line simple unbraced for statements into two lines by -# adding a newline, as in 'for (...) stmt;'. -nl_split_for_one_liner = false # true/false - -# Whether to split one-line simple unbraced while statements into two lines by -# adding a newline, as in 'while (expr) stmt;'. -nl_split_while_one_liner = false # true/false - -# Don't add a newline before a cpp-comment in a parameter list of a function -# call. -donot_add_nl_before_cpp_comment = false # true/false - -# -# Blank line options -# - -# The maximum number of consecutive newlines (3 = 2 blank lines). -nl_max = 0 # unsigned number - -# The maximum number of consecutive newlines in a function. -nl_max_blank_in_func = 0 # unsigned number - -# The number of newlines inside an empty function body. -# This option is overridden by nl_collapse_empty_body=true -nl_inside_empty_func = 0 # unsigned number - -# The number of newlines before a function prototype. -nl_before_func_body_proto = 0 # unsigned number - -# The number of newlines before a multi-line function definition. -nl_before_func_body_def = 0 # unsigned number - -# The number of newlines before a class constructor/destructor prototype. -nl_before_func_class_proto = 0 # unsigned number - -# The number of newlines before a class constructor/destructor definition. -nl_before_func_class_def = 0 # unsigned number - -# The number of newlines after a function prototype. -nl_after_func_proto = 0 # unsigned number - -# The number of newlines after a function prototype, if not followed by -# another function prototype. -nl_after_func_proto_group = 0 # unsigned number - -# The number of newlines after a class constructor/destructor prototype. -nl_after_func_class_proto = 0 # unsigned number - -# The number of newlines after a class constructor/destructor prototype, -# if not followed by another constructor/destructor prototype. -nl_after_func_class_proto_group = 0 # unsigned number - -# Whether one-line method definitions inside a class body should be treated -# as if they were prototypes for the purposes of adding newlines. -# -# Requires nl_class_leave_one_liners=true. Overrides nl_before_func_body_def -# and nl_before_func_class_def for one-liners. -nl_class_leave_one_liner_groups = false # true/false - -# The number of newlines after '}' of a multi-line function body. -nl_after_func_body = 0 # unsigned number - -# The number of newlines after '}' of a multi-line function body in a class -# declaration. Also affects class constructors/destructors. -# -# Overrides nl_after_func_body. -nl_after_func_body_class = 0 # unsigned number - -# The number of newlines after '}' of a single line function body. Also -# affects class constructors/destructors. -# -# Overrides nl_after_func_body and nl_after_func_body_class. -nl_after_func_body_one_liner = 0 # unsigned number - -# The number of blank lines after a block of variable definitions at the top -# of a function body. -# -# 0: No change (default). -nl_func_var_def_blk = 0 # unsigned number - -# The number of newlines before a block of typedefs. If nl_after_access_spec -# is non-zero, that option takes precedence. -# -# 0: No change (default). -nl_typedef_blk_start = 0 # unsigned number - -# The number of newlines after a block of typedefs. -# -# 0: No change (default). -nl_typedef_blk_end = 0 # unsigned number - -# The maximum number of consecutive newlines within a block of typedefs. -# -# 0: No change (default). -nl_typedef_blk_in = 0 # unsigned number - -# The number of newlines before a block of variable definitions not at the top -# of a function body. If nl_after_access_spec is non-zero, that option takes -# precedence. -# -# 0: No change (default). -nl_var_def_blk_start = 0 # unsigned number - -# The number of newlines after a block of variable definitions not at the top -# of a function body. -# -# 0: No change (default). -nl_var_def_blk_end = 0 # unsigned number - -# The maximum number of consecutive newlines within a block of variable -# definitions. -# -# 0: No change (default). -nl_var_def_blk_in = 0 # unsigned number - -# The minimum number of newlines before a multi-line comment. -# Doesn't apply if after a brace open or another multi-line comment. -nl_before_block_comment = 0 # unsigned number - -# The minimum number of newlines before a single-line C comment. -# Doesn't apply if after a brace open or other single-line C comments. -nl_before_c_comment = 0 # unsigned number - -# The minimum number of newlines before a CPP comment. -# Doesn't apply if after a brace open or other CPP comments. -nl_before_cpp_comment = 0 # unsigned number - -# Whether to force a newline after a multi-line comment. -nl_after_multiline_comment = false # true/false - -# Whether to force a newline after a label's colon. -nl_after_label_colon = false # true/false - -# The number of newlines after '}' or ';' of a struct/enum/union definition. -nl_after_struct = 0 # unsigned number - -# The number of newlines before a class definition. -nl_before_class = 0 # unsigned number - -# The number of newlines after '}' or ';' of a class definition. -nl_after_class = 0 # unsigned number - -# The number of newlines before a namespace. -nl_before_namespace = 0 # unsigned number - -# The number of newlines after '{' of a namespace. This also adds newlines -# before the matching '}'. -# -# 0: Apply eat_blanks_after_open_brace or eat_blanks_before_close_brace if -# applicable, otherwise no change. -# -# Overrides eat_blanks_after_open_brace and eat_blanks_before_close_brace. -nl_inside_namespace = 0 # unsigned number - -# The number of newlines after '}' of a namespace. -nl_after_namespace = 0 # unsigned number - -# The number of newlines before an access specifier label. This also includes -# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count -# if after a brace open. -# -# 0: No change (default). -nl_before_access_spec = 0 # unsigned number - -# The number of newlines after an access specifier label. This also includes -# the Qt-specific 'signals:' and 'slots:'. Will not change the newline count -# if after a brace open. -# -# 0: No change (default). -# -# Overrides nl_typedef_blk_start and nl_var_def_blk_start. -nl_after_access_spec = 0 # unsigned number - -# The number of newlines between a function definition and the function -# comment, as in '// comment\n void foo() {...}'. -# -# 0: No change (default). -nl_comment_func_def = 0 # unsigned number - -# The number of newlines after a try-catch-finally block that isn't followed -# by a brace close. -# -# 0: No change (default). -nl_after_try_catch_finally = 0 # unsigned number - -# (C#) The number of newlines before and after a property, indexer or event -# declaration. -# -# 0: No change (default). -nl_around_cs_property = 0 # unsigned number - -# (C#) The number of newlines between the get/set/add/remove handlers. -# -# 0: No change (default). -nl_between_get_set = 0 # unsigned number - -# (C#) Add or remove newline between property and the '{'. -nl_property_brace = ignore # ignore/add/remove/force - -# Whether to remove blank lines after '{'. -eat_blanks_after_open_brace = false # true/false - -# Whether to remove blank lines before '}'. -eat_blanks_before_close_brace = false # true/false - -# How aggressively to remove extra newlines not in preprocessor. -# -# 0: No change (default) -# 1: Remove most newlines not handled by other config -# 2: Remove all newlines and reformat completely by config -nl_remove_extra_newlines = 0 # unsigned number - -# (Java) Add or remove newline after an annotation statement. Only affects -# annotations that are after a newline. -nl_after_annotation = ignore # ignore/add/remove/force - -# (Java) Add or remove newline between two annotations. -nl_between_annotation = ignore # ignore/add/remove/force - -# The number of newlines before a whole-file #ifdef. -# -# 0: No change (default). -nl_before_whole_file_ifdef = 0 # unsigned number - -# The number of newlines after a whole-file #ifdef. -# -# 0: No change (default). -nl_after_whole_file_ifdef = 0 # unsigned number - -# The number of newlines before a whole-file #endif. -# -# 0: No change (default). -nl_before_whole_file_endif = 0 # unsigned number - -# The number of newlines after a whole-file #endif. -# -# 0: No change (default). -nl_after_whole_file_endif = 0 # unsigned number - -# -# Positioning options -# - -# The position of arithmetic operators in wrapped expressions. -pos_arith = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of assignment in wrapped expressions. Do not affect '=' -# followed by '{'. -pos_assign = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of Boolean operators in wrapped expressions. -pos_bool = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of comparison operators in wrapped expressions. -pos_compare = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of conditional operators, as in the '?' and ':' of -# 'expr ? stmt : stmt', in wrapped expressions. -pos_conditional = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in wrapped expressions. -pos_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in enum entries. -pos_enum_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in the base class list if there is more than one -# line. Affects nl_class_init_args. -pos_class_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of the comma in the constructor initialization list. -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_colon. -pos_constr_comma = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of trailing/leading class colon, between class and base class -# list. Affects nl_class_colon. -pos_class_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of colons between constructor and member initialization. -# Related to nl_constr_colon, nl_constr_init_args and pos_constr_comma. -pos_constr_colon = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# The position of shift operators in wrapped expressions. -pos_shift = ignore # ignore/break/force/lead/trail/join/lead_break/lead_force/trail_break/trail_force - -# -# Line splitting options -# - -# Try to limit code width to N columns. -code_width = 0 # unsigned number - -# Whether to fully split long 'for' statements at semi-colons. -ls_for_split_full = false # true/false - -# Whether to fully split long function prototypes/calls at commas. -# The option ls_code_width has priority over the option ls_func_split_full. -ls_func_split_full = false # true/false - -# Whether to split lines as close to code_width as possible and ignore some -# groupings. -# The option ls_code_width has priority over the option ls_func_split_full. -ls_code_width = false # true/false - -# -# Code alignment options (not left column spaces/tabs) -# - -# Whether to keep non-indenting tabs. -align_keep_tabs = false # true/false - -# Whether to use tabs for aligning. -align_with_tabs = false # true/false - -# Whether to bump out to the next tab when aligning. -align_on_tabstop = false # true/false - -# Whether to right-align numbers. -align_number_right = false # true/false - -# Whether to keep whitespace not required for alignment. -align_keep_extra_space = false # true/false - -# Whether to align variable definitions in prototypes and functions. -align_func_params = false # true/false - -# The span for aligning parameter definitions in function on parameter name. -# -# 0: Don't align (default). -align_func_params_span = 0 # unsigned number - -# The threshold for aligning function parameter definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_func_params_thresh = 0 # number - -# The gap for aligning function parameter definitions. -align_func_params_gap = 0 # unsigned number - -# The span for aligning constructor value. -# -# 0: Don't align (default). -align_constr_value_span = 0 # unsigned number - -# The threshold for aligning constructor value. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_constr_value_thresh = 0 # number - -# The gap for aligning constructor value. -align_constr_value_gap = 0 # unsigned number - -# Whether to align parameters in single-line functions that have the same -# name. The function names must already be aligned with each other. -align_same_func_call_params = false # true/false - -# The span for aligning function-call parameters for single line functions. -# -# 0: Don't align (default). -align_same_func_call_params_span = 0 # unsigned number - -# The threshold for aligning function-call parameters for single line -# functions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_same_func_call_params_thresh = 0 # number - -# The span for aligning variable definitions. -# -# 0: Don't align (default). -align_var_def_span = 0 # unsigned number - -# How to consider (or treat) the '*' in the alignment of variable definitions. -# -# 0: Part of the type 'void * foo;' (default) -# 1: Part of the variable 'void *foo;' -# 2: Dangling 'void *foo;' -# Dangling: the '*' will not be taken into account when aligning. -align_var_def_star_style = 0 # unsigned number - -# How to consider (or treat) the '&' in the alignment of variable definitions. -# -# 0: Part of the type 'long & foo;' (default) -# 1: Part of the variable 'long &foo;' -# 2: Dangling 'long &foo;' -# Dangling: the '&' will not be taken into account when aligning. -align_var_def_amp_style = 0 # unsigned number - -# The threshold for aligning variable definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_var_def_thresh = 0 # number - -# The gap for aligning variable definitions. -align_var_def_gap = 0 # unsigned number - -# Whether to align the colon in struct bit fields. -align_var_def_colon = false # true/false - -# The gap for aligning the colon in struct bit fields. -align_var_def_colon_gap = 0 # unsigned number - -# Whether to align any attribute after the variable name. -align_var_def_attribute = false # true/false - -# Whether to align inline struct/enum/union variable definitions. -align_var_def_inline = false # true/false - -# The span for aligning on '=' in assignments. -# -# 0: Don't align (default). -align_assign_span = 0 # unsigned number - -# The span for aligning on '=' in function prototype modifier. -# -# 0: Don't align (default). -align_assign_func_proto_span = 0 # unsigned number - -# The threshold for aligning on '=' in assignments. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_assign_thresh = 0 # number - -# How to apply align_assign_span to function declaration "assignments", i.e. -# 'virtual void foo() = 0' or '~foo() = {default|delete}'. -# -# 0: Align with other assignments (default) -# 1: Align with each other, ignoring regular assignments -# 2: Don't align -align_assign_decl_func = 0 # unsigned number - -# The span for aligning on '=' in enums. -# -# 0: Don't align (default). -align_enum_equ_span = 0 # unsigned number - -# The threshold for aligning on '=' in enums. -# Use a negative number for absolute thresholds. -# -# 0: no limit (default). -align_enum_equ_thresh = 0 # number - -# The span for aligning class member definitions. -# -# 0: Don't align (default). -align_var_class_span = 0 # unsigned number - -# The threshold for aligning class member definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_var_class_thresh = 0 # number - -# The gap for aligning class member definitions. -align_var_class_gap = 0 # unsigned number - -# The span for aligning struct/union member definitions. -# -# 0: Don't align (default). -align_var_struct_span = 0 # unsigned number - -# The threshold for aligning struct/union member definitions. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_var_struct_thresh = 0 # number - -# The gap for aligning struct/union member definitions. -align_var_struct_gap = 0 # unsigned number - -# The span for aligning struct initializer values. -# -# 0: Don't align (default). -align_struct_init_span = 0 # unsigned number - -# The span for aligning single-line typedefs. -# -# 0: Don't align (default). -align_typedef_span = 0 # unsigned number - -# The minimum space between the type and the synonym of a typedef. -align_typedef_gap = 0 # unsigned number - -# How to align typedef'd functions with other typedefs. -# -# 0: Don't mix them at all (default) -# 1: Align the open parenthesis with the types -# 2: Align the function type name with the other type names -align_typedef_func = 0 # unsigned number - -# How to consider (or treat) the '*' in the alignment of typedefs. -# -# 0: Part of the typedef type, 'typedef int * pint;' (default) -# 1: Part of type name: 'typedef int *pint;' -# 2: Dangling: 'typedef int *pint;' -# Dangling: the '*' will not be taken into account when aligning. -align_typedef_star_style = 0 # unsigned number - -# How to consider (or treat) the '&' in the alignment of typedefs. -# -# 0: Part of the typedef type, 'typedef int & intref;' (default) -# 1: Part of type name: 'typedef int &intref;' -# 2: Dangling: 'typedef int &intref;' -# Dangling: the '&' will not be taken into account when aligning. -align_typedef_amp_style = 0 # unsigned number - -# The span for aligning comments that end lines. -# -# 0: Don't align (default). -align_right_cmt_span = 0 # unsigned number - -# Minimum number of columns between preceding text and a trailing comment in -# order for the comment to qualify for being aligned. Must be non-zero to have -# an effect. -align_right_cmt_gap = 0 # unsigned number - -# If aligning comments, whether to mix with comments after '}' and #endif with -# less than three spaces before the comment. -align_right_cmt_mix = false # true/false - -# Whether to only align trailing comments that are at the same brace level. -align_right_cmt_same_level = false # true/false - -# Minimum column at which to align trailing comments. Comments which are -# aligned beyond this column, but which can be aligned in a lesser column, -# may be "pulled in". -# -# 0: Ignore (default). -align_right_cmt_at_col = 0 # unsigned number - -# The span for aligning function prototypes. -# -# 0: Don't align (default). -align_func_proto_span = 0 # unsigned number - -# The threshold for aligning function prototypes. -# Use a negative number for absolute thresholds. -# -# 0: No limit (default). -align_func_proto_thresh = 0 # number - -# Minimum gap between the return type and the function name. -align_func_proto_gap = 0 # unsigned number - -# Whether to align function prototypes on the 'operator' keyword instead of -# what follows. -align_on_operator = false # true/false - -# Whether to mix aligning prototype and variable declarations. If true, -# align_var_def_XXX options are used instead of align_func_proto_XXX options. -align_mix_var_proto = false # true/false - -# Whether to align single-line functions with function prototypes. -# Uses align_func_proto_span. -align_single_line_func = false # true/false - -# Whether to align the open brace of single-line functions. -# Requires align_single_line_func=true. Uses align_func_proto_span. -align_single_line_brace = false # true/false - -# Gap for align_single_line_brace. -align_single_line_brace_gap = 0 # unsigned number - -# (OC) The span for aligning Objective-C message specifications. -# -# 0: Don't align (default). -align_oc_msg_spec_span = 0 # unsigned number - -# Whether to align macros wrapped with a backslash and a newline. This will -# not work right if the macro contains a multi-line comment. -align_nl_cont = false # true/false - -# Whether to align macro functions and variables together. -align_pp_define_together = false # true/false - -# The span for aligning on '#define' bodies. -# -# =0: Don't align (default) -# >0: Number of lines (including comments) between blocks -align_pp_define_span = 0 # unsigned number - -# The minimum space between label and value of a preprocessor define. -align_pp_define_gap = 0 # unsigned number - -# Whether to align lines that start with '<<' with previous '<<'. -# -# Default: true -align_left_shift = true # true/false - -# Whether to align comma-separated statements following '<<' (as used to -# initialize Eigen matrices). -align_eigen_comma_init = false # true/false - -# Whether to align text after 'asm volatile ()' colons. -align_asm_colon = false # true/false - -# (OC) Span for aligning parameters in an Objective-C message call -# on the ':'. -# -# 0: Don't align. -align_oc_msg_colon_span = 0 # unsigned number - -# (OC) Whether to always align with the first parameter, even if it is too -# short. -align_oc_msg_colon_first = false # true/false - -# (OC) Whether to align parameters in an Objective-C '+' or '-' declaration -# on the ':'. -align_oc_decl_colon = false # true/false - -# (OC) Whether to not align parameters in an Objectve-C message call if first -# colon is not on next line of the message call (the same way Xcode does -# aligment) -align_oc_msg_colon_xcode_like = false # true/false - -# -# Comment modification options -# - -# Try to wrap comments at N columns. -cmt_width = 0 # unsigned number - -# How to reflow comments. -# -# 0: No reflowing (apart from the line wrapping due to cmt_width) (default) -# 1: No touching at all -# 2: Full reflow -cmt_reflow_mode = 0 # unsigned number - -# Whether to convert all tabs to spaces in comments. If false, tabs in -# comments are left alone, unless used for indenting. -cmt_convert_tab_to_spaces = true # true/false - -# Whether to apply changes to multi-line comments, including cmt_width, -# keyword substitution and leading chars. -# -# Default: true -cmt_indent_multi = true # true/false - -# Whether to group c-comments that look like they are in a block. -cmt_c_group = false # true/false - -# Whether to put an empty '/*' on the first line of the combined c-comment. -cmt_c_nl_start = false # true/false - -# Whether to add a newline before the closing '*/' of the combined c-comment. -cmt_c_nl_end = false # true/false - -# Whether to change cpp-comments into c-comments. -cmt_cpp_to_c = false # true/false - -# Whether to group cpp-comments that look like they are in a block. Only -# meaningful if cmt_cpp_to_c=true. -cmt_cpp_group = false # true/false - -# Whether to put an empty '/*' on the first line of the combined cpp-comment -# when converting to a c-comment. -# -# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. -cmt_cpp_nl_start = false # true/false - -# Whether to add a newline before the closing '*/' of the combined cpp-comment -# when converting to a c-comment. -# -# Requires cmt_cpp_to_c=true and cmt_cpp_group=true. -cmt_cpp_nl_end = false # true/false - -# Whether to put a star on subsequent comment lines. -cmt_star_cont = false # true/false - -# The number of spaces to insert at the start of subsequent comment lines. -cmt_sp_before_star_cont = 0 # unsigned number - -# The number of spaces to insert after the star on subsequent comment lines. -cmt_sp_after_star_cont = 0 # unsigned number - -# For multi-line comments with a '*' lead, remove leading spaces if the first -# and last lines of the comment are the same length. -# -# Default: true -cmt_multi_check_last = true # true/false - -# For multi-line comments with a '*' lead, remove leading spaces if the first -# and last lines of the comment are the same length AND if the length is -# bigger as the first_len minimum. -# -# Default: 4 -cmt_multi_first_len_minimum = 4 # unsigned number - -# Path to a file that contains text to insert at the beginning of a file if -# the file doesn't start with a C/C++ comment. If the inserted text contains -# '$(filename)', that will be replaced with the current file's name. -cmt_insert_file_header = "" # string - -# Path to a file that contains text to insert at the end of a file if the -# file doesn't end with a C/C++ comment. If the inserted text contains -# '$(filename)', that will be replaced with the current file's name. -cmt_insert_file_footer = "" # string - -# Path to a file that contains text to insert before a function definition if -# the function isn't preceded by a C/C++ comment. If the inserted text -# contains '$(function)', '$(javaparam)' or '$(fclass)', these will be -# replaced with, respectively, the name of the function, the javadoc '@param' -# and '@return' stuff, or the name of the class to which the member function -# belongs. -cmt_insert_func_header = "" # string - -# Path to a file that contains text to insert before a class if the class -# isn't preceded by a C/C++ comment. If the inserted text contains '$(class)', -# that will be replaced with the class name. -cmt_insert_class_header = "" # string - -# Path to a file that contains text to insert before an Objective-C message -# specification, if the method isn't preceded by a C/C++ comment. If the -# inserted text contains '$(message)' or '$(javaparam)', these will be -# replaced with, respectively, the name of the function, or the javadoc -# '@param' and '@return' stuff. -cmt_insert_oc_msg_header = "" # string - -# Whether a comment should be inserted if a preprocessor is encountered when -# stepping backwards from a function name. -# -# Applies to cmt_insert_oc_msg_header, cmt_insert_func_header and -# cmt_insert_class_header. -cmt_insert_before_preproc = false # true/false - -# Whether a comment should be inserted if a function is declared inline to a -# class definition. -# -# Applies to cmt_insert_func_header. -# -# Default: true -cmt_insert_before_inlines = true # true/false - -# Whether a comment should be inserted if the function is a class constructor -# or destructor. -# -# Applies to cmt_insert_func_header. -cmt_insert_before_ctor_dtor = false # true/false - -# -# Code modifying options (non-whitespace) -# - -# Add or remove braces on a single-line 'do' statement. -mod_full_brace_do = ignore # ignore/add/remove/force - -# Add or remove braces on a single-line 'for' statement. -mod_full_brace_for = ignore # ignore/add/remove/force - -# (Pawn) Add or remove braces on a single-line function definition. -mod_full_brace_function = ignore # ignore/add/remove/force - -# Add or remove braces on a single-line 'if' statement. Braces will not be -# removed if the braced statement contains an 'else'. -mod_full_brace_if = ignore # ignore/add/remove/force - -# Whether to enforce that all blocks of an 'if'/'else if'/'else' chain either -# have, or do not have, braces. If true, braces will be added if any block -# needs braces, and will only be removed if they can be removed from all -# blocks. -# -# Overrides mod_full_brace_if. -mod_full_brace_if_chain = false # true/false - -# Whether to add braces to all blocks of an 'if'/'else if'/'else' chain. -# If true, mod_full_brace_if_chain will only remove braces from an 'if' that -# does not have an 'else if' or 'else'. -mod_full_brace_if_chain_only = false # true/false - -# Add or remove braces on single-line 'while' statement. -mod_full_brace_while = ignore # ignore/add/remove/force - -# Add or remove braces on single-line 'using ()' statement. -mod_full_brace_using = ignore # ignore/add/remove/force - -# Don't remove braces around statements that span N newlines -mod_full_brace_nl = 0 # unsigned number - -# Whether to prevent removal of braces from 'if'/'for'/'while'/etc. blocks -# which span multiple lines. -# -# Affects: -# mod_full_brace_for -# mod_full_brace_if -# mod_full_brace_if_chain -# mod_full_brace_if_chain_only -# mod_full_brace_while -# mod_full_brace_using -# -# Does not affect: -# mod_full_brace_do -# mod_full_brace_function -mod_full_brace_nl_block_rem_mlcond = false # true/false - -# Add or remove unnecessary parenthesis on 'return' statement. -mod_paren_on_return = ignore # ignore/add/remove/force - -# (Pawn) Whether to change optional semicolons to real semicolons. -mod_pawn_semicolon = false # true/false - -# Whether to fully parenthesize Boolean expressions in 'while' and 'if' -# statement, as in 'if (a && b > c)' => 'if (a && (b > c))'. -mod_full_paren_if_bool = false # true/false - -# Whether to remove superfluous semicolons. -mod_remove_extra_semicolon = false # true/false - -# If a function body exceeds the specified number of newlines and doesn't have -# a comment after the close brace, a comment will be added. -mod_add_long_function_closebrace_comment = 0 # unsigned number - -# If a namespace body exceeds the specified number of newlines and doesn't -# have a comment after the close brace, a comment will be added. -mod_add_long_namespace_closebrace_comment = 0 # unsigned number - -# If a class body exceeds the specified number of newlines and doesn't have a -# comment after the close brace, a comment will be added. -mod_add_long_class_closebrace_comment = 0 # unsigned number - -# If a switch body exceeds the specified number of newlines and doesn't have a -# comment after the close brace, a comment will be added. -mod_add_long_switch_closebrace_comment = 0 # unsigned number - -# If an #ifdef body exceeds the specified number of newlines and doesn't have -# a comment after the #endif, a comment will be added. -mod_add_long_ifdef_endif_comment = 0 # unsigned number - -# If an #ifdef or #else body exceeds the specified number of newlines and -# doesn't have a comment after the #else, a comment will be added. -mod_add_long_ifdef_else_comment = 0 # unsigned number - -# Whether to take care of the case by the mod_sort_xx options. -mod_sort_case_sensitive = false # true/false - -# Whether to sort consecutive single-line 'import' statements. -mod_sort_import = false # true/false - -# (C#) Whether to sort consecutive single-line 'using' statements. -mod_sort_using = false # true/false - -# Whether to sort consecutive single-line '#include' statements (C/C++) and -# '#import' statements (Objective-C). Be aware that this has the potential to -# break your code if your includes/imports have ordering dependencies. -mod_sort_include = false # true/false - -# Whether to prioritize '#include' and '#import' statements that contain -# filename without extension when sorting is enabled. -mod_sort_incl_import_prioritize_filename = false # true/false - -# Whether to prioritize '#include' and '#import' statements that does not -# contain extensions when sorting is enabled. -mod_sort_incl_import_prioritize_extensionless = false # true/false - -# Whether to prioritize '#include' and '#import' statements that contain -# angle over quotes when sorting is enabled. -mod_sort_incl_import_prioritize_angle_over_quotes = false # true/false - -# Whether to ignore file extension in '#include' and '#import' statements -# for sorting comparison. -mod_sort_incl_import_ignore_extension = false # true/false - -# Whether to group '#include' and '#import' statements when sorting is enabled. -mod_sort_incl_import_grouping_enabled = false # true/false - -# Whether to move a 'break' that appears after a fully braced 'case' before -# the close brace, as in 'case X: { ... } break;' => 'case X: { ... break; }'. -mod_move_case_break = false # true/false - -# Add or remove braces around a fully braced case statement. Will only remove -# braces if there are no variable declarations in the block. -mod_case_brace = ignore # ignore/add/remove/force - -# Whether to remove a void 'return;' that appears as the last statement in a -# function. -mod_remove_empty_return = false # true/false - -# Add or remove the comma after the last value of an enumeration. -mod_enum_last_comma = ignore # ignore/add/remove/force - -# (OC) Whether to organize the properties. If true, properties will be -# rearranged according to the mod_sort_oc_property_*_weight factors. -mod_sort_oc_properties = false # true/false - -# (OC) Weight of a class property modifier. -mod_sort_oc_property_class_weight = 0 # number - -# (OC) Weight of 'atomic' and 'nonatomic'. -mod_sort_oc_property_thread_safe_weight = 0 # number - -# (OC) Weight of 'readwrite' when organizing properties. -mod_sort_oc_property_readwrite_weight = 0 # number - -# (OC) Weight of a reference type specifier ('retain', 'copy', 'assign', -# 'weak', 'strong') when organizing properties. -mod_sort_oc_property_reference_weight = 0 # number - -# (OC) Weight of getter type ('getter=') when organizing properties. -mod_sort_oc_property_getter_weight = 0 # number - -# (OC) Weight of setter type ('setter=') when organizing properties. -mod_sort_oc_property_setter_weight = 0 # number - -# (OC) Weight of nullability type ('nullable', 'nonnull', 'null_unspecified', -# 'null_resettable') when organizing properties. -mod_sort_oc_property_nullability_weight = 0 # number - -# -# Preprocessor options -# - -# Add or remove indentation of preprocessor directives inside #if blocks -# at brace level 0 (file-level). -pp_indent = ignore # ignore/add/remove/force - -# Whether to indent #if/#else/#endif at the brace level. If false, these are -# indented from column 1. -pp_indent_at_level = false # true/false - -# Specifies the number of columns to indent preprocessors per level -# at brace level 0 (file-level). If pp_indent_at_level=false, also specifies -# the number of columns to indent preprocessors per level -# at brace level > 0 (function-level). -# -# Default: 1 -pp_indent_count = 1 # unsigned number - -# Add or remove space after # based on pp_level of #if blocks. -pp_space = ignore # ignore/add/remove/force - -# Sets the number of spaces per level added with pp_space. -pp_space_count = 0 # unsigned number - -# The indent for '#region' and '#endregion' in C# and '#pragma region' in -# C/C++. Negative values decrease indent down to the first column. -pp_indent_region = 0 # number - -# Whether to indent the code between #region and #endregion. -pp_region_indent_code = false # true/false - -# If pp_indent_at_level=true, sets the indent for #if, #else and #endif when -# not at file-level. Negative values decrease indent down to the first column. -# -# =0: Indent preprocessors using output_tab_size -# >0: Column at which all preprocessors will be indented -pp_indent_if = 0 # number - -# Whether to indent the code between #if, #else and #endif. -pp_if_indent_code = false # true/false - -# Whether to indent '#define' at the brace level. If false, these are -# indented from column 1. -pp_define_at_level = false # true/false - -# Whether to ignore the '#define' body while formatting. -pp_ignore_define_body = false # true/false - -# Whether to indent case statements between #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the case statements -# directly inside of. -# -# Default: true -pp_indent_case = true # true/false - -# Whether to indent whole function definitions between #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the function definition -# is directly inside of. -# -# Default: true -pp_indent_func_def = true # true/false - -# Whether to indent extern C blocks between #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the extern block is -# directly inside of. -# -# Default: true -pp_indent_extern = true # true/false - -# Whether to indent braces directly inside #if, #else, and #endif. -# Only applies to the indent of the preprocesser that the braces are directly -# inside of. -# -# Default: true -pp_indent_brace = true # true/false - -# -# Sort includes options -# - -# The regex for include category with priority 0. -include_category_0 = "" # string - -# The regex for include category with priority 1. -include_category_1 = "" # string - -# The regex for include category with priority 2. -include_category_2 = "" # string - -# -# Use or Do not Use options -# - -# true: indent_func_call_param will be used (default) -# false: indent_func_call_param will NOT be used -# -# Default: true -use_indent_func_call_param = true # true/false - -# The value of the indentation for a continuation line is calculated -# differently if the statement is: -# - a declaration: your case with QString fileName ... -# - an assignment: your case with pSettings = new QSettings( ... -# -# At the second case the indentation value might be used twice: -# - at the assignment -# - at the function call (if present) -# -# To prevent the double use of the indentation value, use this option with the -# value 'true'. -# -# true: indent_continue will be used only once -# false: indent_continue will be used every time (default) -use_indent_continue_only_once = false # true/false - -# The value might be used twice: -# - at the assignment -# - at the opening brace -# -# To prevent the double use of the indentation value, use this option with the -# value 'true'. +# To prevent the double use of the indentation value, use this option with the +# value 'true'. # # true: indentation will be used only once # false: indentation will be used every time (default) indent_cpp_lambda_only_once = true # true/false - -# Whether sp_after_angle takes precedence over sp_inside_fparen. This was the -# historic behavior, but is probably not the desired behavior, so this is off -# by default. -use_sp_after_angle_always = false # true/false - -# Whether to apply special formatting for Qt SIGNAL/SLOT macros. Essentially, -# this tries to format these so that they match Qt's normalized form (i.e. the -# result of QMetaObject::normalizedSignature), which can slightly improve the -# performance of the QObject::connect call, rather than how they would -# otherwise be formatted. -# -# See options_for_QT.cpp for details. -# -# Default: true -use_options_overriding_for_qt_macros = true # true/false - -# If true: the form feed character is removed from the list -# of whitespace characters. -# See https://en.cppreference.com/w/cpp/string/byte/isspace -use_form_feed_no_more_as_whitespace_character = false # true/false - -# -# Warn levels - 1: error, 2: warning (default), 3: note -# - -# (C#) Warning is given if doing tab-to-\t replacement and we have found one -# in a C# verbatim string literal. -# -# Default: 2 -warn_level_tabs_found_in_verbatim_string_literals = 2 # unsigned number - -# Limit the number of loops. -# Used by uncrustify.cpp to exit from infinite loop. -# 0: no limit. -debug_max_number_of_loops = 0 # number - -# Set the number of the line to protocol; -# Used in the function prot_the_line if the 2. parameter is zero. -# 0: nothing protocol. -debug_line_number_to_protocol = 0 # number - -# Set the number of second(s) before terminating formatting the current file, -# 0: no timeout. -# only for linux -debug_timeout = 0 # number - -# Meaning of the settings: -# Ignore - do not do any changes -# Add - makes sure there is 1 or more space/brace/newline/etc -# Force - makes sure there is exactly 1 space/brace/newline/etc, -# behaves like Add in some contexts -# Remove - removes space/brace/newline/etc -# -# -# - Token(s) can be treated as specific type(s) with the 'set' option: -# `set tokenType tokenString [tokenString...]` -# -# Example: -# `set BOOL __AND__ __OR__` -# -# tokenTypes are defined in src/token_enum.h, use them without the -# 'CT_' prefix: 'CT_BOOL' => 'BOOL' -# -# -# - Token(s) can be treated as type(s) with the 'type' option. -# `type tokenString [tokenString...]` -# -# Example: -# `type int c_uint_8 Rectangle` -# -# This can also be achieved with `set TYPE int c_uint_8 Rectangle` -# -# -# To embed whitespace in tokenStrings use the '\' escape character, or quote -# the tokenStrings. These quotes are supported: "'` -# -# -# - Support for the auto detection of languages through the file ending can be -# added using the 'file_ext' command. -# `file_ext langType langString [langString..]` -# -# Example: -# `file_ext CPP .ch .cxx .cpp.in` -# -# langTypes are defined in uncrusify_types.h in the lang_flag_e enum, use -# them without the 'LANG_' prefix: 'LANG_CPP' => 'CPP' -# -# -# - Custom macro-based indentation can be set up using 'macro-open', -# 'macro-else' and 'macro-close'. -# `(macro-open | macro-else | macro-close) tokenString` -# -# Example: -# `macro-open BEGIN_TEMPLATE_MESSAGE_MAP` -# `macro-open BEGIN_MESSAGE_MAP` -# `macro-close END_MESSAGE_MAP` -# -# -# option(s) with 'not default' value: 24 -# diff --git a/AUTHORS b/AUTHORS index e3610324298..be41c3c525c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,6 @@ The cppcheck team, in alphabetical order: +0x41head Abhijit Sawant Abhishek Bharadwaj Abigail Buccaneer @@ -21,12 +22,14 @@ Alexey Eryomenko Alexey Zhikhartsev Alfi Maulana Ali Can Demiralp +Allen Winter Alon Alexander Alon Liberman Ameen Ali Andreas Bacher Andreas Bießmann Andreas Grob +Andreas Lutsch Andreas Pokorny Andreas Rönnquist Andreas Vollenweider @@ -36,13 +39,16 @@ Andrew C. Martin Andrew D. Bancroft Andy Holmes Andy Maloney +Andy Mac Gregor Aneesh Azhakesan S Ankita Gupta +anoymouserver Anton Lindqvist Antti Tuppurainen Anurag Garg Armin Müller Arpit Chaudhary +Artemis Meursault Gerrard August Sodora Ayaz Salikhov Balázs Tóth @@ -60,6 +66,7 @@ Ben T Bernd Buschinski Bill Egert Björge Dijkstra +Björn Blissing booga Boris Barbulovski Boris Egorov @@ -71,11 +78,15 @@ Carl Morgan Carlo Marcelo Arenas Belón Carlos Gomes Martinho Carl-Oskar Larsson +Cary Converse Cary R +Caspar Kielwein Changkyoon Kim Chris Lalancette Christian Ehrlicher Christian Franke +Christian Göttsche +Christoph Grüninger Christoph Schmidt Christoph Strehle Chuck Larson @@ -92,17 +103,21 @@ David Korth Dávid Slivka Debrard Sebastien Deepak Gupta +Degen's Regens dencat Diego de las Heras Dirk Jagdmann +Dirk Mueller Dmitriy Dmitry Marakasov Dmitry-Me +dsamo Duraffort Edoardo Prezioso Eivind Tagseth Elbert Pol Emmanuel Blot +Eric Lemanissier Eric Malenfant Eric Sesterhenn Erik Hovland @@ -110,12 +125,17 @@ Erik Lax Ettl Martin Even Rouault Evgeny Mandrikov +feelamee Felipe Pena +Felix Faber Felix Geyer Felix Passenberg Felix Wolff Florin Iucha +flovent Francesc Elies +François Berder +Frank Winklmeier Frank Zingsheim Frederik Schwarzer fu7mu4 @@ -132,6 +152,7 @@ Gerik Rhoden Gianfranco Costamagna Gianluca Scacco Gleydson Soares +Goncalo Mao-Cheia Goran Džaferi Graham Whitted Greg Hewgill @@ -150,6 +171,7 @@ He Yuqi Hoang Tuan Su Igor Rondarev Igor Zhukov +Ilya Shipitsin Ivan Maidanski Iván Matellanes Ivan Ryabov @@ -168,6 +190,8 @@ Jesse Boswell Jim Kuhn Jim Zhou jlguardi +Joel Johnson +Johan Bertrand Johan Samuelson John Marshall John-Paul Ore @@ -188,12 +212,14 @@ Jussi Lehtola Jørgen Kvalsvik Kamil Dudka Kartik Bajaj +Kefu Chai keinflue Ken-Patrick Lehrmann Ketil Skjerve Kevin Christian Kevin Kendzia Kimmo Varis +Kitsios Konstantinos Kleber Tarcísio Konrad Grochowski Konrad Windszus @@ -204,6 +230,7 @@ Lars Even Almaas larudwer Lau bakman Lauri Nurmi +Leander Schulten Leandro Lisboa Penz Leila F. Rahman Lena Herscheid @@ -212,11 +239,15 @@ Lieven de Cock lioncash Lionel Gimbert Lucas Manuel Rodriguez +Ludvig Gunne Lindström Luis Díaz Más +Luís Pereira Lukas Grützmacher +Lukas Hiesmayr Lukasz Czajczyk Łukasz Jankowski Luxon Jean-Pierre +Maarten van der Schrieck Maksim Derbasov Malcolm Parsons Marc-Antoine Perennou @@ -225,6 +256,7 @@ Marco Trevisan Marek Zmysłowski Marian Klymov Mark de Wever +Mark Hermeling Markus Elfring Martin Delille Martin Ettl @@ -235,6 +267,7 @@ Márton Csordás Masafumi Koba Massimo Paladin Mateusz Michalak +Mateusz Patyk Mateusz Pusz Mathias De Maré Mathias Schmid @@ -244,6 +277,7 @@ Matthias Schmieder Matt Johnson Maurice Gilden Mavik +Melroy van den Berg Michael Drake Michael Løiten Miika-Petteri Matikainen @@ -266,6 +300,8 @@ Nicolás Alvarez Nicolas Le Cam Nilesh Kumar Ogawa KenIchi +Ola Söder +Oleksandr Labetskyi Oleksandr Redko Oliver Schode Oliver Stöneberg @@ -283,8 +319,10 @@ Pavol Misik Pete Johns Peter Pentchev Peter Schops +Philip Chimento Philipp Kloke Pierre Schweitzer +Pieter Duchi Pino Toscano Pranav Khanna Radek Jarecki @@ -293,6 +331,7 @@ Ramzan Bekbulatov Raphael Geissert Razvan Ioan Alexe Reijo Tomperi +Reshma V Kumar Rainer Wiesenfarth Riccardo Ghetta Richard A. Smith @@ -304,6 +343,7 @@ Robert Habrich Robert Morin Roberto Martelloni Robert Reif +Robin Getz rofl0r Roman Zaytsev Borisovich Ronald Hiemstra @@ -311,13 +351,17 @@ root Rosen Penev Rudi Danner Rudolf Grauberger +Ryan M. Lederman Ryan Pavlik Samir Aguiar Sam Truscott Samuel Degrande +Samuel Poláček Sandeep Dutta Savvas Etairidis +Scott Ehlert Scott Furry +Seafarix Ltd. Sebastian Held Sebastian Matuschka Sébastien Debrard @@ -325,6 +369,7 @@ Sergei Chernykh Sergei Trofimovich Sergey Burgsdorf Shane Tapp +Shohei YOSHIDA Simon Cornell Simon Kagstrom Simon Large @@ -343,35 +388,47 @@ Steve Duan Steve Mokris Steven Cook Steven Myint +Sune Stolborg Vuorela Susi Lehtola +Sven Wienand Swasti Shrivastava Sylvain Joubert Tam Do Thanh Teddy Didé +Temuri Doghonadze Thomas Arnhold +Tomasz Edward Posluszny Thomas Jarosch Thomas Niederberger Thomas Otto Thomas P. K. Healy Thomas Sondergaard Thorsten Sick +Tim Blume Tim Gerundt tititiou36 +Tobias Weber Tobias Weibel Tomasz Kłoczko Tom Pollok Tomo Dote +Tommy Bergman Toralf Förster Troshin V.S. Tyson Nottingham +Usman Majid +Valentin Batz Valerii Lashmanov Vasily Maslyukov Veli-Matti Visuri -WenChung Chiu Vesa Pikki Ville-Pekka Vahteala Ville Skyttä Vincent Le Garrec +Vladimir Petrigo +Wang Haoyu +Wang Yang +WenChung Chiu Wolfgang Stöggl x29a XhmikosR diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b76fbf81dd..3595154f7ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,28 +1,31 @@ -cmake_minimum_required(VERSION 2.8.12) -project(Cppcheck) +cmake_minimum_required(VERSION 3.13) +project(Cppcheck VERSION 2.18.99 LANGUAGES CXX) + +include(cmake/options.cmake) include(cmake/cxx11.cmake) use_cxx11() +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(GNUInstallDirs) -include(cmake/ccache.cmake) include(cmake/compilerCheck.cmake) include(cmake/versions.cmake) -include(cmake/options.cmake) include(cmake/findDependencies.cmake) include(cmake/compileroptions.cmake) include(cmake/compilerDefinitions.cmake) include(cmake/buildFiles.cmake) -include(cmake/printInfo.cmake) if(BUILD_GUI) include(cmake/qtCompat.cmake) endif() +include(cmake/printInfo.cmake) -file(GLOB addons "addons/*.py") +file(GLOB addons_py "addons/*.py") +file(GLOB addons_json "addons/*.json") file(GLOB cfgs "cfg/*.cfg") file(GLOB platforms "platforms/*.xml") @@ -44,16 +47,18 @@ if(LIBXML2_XMLLINT_EXECUTABLE) add_dependencies(validatePlatforms validatePlatforms-${platformname}) endforeach() - add_custom_target(errorlist-xml $ --errorlist > ${CMAKE_BINARY_DIR}/errorlist.xml - DEPENDS cppcheck) + if(TARGET cppcheck) + add_custom_target(errorlist-xml $ --errorlist > ${CMAKE_BINARY_DIR}/errorlist.xml + DEPENDS cppcheck) - add_custom_target(example-xml $ --xml --enable=all --inconclusive --max-configs=1 ${CMAKE_SOURCE_DIR}/samples 2> ${CMAKE_BINARY_DIR}/example.xml - DEPENDS cppcheck) + add_custom_target(example-xml $ --xml --enable=all --inconclusive --max-configs=1 ${CMAKE_SOURCE_DIR}/samples 2> ${CMAKE_BINARY_DIR}/example.xml + DEPENDS cppcheck) + endif() add_custom_target(createXMLExamples DEPENDS errorlist-xml example-xml) - if(PYTHON_EXECUTABLE) - add_custom_target(checkCWEEntries ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/listErrorsWithoutCWE.py -F ${CMAKE_BINARY_DIR}/errorlist.xml + if(Python_EXECUTABLE) + add_custom_target(checkCWEEntries ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/listErrorsWithoutCWE.py -F ${CMAKE_BINARY_DIR}/errorlist.xml DEPENDS errorlist-xml) endif() @@ -66,6 +71,12 @@ if(LIBXML2_XMLLINT_EXECUTABLE) add_custom_target(validateRules ${LIBXML2_XMLLINT_EXECUTABLE} --noout ${CMAKE_SOURCE_DIR}/rules/*.xml) endif() +# TODO: add the following Makefile features: +# - "man/cppcheck.1" target +# - "tags" target +# - Cygwin handling +# - MinGW handling + if(BUILD_TESTS) enable_testing() endif() @@ -75,14 +86,22 @@ add_custom_target(copy_cfg ALL "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/cfg" COMMENT "Copying cfg files to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}") +# TODO: copy *.py and *.json only add_custom_target(copy_addons ALL ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/addons" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/addons" COMMENT "Copying addons files to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}") +add_custom_target(remove_unsigned_platforms ALL + ${CMAKE_COMMAND} -E remove -f + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/platforms/unix32-unsigned.xml" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/platforms/unix64-unsigned.xml" + COMMENT "Removing unsigned platforms files from ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}") + add_custom_target(copy_platforms ALL ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/platforms" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/platforms" + DEPENDS remove_unsigned_platforms COMMENT "Copying platforms files to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}") if(USE_BUNDLED_TINYXML2) @@ -90,11 +109,13 @@ if(USE_BUNDLED_TINYXML2) add_subdirectory(externals/tinyxml2) endif() add_subdirectory(externals/simplecpp) +add_subdirectory(externals/picojson) add_subdirectory(lib) # CppCheck Library +add_subdirectory(frontend) add_subdirectory(cli) # Client application add_subdirectory(test) # Tests add_subdirectory(gui) # Graphical application -add_subdirectory(tools/triage) # Triage tool add_subdirectory(tools) +add_subdirectory(man) include(cmake/clang_tidy.cmake) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..715a913b6fc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,67 @@ +# Contributing To Cppcheck + +These are some guidelines *any* contributor should follow. They will help to make for better contributions which will most likely allow for them to be processed. + +(TODO: move daca@home section here?) + +## Code Changes + +Code contributions are handled via GitHub pull requests: https://github.com/danmar/cppcheck/pulls. + +If you file a pull request you might not get a reply immediately. We are a very small team and it might not fit in the current scope or time. + +Any kind of contribution is welcome but we might reject it. In that case we usually provide an explanation for the reasons but everything is always open to discussion. + +Changes in the `externals` folder need to be submitted to the respective upstream projects and will be pulled downstream with their next stable release (`picojson` is an exception because it is no longer maintained - the handling of such changes is not yet determined - see also https://trac.cppcheck.net/ticket/12233). + +Also after you filed a pull request please be ready to reply to questions and feedback. If you just "dump and leave" it might lower the chances of your change being accepted. This also applies after the PR was successfully merged as it might cause issues which were not exposed by the CI. + +Please do not be discouraged if your change was rejected or if the review process might not have been as smooth as it could have been. + +Each change should be accompanied with a unit ([C++](https://github.com/danmar/cppcheck/tree/main/test)) or integration ([Python](https://github.com/danmar/cppcheck/tree/main/test/cli)) test to ensure that it doesn't regress with future changes. Negative tests (testing the opposite behavior) would be favorable but might not be required or might already exist depending on the change. Tests which introduce `TODO_ASSERT_` or `@pytest.mark.skip`/`@pytest.mark.xfail` should have tickets filed. + +If the change is modifying existing behavior (i.e. adding a feature or fixing a bug) it should be accompanied by an issue in the [tracker](https://trac.cppcheck.net) (if you do not have access we can assist with that). Depending on the change it might also warrant an entry in `releasenotes.txt`. + +The CI is already doing a lot of work but there are certain parts it cannot ensure. + +(TODO: mention test_pr.py) + +The CI has an "always green" approach which means that failing tests are not allowed. Flakey tests might be acceptable depending on the frequency of their failures but they should be accompanied by ticket so they are being tracked. If introduce a test which is expected to fail you should use the `TODO_*` macros (C++) or `@pytest.mark.xfail(strict=False)` annotations. + +Note: Usually you can run the CI on your own fork to verify that it passes before even open an PR. Unfortunately some changes to avoid duplicated builds in our CI disabled this (TODO: file a ticket about this). + +### Targets + +Cppcheck is tracking its issues at https://trac.cppcheck.net. + +The tickets are not really prioritized (except for non-synthetic crashing issues) but of most interest are the following types of tickets. + +[False Positives](https://trac.cppcheck.net/query?status=accepted&status=assigned&status=new&status=reopened&component=False+positive&col=id&col=summary&col=status&col=component&col=type&col=priority&col=milestone&order=priority) + +Since Cppcheck aims to be low on false positives, these kind of issues are obviously of the highest priority. + +[Detection Regressions](https://trac.cppcheck.net/query?status=accepted&status=assigned&status=new&status=reopened&keywords=~regression&component=Improve+check&col=id&col=summary&col=status&col=type&col=priority&col=milestone&col=component&order=priority) + +Changes might lead to fewer findings being reported. In very few cases this might be intentional but we should not regress in what findings are being reported. + +[Other Defects](https://trac.cppcheck.net/query?status=accepted&status=assigned&status=new&status=reopened&type=defect&component=!False+positive&col=id&col=summary&col=type&col=status&col=component&col=priority&col=milestone&order=priority) + +Note: If you start working on ticket, please assign yourself or request to be. + +## Source TODOs + +There are also various source-level TODOs. These might be related to already tracked issues (even if not explicitly noted) but may also be just exist exploratively, have even been added overzealously or might even be outdated. + +So if you start spending a lot of time on these, you might want to get into touch before proceeding further. + +## simplecpp + +At its core Cppcheck is relying on the `simplecpp` library which is a preprocessor implementation which was spun off into its [separate project](https://github.com/danmar/simplecpp) with its own [bug tracker](https://github.com/danmar/simplecpp/issues). This is also maintained by the Cppcheck developers and contributions to it are also welcome. + +## Translations + +We are also maintaining various translations for `cppcheck-gui`. + +Several of these are not complete or might be out-of-date so contributions are welcome. We will also accept additional languages but such contributions should be complete. + +(TODO: provide more details) diff --git a/Makefile b/Makefile index 81e18beca52..d5e3f74f6d1 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,13 @@ -# This file is generated by tools/dmake, do not edit. +# This file is generated by dmake, do not edit. ifndef VERBOSE VERBOSE= endif # To compile with rules, use 'make HAVE_RULES=yes' ifndef HAVE_RULES - HAVE_RULES=no + HAVE_RULES= endif -ifdef SRCDIR - $(error Usage of SRCDIR to activate match compiler has been removed. Use MATCHCOMPILER=yes instead.) -endif ifndef MATCHCOMPILER MATCHCOMPILER= endif @@ -32,8 +29,10 @@ ifeq ($(MATCHCOMPILER),yes) matchcompiler_S := $(shell $(PYTHON_INTERPRETER) tools/matchcompiler.py) endif libcppdir:=build -else +else ifeq ($(MATCHCOMPILER),) libcppdir:=lib +else + $(error invalid MATCHCOMPILER value '$(MATCHCOMPILER)') endif ifndef CPPFLAGS @@ -41,10 +40,10 @@ ifndef CPPFLAGS endif ifdef FILESDIR - CPPFLAGS+=-DFILESDIR=\"$(FILESDIR)\" + override CPPFLAGS+=-DFILESDIR=\"$(FILESDIR)\" endif -RDYNAMIC=-rdynamic +RDYNAMIC?=-rdynamic # Set the CPPCHK_GLIBCXX_DEBUG flag. This flag is not used in release Makefiles. # The _GLIBCXX_DEBUG define doesn't work in Cygwin or other Win32 systems. ifndef COMSPEC @@ -121,10 +120,6 @@ ifdef CYGWIN $(info CYGWIN found) endif - # Set the flag to address compile time warnings - # with tinyxml2 and Cygwin. - CPPFLAGS+=-U__STRICT_ANSI__ - # Increase stack size for Cygwin builds to avoid segmentation fault in limited recursive tests. CXXFLAGS+=-Wl,--stack,8388608 endif # CYGWIN @@ -137,32 +132,33 @@ ifeq (clang++, $(findstring clang++,$(CXX))) CPPCHK_GLIBCXX_DEBUG= endif ifndef CXXFLAGS - CXXFLAGS=-pedantic -Wall -Wextra -Wcast-qual -Wno-deprecated-declarations -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-shadow -Wno-missing-field-initializers -Wno-missing-braces -Wno-sign-compare -Wno-multichar $(CPPCHK_GLIBCXX_DEBUG) -g + CXXFLAGS=-pedantic -Wall -Wextra -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wmissing-format-attribute -Wno-long-long -Wpacked -Wredundant-decls -Wundef -Wno-sign-compare -Wno-multichar -Woverloaded-virtual -g endif ifeq (g++, $(findstring g++,$(CXX))) - override CXXFLAGS += -std=gnu++0x -pipe -else ifeq (clang++, $(findstring clang++,$(CXX))) - override CXXFLAGS += -std=c++0x -else ifeq ($(CXX), c++) - ifeq ($(shell uname -s), Darwin) - override CXXFLAGS += -std=c++0x - endif + override CXXFLAGS += -pipe endif - +override CXXFLAGS += -std=c++11 ifeq ($(HAVE_RULES),yes) PCRE_CONFIG = $(shell which pcre-config) ifeq ($(PCRE_CONFIG),) $(error Did not find pcre-config) endif - override CXXFLAGS += -DHAVE_RULES -DTIXML_USE_STL $(shell $(PCRE_CONFIG) --cflags) + override CXXFLAGS += $(shell $(PCRE_CONFIG) --cflags) + override CPPFLAGS += -DHAVE_RULES ifdef LIBS LIBS += $(shell $(PCRE_CONFIG) --libs) else LIBS=$(shell $(PCRE_CONFIG) --libs) endif +else ifneq ($(HAVE_RULES),) + $(error invalid HAVE_RULES value '$(HAVE_RULES)') endif +override CXXFLAGS += $(CXXOPTS) +override CPPFLAGS += $(CPPOPTS) +override LDFLAGS += $(LDOPTS) + ifndef PREFIX PREFIX=/usr endif @@ -171,12 +167,20 @@ ifndef INCLUDE_FOR_LIB INCLUDE_FOR_LIB=-Ilib -isystem externals -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2 endif +ifndef INCLUDE_FOR_FE + INCLUDE_FOR_FE=-Ilib +endif + ifndef INCLUDE_FOR_CLI - INCLUDE_FOR_CLI=-Ilib -isystem externals/simplecpp -isystem externals/tinyxml2 + INCLUDE_FOR_CLI=-Ilib -Ifrontend -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2 endif ifndef INCLUDE_FOR_TEST - INCLUDE_FOR_TEST=-Ilib -Icli -isystem externals/simplecpp -isystem externals/tinyxml2 + INCLUDE_FOR_TEST=-Ilib -Ifrontend -Icli -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2 +endif + +ifndef CFLAGS_FOR_TEST + CFLAGS_FOR_TEST=-Wno-dollar-in-identifier-extension endif BIN=$(DESTDIR)$(PREFIX)/bin @@ -189,17 +193,23 @@ MAN_SOURCE=man/cppcheck.1.xml ###### Object Files -LIBOBJ = $(libcppdir)/analyzerinfo.o \ +LIBOBJ = $(libcppdir)/valueflow.o \ + $(libcppdir)/tokenize.o \ + $(libcppdir)/symboldatabase.o \ + $(libcppdir)/addoninfo.o \ + $(libcppdir)/analyzerinfo.o \ $(libcppdir)/astutils.o \ $(libcppdir)/check.o \ $(libcppdir)/check64bit.o \ $(libcppdir)/checkassert.o \ $(libcppdir)/checkautovariables.o \ $(libcppdir)/checkbool.o \ - $(libcppdir)/checkboost.o \ $(libcppdir)/checkbufferoverrun.o \ $(libcppdir)/checkclass.o \ $(libcppdir)/checkcondition.o \ + $(libcppdir)/checkers.o \ + $(libcppdir)/checkersidmapping.o \ + $(libcppdir)/checkersreport.o \ $(libcppdir)/checkexceptionsafety.o \ $(libcppdir)/checkfunctions.o \ $(libcppdir)/checkinternal.o \ @@ -223,6 +233,7 @@ LIBOBJ = $(libcppdir)/analyzerinfo.o \ $(libcppdir)/ctu.o \ $(libcppdir)/errorlogger.o \ $(libcppdir)/errortypes.o \ + $(libcppdir)/findtoken.o \ $(libcppdir)/forwardanalyzer.o \ $(libcppdir)/fwdanalysis.o \ $(libcppdir)/importproject.o \ @@ -236,31 +247,36 @@ LIBOBJ = $(libcppdir)/analyzerinfo.o \ $(libcppdir)/platform.o \ $(libcppdir)/preprocessor.o \ $(libcppdir)/programmemory.o \ + $(libcppdir)/regex.o \ $(libcppdir)/reverseanalyzer.o \ + $(libcppdir)/sarifreport.o \ $(libcppdir)/settings.o \ + $(libcppdir)/standards.o \ $(libcppdir)/summaries.o \ $(libcppdir)/suppressions.o \ - $(libcppdir)/symboldatabase.o \ $(libcppdir)/templatesimplifier.o \ $(libcppdir)/timer.o \ $(libcppdir)/token.o \ - $(libcppdir)/tokenize.o \ $(libcppdir)/tokenlist.o \ $(libcppdir)/utils.o \ - $(libcppdir)/valueflow.o \ + $(libcppdir)/vf_analyzers.o \ + $(libcppdir)/vf_common.o \ + $(libcppdir)/vf_settokenvalue.o \ $(libcppdir)/vfvalue.o EXTOBJ = externals/simplecpp/simplecpp.o \ externals/tinyxml2/tinyxml2.o +FEOBJ = frontend/frontend.o + CLIOBJ = cli/cmdlineparser.o \ cli/cppcheckexecutor.o \ - cli/cppcheckexecutorseh.o \ - cli/cppcheckexecutorsig.o \ cli/executor.o \ cli/filelister.o \ cli/main.o \ cli/processexecutor.o \ + cli/sehwrapper.o \ + cli/signalhandler.o \ cli/singleexecutor.o \ cli/stacktrace.o \ cli/threadexecutor.o @@ -275,9 +291,9 @@ TESTOBJ = test/fixture.o \ test/testastutils.o \ test/testautovariables.o \ test/testbool.o \ - test/testboost.o \ test/testbufferoverrun.o \ test/testcharvar.o \ + test/testcheck.o \ test/testclangimport.o \ test/testclass.o \ test/testcmdlineparser.o \ @@ -287,7 +303,10 @@ TESTOBJ = test/fixture.o \ test/testcppcheck.o \ test/testerrorlogger.o \ test/testexceptionsafety.o \ + test/testexecutor.o \ test/testfilelister.o \ + test/testfilesettings.o \ + test/testfrontend.o \ test/testfunctions.o \ test/testgarbage.o \ test/testimportproject.o \ @@ -307,6 +326,9 @@ TESTOBJ = test/fixture.o \ test/testpostfixoperator.o \ test/testpreprocessor.o \ test/testprocessexecutor.o \ + test/testprogrammemory.o \ + test/testregex.o \ + test/testsarifreport.o \ test/testsettings.o \ test/testsimplifytemplate.o \ test/testsimplifytokens.o \ @@ -314,6 +336,7 @@ TESTOBJ = test/fixture.o \ test/testsimplifyusing.o \ test/testsingleexecutor.o \ test/testsizeof.o \ + test/teststandards.o \ test/teststl.o \ test/teststring.o \ test/testsummaries.o \ @@ -333,20 +356,21 @@ TESTOBJ = test/fixture.o \ test/testutils.o \ test/testvaarg.o \ test/testvalueflow.o \ - test/testvarid.o + test/testvarid.o \ + test/testvfvalue.o .PHONY: run-dmake tags ###### Targets -cppcheck: $(LIBOBJ) $(CLIOBJ) $(EXTOBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS) $(RDYNAMIC) +cppcheck: $(EXTOBJ) $(LIBOBJ) $(FEOBJ) $(CLIOBJ) + $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS) $(RDYNAMIC) all: cppcheck testrunner -testrunner: $(TESTOBJ) $(LIBOBJ) $(EXTOBJ) cli/executor.o cli/processexecutor.o cli/singleexecutor.o cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/cppcheckexecutorseh.o cli/cppcheckexecutorsig.o cli/stacktrace.o cli/filelister.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS) $(RDYNAMIC) +testrunner: $(EXTOBJ) $(TESTOBJ) $(LIBOBJ) $(FEOBJ) cli/cmdlineparser.o cli/cppcheckexecutor.o cli/executor.o cli/filelister.o cli/processexecutor.o cli/sehwrapper.o cli/signalhandler.o cli/singleexecutor.o cli/stacktrace.o cli/threadexecutor.o + $(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS) $(RDYNAMIC) test: all ./testrunner @@ -357,14 +381,14 @@ check: all checkcfg: cppcheck validateCFG ./test/cfg/runtests.sh -dmake: tools/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o +dmake: tools/dmake/dmake.o cli/filelister.o $(libcppdir)/pathmatch.o $(libcppdir)/path.o $(libcppdir)/utils.o externals/simplecpp/simplecpp.o $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) run-dmake: dmake ./dmake clean: - rm -f build/*.cpp build/*.o lib/*.o cli/*.o test/*.o tools/*.o externals/*/*.o testrunner dmake cppcheck cppcheck.exe cppcheck.1 + rm -f build/*.cpp build/*.o lib/*.o cli/*.o frontend/*.o test/*.o tools/dmake/*.o externals/*/*.o testrunner dmake cppcheck cppcheck.exe cppcheck.1 man: man/cppcheck.1 @@ -382,6 +406,7 @@ install: cppcheck ifdef FILESDIR install -d ${DESTDIR}${FILESDIR} install -d ${DESTDIR}${FILESDIR}/addons + install -m 644 addons/*.json ${DESTDIR}${FILESDIR}/addons install -m 644 addons/*.py ${DESTDIR}${FILESDIR}/addons install -d ${DESTDIR}${FILESDIR}/cfg install -m 644 cfg/*.cfg ${DESTDIR}${FILESDIR}/cfg @@ -403,16 +428,6 @@ ifdef FILESDIR rm -rf ${DESTDIR}${FILESDIR}; \ fi endif -ifdef CFGDIR - @if test -d ${DESTDIR}${CFGDIR}; then \ - files="`cd cfg 2>/dev/null && ls`"; \ - if test -n "$$files"; then \ - echo '(' cd ${DESTDIR}${CFGDIR} '&&' rm -f $$files ')'; \ - ( cd ${DESTDIR}${CFGDIR} && rm -f $$files ); \ - fi; \ - fi -endif - # Validation of library files: ConfigFiles := $(wildcard cfg/*.cfg) ConfigFilesCHECKED := $(patsubst %.cfg,%.checked,$(ConfigFiles)) @@ -451,435 +466,495 @@ checkCWEEntries: /tmp/errorlist.xml .PHONY: validateRules validateRules: xmllint --noout rules/*.xml +.PHONY: check-nonneg +check-nonneg: + ls lib/*.cpp | xargs -n 1 -P $$(nproc) g++ -fsyntax-only -DNONNEG $(CXXFLAGS) $(INCLUDE_FOR_LIB) ###### Build -$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/path.h lib/platform.h lib/suppressions.h lib/utils.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp + +$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp + +$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp + +$(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp + +$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/config.h lib/errortypes.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check.o: lib/check.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check.o: lib/check.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check.cpp -$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/check.h lib/check64bit.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/check.h lib/checkassert.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/astutils.h lib/check.h lib/checkautovariables.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/astutils.h lib/check.h lib/checkbool.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkboost.o: lib/checkboost.cpp lib/check.h lib/checkboost.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkboost.cpp - -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkother.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp -$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/check.h lib/checkexceptionsafety.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkers.cpp + +$(libcppdir)/checkersidmapping.o: lib/checkersidmapping.cpp lib/checkers.h lib/config.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp + +$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp + +$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/astutils.h lib/check.h lib/checkfunctions.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/astutils.h lib/check.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/check.h lib/checkio.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/astutils.h lib/check.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/check.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/astutils.h lib/check.h lib/checknullpointer.h lib/checkstl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/astutils.h lib/check.h lib/checkstring.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: lib/checktype.cpp lib/check.h lib/checktype.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checktype.o: lib/checktype.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/astutils.h lib/check.h lib/checknullpointer.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/check.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp -$(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/clangimport.o: lib/clangimport.cpp lib/addoninfo.h lib/checkers.h lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/clangimport.cpp $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h +$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp -$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp -$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h +$(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp -$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/findtoken.o: lib/findtoken.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp + +$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp -$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/importproject.cpp -$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes.h lib/infer.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/infer.cpp $(libcppdir)/keywords.o: lib/keywords.cpp lib/config.h lib/keywords.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/keywords.cpp -$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp -$(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/utils.h +$(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/mathlib.cpp -$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/utils.h +$(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp $(libcppdir)/pathanalysis.o: lib/pathanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp -$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/utils.h +$(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/standards.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathmatch.cpp -$(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/path.h lib/platform.h +$(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/astutils.h lib/calculate.h lib/config.h lib/errortypes.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp -$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/analyzer.h lib/astutils.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/regex.o: lib/regex.cpp lib/config.h lib/regex.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp + +$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/timer.h lib/utils.h lib/vfvalue.h +$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp + +$(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/settings.cpp -$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/standards.o: lib/standards.cpp externals/simplecpp/simplecpp.h lib/config.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp + +$(libcppdir)/summaries.o: lib/summaries.cpp lib/addoninfo.h lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/mathlib.h lib/path.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp - -$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: lib/timer.cpp lib/config.h lib/timer.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: lib/token.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp - -$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/importproject.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp +$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp + +$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/addoninfo.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp + +$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp -$(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp + +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/cppcheckexecutorsig.h cli/executor.h cli/filelister.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp -cli/cppcheckexecutorseh.o: cli/cppcheckexecutorseh.cpp cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/suppressions.h lib/utils.h - $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutorseh.cpp - -cli/cppcheckexecutorsig.o: cli/cppcheckexecutorsig.cpp cli/cppcheckexecutor.h cli/cppcheckexecutorsig.h cli/stacktrace.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/suppressions.h - $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutorsig.cpp - -cli/executor.o: cli/executor.cpp cli/executor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp -cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/path.h lib/pathmatch.h lib/utils.h +cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/filelister.cpp -cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/suppressions.h +cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/main.cpp -cli/processexecutor.o: cli/processexecutor.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/processexecutor.cpp -cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h + $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/sehwrapper.cpp + +cli/signalhandler.o: cli/signalhandler.cpp cli/signalhandler.h cli/stacktrace.h lib/config.h lib/utils.h + $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/signalhandler.cpp + +cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/singleexecutor.cpp cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/stacktrace.cpp -cli/threadexecutor.o: cli/threadexecutor.cpp cli/cppcheckexecutor.h cli/executor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h test/options.h test/redirect.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp -test/helpers.o: test/helpers.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp +test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h test/options.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp test/options.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp + +test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp + +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp + +test/testassert.o: test/testassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp + +test/testastutils.o: test/testastutils.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp + +test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp + +test/testbool.o: test/testbool.cpp lib/addoninfo.h lib/check.h lib/checkbool.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp + +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp + +test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp -test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp +test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp +test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp +test/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp +test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp +test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testboost.o: test/testboost.cpp lib/check.h lib/checkboost.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testboost.cpp +test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkbufferoverrun.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp +test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testclass.o: test/testclass.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlineparser.h cli/cppcheckexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testcolor.o: test/testcolor.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp +test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testcondition.o: test/testcondition.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkcondition.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp +test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testconstructors.o: test/testconstructors.cpp lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp +test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testcppcheck.o: test/testcppcheck.cpp lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp +test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp +test/testimportproject.o: test/testimportproject.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h test/fixture.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkexceptionsafety.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp +test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp +test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testfunctions.o: test/testfunctions.cpp lib/check.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp +test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testgarbage.o: test/testgarbage.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp +test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testimportproject.o: test/testimportproject.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp +test/testlibrary.o: test/testlibrary.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp +test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp +test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testio.o: test/testio.cpp lib/check.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp +test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testleakautovar.o: test/testleakautovar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp +test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testlibrary.o: test/testlibrary.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp +test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testmathlib.o: test/testmathlib.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp +test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testmemleak.o: test/testmemleak.cpp lib/check.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp +test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testnullpointer.o: test/testnullpointer.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testoptions.o: test/testoptions.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h test/options.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testother.o: test/testother.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testpath.o: test/testpath.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp +test/testprogrammemory.o: test/testprogrammemory.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp +test/testregex.o: test/testregex.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp +test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsettings.o: test/testsettings.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp +test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp +test/teststandards.o: test/teststandards.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/testsizeof.o: test/testsizeof.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp +test/teststl.o: test/teststl.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststl.o: test/teststl.cpp lib/check.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp +test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/teststring.o: test/teststring.cpp lib/check.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp +test/testsummaries.o: test/testsummaries.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp -test/testsummaries.o: test/testsummaries.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp +test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h test/redirect.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp +test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtimer.o: test/testtimer.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp +test/testtoken.o: test/testtoken.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtoken.o: test/testtoken.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenlist.o: test/testtokenlist.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp +test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp +test/testtype.o: test/testtype.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testtype.o: test/testtype.cpp lib/check.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp +test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/addoninfo.h lib/check.h lib/checkclass.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkclass.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp +test/testutils.o: test/testutils.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testutils.o: test/testutils.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp +test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp +test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvalueflow.o: test/testvalueflow.cpp externals/simplecpp/simplecpp.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp +test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvarid.o: test/testvarid.cpp lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h - $(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp +test/testvfvalue.o: test/testvfvalue.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h $(CXX) $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ externals/simplecpp/simplecpp.cpp externals/tinyxml2/tinyxml2.o: externals/tinyxml2/tinyxml2.cpp externals/tinyxml2/tinyxml2.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -w -c -o $@ externals/tinyxml2/tinyxml2.cpp + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ externals/tinyxml2/tinyxml2.cpp -tools/dmake.o: tools/dmake.cpp cli/filelister.h lib/config.h lib/pathmatch.h lib/utils.h - $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ tools/dmake.cpp +tools/dmake/dmake.o: tools/dmake/dmake.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h + $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ tools/dmake/dmake.cpp diff --git a/TUNING.md b/TUNING.md new file mode 100644 index 00000000000..4643e7d506a --- /dev/null +++ b/TUNING.md @@ -0,0 +1,171 @@ +# Tuning Cppcheck Analysis + +There are several ways you can potentially improve the runtime of a Cppcheck analysis. + +Note: Most of these suggestions highly depend on your code base so they need to be evaluated before being applied. They might also depend the code of Cppcheck itself and your environment. So you might want to evaluate these on a regular basis. + +## Collecting Information + +To see the time each file took to analyze just specify the `--showtime=file-total` CLI option. + +## Tuning At Build-Level + +It is most likely that a pre-built binary is being used - either an official one or one provided by the packaging manager of my operating system. + +But if you build your own binary it is possible to apply several steps to potentially improve the performance. + +Note: Recently more distribution have opted to use more advanced optimization for their packages so several of the following suggestions might have already been applied. +Please refer to the documentation of your distribution for more insight on this. + +### Use Matchcompiler + +(TODO: document how to use it when using the in-tree Visual Studio project) +(TODO: check with a CMake generated Visual Studio project) + +### Use Boost + +Boost.Container (https://www.boost.org/doc/libs/release/libs/container) is being used for some containers which have a smaller overhead. + +As the used library is header-only implementation you only need to install the package on the system you build the binary on but not on the system you run the analysis on. + +The official Windows binary is always using this. + +This will be used by default if Boost is detected in CMake. If you want to enforce the usage, you can use the CMake option `-DUSE_BOOST=On` which will cause the build to fail if no Boost was detected. + +Using Visual Studio you need to provide a full Boost release (i.e. including binaries) for it to be detected by CMake. If you are not able to do this you can specify the CMake option `-DBOOST_INCLUDEDIR=` (pointing to the directory which *contains* the `boost` include directory) to work around this (this is a Cppcheck specific hack) - see https://trac.cppcheck.net/ticket/13822 for more details. + +If you are using `make` instead you need to specify `-DHAVE_BOOST` in the flags. + +If you are using the Visual Studio project you need to specify the properties `HaveBoost` (always needs to be set to `HAVE_BOOST`) and `BoostInclude` (set to the Boost folder). On the command-line you would need to add `-p:HaveBoost=HAVE_BOOST -p:BoostInclude=`. + +### Use A Different Compiler + +Analyzing our own code base has shown that using a different compiler might lead to slightly better performance. + +In our case Clang is mostly faster than GCC. See https://trac.cppcheck.net/ticket/10778 for some details. + +### Use More Advanced Optimizations + +By default we enforce the `-O2` optimization level. Even when using the `Release` build type in CMake which defaults to `-O3`. It might be possible that building with `-O3` might yield a perfomance increase. + +There are also no additional code generation flags provided so the resulting binary can run on any system. You might be able to tune this and apply more optimization which is tailored to the system you will be running the binary on. + +Needs to be evaluated. (TODO: file tickets) + +### Use LTO + +Needs to be evaluated. See https://trac.cppcheck.net/ticket/11671. + +### Use profile-guided optimizations (PGO/BOLT/AutoFDO/Propeller) + +Needs to be evaluated. See https://trac.cppcheck.net/ticket/11672. + +## Tuning At Analysis-Level + +### Use A More Performant Platform + +It seems people assume that you need to run the analysis on the same system you build your code on/for. That is not necessary as the analysis is system-agnostic. +As system headers are not required for analyzing your code you only need to specify the configuration which matches the system you run your code on. + +In case you are using a project as input which can only be generated on the build/target system you can just transfer that to a different system and still run the analysis. + +### Specify A Build Dir + +Using the `--cppcheck-build-dir` allows you to perform incremental runs which omit files which have not been changed. + +Important: As this is currently seriously lacking in testing coverage it might have shortcomings and need to be used with care. (TODO: file ticket) + +### Exclude Static/Generated Files + +If your code base contains files which rarely change (e.g. local copies of external dependencies) or you have generated files (e.g. `moc_*.cpp` for Qt projects) you might consider excluding these from the analysis. +This can be done by using the `-i` option on the CLI, `` in GUI projects or by including them to begin with into the files passed to the analysis. + +Depending on your setup you might also consider to scan these files in a less frequent run (e.g. only when the files have changed or Cppcheck was updated). + +This could also be handled using `--cppcheck-build-dir` (see above). + +### Exclude System Headers + +System headers are not necessary to perform the analysis. So you might consider not providing those to the analysis and specify a library configuration via `--library` instead. + +`pkg-config` for instance will always provide non-system includes. + +(TODO: file ticket about ignoring all braced includes) + +### Limit The Configuration + +By default configuration to analyze will be determined automatically for each file based on the code. The maximum amount is limited and can be controlled by CLI options. + +Depending on your setup you might want to limit it to specific configuration by using `-D` (CLI) or `--project-configuration=` (Visual Studio project). +When you are using a compilation database generated by CMake it is already using a fixed configuration. + +### Use Multiple Jobs + +By default only a single process/thread is being used. You might to scale this up using the `-j` CLI option. Please note that specifying a value that will max out your systems resources might have a detrimental effect. + +### Use A Different Threading Model + +When using multiple job for the analysis (see above) on Linux it will default to using processes. This is done so the analysis is not aborted prematurely aborted in case of a crash. +Unfortunately it has overhead because of a suboptimal implementation and the fact that data needs to be transferred from the child processes to the main process. +So if you do not require the additional safety you might want to switch to the usage of thread instead using `--executor=thread`. + +Note: For Windows binaries we currently do not provide the possibility of using processes so this does not apply. + +### Disable Analyzing Of Unused Templated Functions + +Currently all templated functions (either locally or in headers) will be analyzed regardless if they are instantiated or not. If you have template-heavy includes that might lead to unnecessary work and findings, and might slow down the analysis. This behavior can be disabled with `--no-check-unused-templates`. + +Note: This might lead to "false negatives" in such functions if they are never instantiated. You should make sure that you have proper coverage of the affected functions in your code before enabling this. + +### Limit Analysis Of Projects + +If you specify a project all files will be analyzed by default. But in some cases you might only be interested in the results in a subset of those (e.g. in IDE integrations). + +Using the `--file-filter=` CLI option you can select files using a globbing syntax. Using `--file-filter=-` you can provide the filters directly on the CLI. + +## Advanced Tuning + +### Re-order The Files + +Files which take longer to analyze should be processed at first so they might not extended the run time. As the order how the files provided on the CLI or via the project are being honored it is as simple as that. + +### Adjust Thresholds + +There are lots of internal thresholds which limit the work which is put into parts of the analysis. The defaults were chosen as a compromise of time being spent vs. issues being detected but not might not be a good fit in all cases. + +These thresholds are currently neither exposed nor documented so they cannot be changed without the modifying the source which is *highly discouraged*. + +They are being utilized internally by `-check-level` though (see below). + +(TODO: file ticket about providing all bailouts) +(TODO: file ticket about expose these) +(TODO: file ticket about specifying these per file) + +Note: As these will lead to less data being collected for the analysis it might lead to false negatives *and* false positives. + +### Adjust Check Level + +There are several check levels which are basically a collection of different threshold values (see above). This can be adjusted by the CLI option `--check-level`. + +Note: The current default is the lowest available check level. + +Note: As these will lead to less data being collected for the analysis it might lead to false negatives *and* false positives. + +## Reporting Issues + +If you encounter a file which has an unreasonable slow analysis please consider reporting this as an issue. + +Also consider reporting major upticks in the runtime of the analysis after updating to a newer version. Some of these might be expected as the analysis is constantly improved but out-of-the-box we still need aim for reasonable times. + +In all cases please try to provide a small reproducer if possible. + +Note: There might even be cases the analysis will never finish because it is stuck in a cycle. This is quite uncommon but there are still several unresolved known cases so it is possible to encounter this. + +### Known Issues + +https://trac.cppcheck.net/ticket/10663 +https://trac.cppcheck.net/ticket/10765 +https://trac.cppcheck.net/ticket/10778 +https://trac.cppcheck.net/ticket/11262 +https://trac.cppcheck.net/ticket/12528 +https://trac.cppcheck.net/ticket/13698 \ No newline at end of file diff --git a/addons/README.md b/addons/README.md index b441b22b19f..8df8229b970 100644 --- a/addons/README.md +++ b/addons/README.md @@ -7,9 +7,40 @@ Addons are scripts that analyses Cppcheck dump files to check compatibility with + [misra.py](https://github.com/danmar/cppcheck/blob/main/addons/misra.py) Used to verify compliance with MISRA C 2012 - a proprietary set of guidelines to avoid such questionable code, developed for embedded systems. Since this standard is proprietary, cppcheck does not display error text by specifying only the number of violated rules (for example, [c2012-21.3]). If you want to display full texts for violated rules, you will need to create a text file containing MISRA rules, which you will have to pass when calling the script with `--rule-texts` key. Some examples of rule texts files available in [tests directory](https://github.com/danmar/cppcheck/blob/main/addons/test/misra/). + [y2038.py](https://github.com/danmar/cppcheck/blob/main/addons/y2038.py) - Checks Linux system for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. This required [modified environment](https://github.com/3adev/y2038). See complete description [here](https://github.com/danmar/cppcheck/blob/main/addons/doc/y2038.txt). + Checks code for [year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) safety. See complete description [here](https://github.com/danmar/cppcheck/blob/main/addons/doc/y2038.md). + [threadsafety.py](https://github.com/danmar/cppcheck/blob/main/addons/threadsafety.py) Analyse Cppcheck dump files to locate threadsafety issues like static local objects used by multiple threads. ++ [naming.py](https://github.com/danmar/cppcheck/blob/main/addons/naming.py) + Enforces naming conventions across the code. ++ [namingng.py](https://github.com/danmar/cppcheck/blob/main/addons/namingng.py) + Enforces naming conventions across the code. Enhanced version with support for type prefixes in variable and function names. ++ [findcasts.py](https://github.com/danmar/cppcheck/blob/main/addons/findcasts.py) + Locates casts in the code. ++ [misc.py](https://github.com/danmar/cppcheck/blob/main/addons/misc.py) + Performs miscellaneous checks. + +### Other files + +- doc + Additional files for documentation generation. +- tests + Contains various unit tests for the addons. +- cppcheck.py + Internal helper used by Cppcheck binary to run the addons. +- cppcheckdata.doxyfile + Configuration file for documentation generation. +- cppcheckdata.py + Helper class for reading Cppcheck dump files within an addon. +- misra_9.py + Implementation of the MISRA 9.x rules used by `misra` addon. +- namingng.config.json + Example configuration for `namingng` addon. +- namingng.json + Example JSON file that can be used using --addon=namingng.json, referring to namingng.py and namingng.config.json +- ROS_naming.json + Example configuration for the `namingng` addon enforcing the [ROS naming convention for C++ ](http://wiki.ros.org/CppStyleGuide#Files). +- runaddon.py + Internal helper used by Cppcheck binary to run the addons. ## Usage @@ -19,6 +50,11 @@ Addons are scripts that analyses Cppcheck dump files to check compatibility with cppcheck --addon=misc src/test.c ``` +For project-wide analysis with compile_commands.json: +```bash +cppcheck --project=build/compile_commands.json --addon=y2038 +``` + It is also possible to call scripts as follows: ```bash cppcheck --dump --quiet src/test.c diff --git a/addons/ROS_naming.json b/addons/ROS_naming.json index 82c0131cf0a..0262d69c09b 100644 --- a/addons/ROS_naming.json +++ b/addons/ROS_naming.json @@ -1,5 +1,5 @@ { - "RE_FILE": {".*[A-Z]": [true, "under_scored"]}, + "RE_FILE": [".*[A-Z]"], "RE_NAMESPACE": {".*[A-Z]": [true, "under_scored"], ".*\\_$": [true, "under_scored"]}, "RE_FUNCTIONNAME": {".*\\_": [true, "camelCase"], diff --git a/addons/cppcheck.py b/addons/cppcheck.py index 1649815e070..735269d32c5 100644 --- a/addons/cppcheck.py +++ b/addons/cppcheck.py @@ -1,5 +1,7 @@ -import cppcheckdata, sys, os +import cppcheckdata +import sys +import os __checkers__ = [] diff --git a/addons/cppcheckdata.py b/addons/cppcheckdata.py index 550d2ea7174..dbe36d56a57 100755 --- a/addons/cppcheckdata.py +++ b/addons/cppcheckdata.py @@ -166,7 +166,7 @@ class ValueType: Attributes: type nonstd/pod/record/smart-pointer/container/iterator/void/bool/char/short/wchar_t/int/long/long long/unknown int/float/double/long double sign signed/unsigned - bits + bits bit count for bit-fields, otherwise None pointer constness reference @@ -178,7 +178,7 @@ class ValueType: type = None sign = None - bits = 0 + bits = None constness = 0 pointer = 0 typeScopeId = None @@ -188,7 +188,8 @@ class ValueType: def __init__(self, element): self.type = element.get('valueType-type') self.sign = element.get('valueType-sign') - self.bits = int(element.get('valueType-bits', 0)) + self.bits = element.get('valueType-bits', None) + self.bits = int(self.bits) if self.bits else None self.pointer = int(element.get('valueType-pointer', 0)) self.constness = int(element.get('valueType-constness', 0)) self.reference = element.get('valueType-reference') @@ -254,6 +255,7 @@ class Token: isCast externLang isExpandedMacro Is this token a expanded macro token + macroName Macro name that this token is expanded from isRemovedVoidParameter Has void parameter been removed? isSplittedVarDeclComma Is this a comma changed to semicolon in a split variable declaration ('int a,b;' => 'int a; int b;') isSplittedVarDeclEq Is this a '=' changed to semicolon in a split variable declaration ('int a=5;' => 'int a; a=5;') @@ -261,6 +263,7 @@ class Token: isComplex isRestrict isAttributeExport + isAnonymous varId varId for token, each variable has a unique non-zero id exprId exprId for token, each expression has a unique non-zero id variable Variable information for this token. See the Variable class. @@ -313,6 +316,7 @@ class Token: isCast = False isUnsigned = False isSigned = False + macroName = None isExpandedMacro = False isRemovedVoidParameter = False isSplittedVarDeclComma = False @@ -321,6 +325,7 @@ class Token: isComplex = False isRestrict = False isAttributeExport = False + isAnonymous = False exprId = None varId = None variableId = None @@ -334,6 +339,7 @@ class Token: typeScopeId = None typeScope = None + type = None astParentId = None astParent = None @@ -353,27 +359,27 @@ def __init__(self, element): self.previous = None self.scopeId = element.get('scope') self.scope = None - type = element.get('type') - if type == 'name': + self.type = element.get('type') + if self.type == 'name': self.isName = True if element.get('isUnsigned'): self.isUnsigned = True if element.get('isSigned'): self.isSigned = True - elif type == 'number': + elif self.type == 'number': self.isNumber = True if element.get('isInt'): self.isInt = True elif element.get('isFloat'): self.isFloat = True - elif type == 'string': + elif self.type == 'string': self.isString = True self.strlen = int(element.get('strlen')) - elif type == 'char': + elif self.type == 'char': self.isChar = True - elif type == 'boolean': + elif self.type == 'boolean': self.isBoolean = True - elif type == 'op': + elif self.type == 'op': self.isOp = True if element.get('isArithmeticalOp'): self.isArithmeticalOp = True @@ -386,7 +392,8 @@ def __init__(self, element): if element.get('isCast'): self.isCast = True self.externLang = element.get('externLang') - if element.get('isExpandedMacro'): + self.macroName = element.get('macroName') + if self.macroName or element.get('isExpandedMacro'): self.isExpandedMacro = True if element.get('isRemovedVoidParameter'): self.isRemovedVoidParameter = True @@ -402,6 +409,8 @@ def __init__(self, element): self.isRestrict = True if element.get('isAttributeExport'): self.isAttributeExport = True + if element.get('isAnonymous'): + self.isAnonymous = True self.linkId = element.get('link') self.link = None if element.get('varId'): @@ -435,7 +444,7 @@ def __repr__(self): "isChar", "isBoolean", "isOp", "isArithmeticalOp", "isAssignmentOp", "isComparisonOp", "isLogicalOp", "isCast", "externLang", "isExpandedMacro", "isRemovedVoidParameter", "isSplittedVarDeclComma", "isSplittedVarDeclEq", - "isImplicitInt", "isComplex", "isRestrict", "isAttributeExport", "linkId", + "isImplicitInt", "isComplex", "isRestrict", "isAttributeExport", "isAnonymous", "linkId", "varId", "variableId", "functionId", "valuesId", "valueType", "typeScopeId", "astParentId", "astOperand1Id", "file", "linenr", "column"] @@ -528,6 +537,7 @@ def tokAt(self, n): for i, t in enumerate(tl): if i == n: return t + return None def linkAt(self, n): token = self.tokAt(n) @@ -566,6 +576,7 @@ class Scope: function = None nestedInId = None nestedIn = None + nestedList = None type = None isExecutable = None varlistId = None @@ -583,13 +594,14 @@ def __init__(self, element): self.bodyEnd = None self.nestedInId = element.get('nestedIn') self.nestedIn = None + self.nestedList = [] self.type = element.get('type') self.definedType = element.get('definedType') self.isExecutable = (self.type in ('Function', 'If', 'Else', 'For', 'While', 'Do', 'Switch', 'Try', 'Catch', 'Unconditional', 'Lambda')) - self.varlistId = list() - self.varlist = list() + self.varlistId = [] + self.varlist = [] def __repr__(self): attrs = ["Id", "className", "functionId", "bodyStartId", "bodyEndId", @@ -603,6 +615,8 @@ def setId(self, IdMap): self.bodyStart = IdMap[self.bodyStartId] self.bodyEnd = IdMap[self.bodyEndId] self.nestedIn = IdMap[self.nestedInId] + if self.nestedIn: + self.nestedIn.nestedList.append(self) self.function = IdMap[self.functionId] for v in self.varlistId: value = IdMap.get(v) @@ -669,7 +683,7 @@ def __init__(self, element, nestedIn): self.argumentId = {} def __repr__(self): - attrs = ["Id", "tokenId", "tokenDefId", "name", "type", "hasVirtualSpecifier", + attrs = ["Id", "tokenId", "tokenDefId", "name", "type", "hasVirtualSpecifier", "isImplicitlyVirtual", "access", "isInlineKeyword", "isStatic", "isAttributeNoreturn", "overriddenFunction", "nestedIn", "argumentId"] return "{}({})".format( @@ -823,7 +837,7 @@ class Value: intvalue integer value tokvalue token value floatvalue float value - movedValue + movedvalue uninit containerSize container size bufferSize buffer size @@ -893,7 +907,7 @@ def setId(self, IdMap): self.symbolic = IdMap.get(self._symbolicId) def __repr__(self): - attrs = ["intvalue", "tokvalue", "floatvalue", "movedValue", "uninit", + attrs = ["intvalue", "tokvalue", "floatvalue", "movedvalue", "uninit", "bufferSize", "containerSize", "condition", "valueKind"] return "{}({})".format( "Value", @@ -938,29 +952,60 @@ class Suppression: fileName The name of the file to suppress warnings for, can include wildcards lineNumber The number of the line to suppress warnings from, can be 0 to represent any line symbolName The name of the symbol to match warnings for, can include wildcards + lineBegin The first line to suppress warnings from + lineEnd The last line to suppress warnings from + suppressionType The type of suppression which is applied (unique = None (default), file, block, blockBegin, blockEnd, macro) """ errorId = None fileName = None lineNumber = None symbolName = None + lineBegin = None + lineEnd = None + suppressionType = None def __init__(self, element): self.errorId = element.get('errorId') self.fileName = element.get('fileName') self.lineNumber = element.get('lineNumber') self.symbolName = element.get('symbolName') + self.lineBegin = element.get('lineBegin') + self.lineEnd = element.get('lineEnd') + self.suppressionType = element.get('type') def __repr__(self): - attrs = ['errorId' , "fileName", "lineNumber", "symbolName"] + attrs = ["errorId", "fileName", "lineNumber", "symbolName", "lineBegin", "lineEnd","suppressionType"] return "{}({})".format( "Suppression", ", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs)) ) def isMatch(self, file, line, message, errorId): + # Line Suppression + if ((self.fileName is None or fnmatch(file, self.fileName)) + and (self.suppressionType is None) # Verify use of default suppression type (None = unique) + and (self.lineNumber is not None and int(line) == int(self.lineNumber)) + and (self.symbolName is None or fnmatch(message, '*'+self.symbolName+'*')) + and fnmatch(errorId, self.errorId)): + return True + # File Suppression + if ((self.fileName is None or fnmatch(file, self.fileName)) + and (self.suppressionType is not None and self.suppressionType == "file") # Verify use of file (global) suppression type + and (self.symbolName is None or fnmatch(message, '*'+self.symbolName+'*')) + and fnmatch(errorId, self.errorId)): + return True + # Block Suppression Mode + if ((self.fileName is None or fnmatch(file, self.fileName)) + and (self.suppressionType is not None and self.suppressionType == "block") # Type for Block suppression + and (self.lineBegin is not None and int(line) > int(self.lineBegin)) # Code Match is between the Block suppression + and (self.lineEnd is not None and int(line) < int(self.lineEnd)) # Code Match is between the Block suppression + and (self.symbolName is None or fnmatch(message, '*'+self.symbolName+'*')) + and fnmatch(errorId, self.errorId)): + return True + # Other Suppression (Globaly set via suppression file or cli command) if ((self.fileName is None or fnmatch(file, self.fileName)) - and (self.lineNumber is None or int(line) == int(self.lineNumber)) + and (self.suppressionType is None) and (self.symbolName is None or fnmatch(message, '*'+self.symbolName+'*')) and fnmatch(errorId, self.errorId)): return True @@ -1178,6 +1223,7 @@ def __init__(self, filename): """ :param filename: Path to Cppcheck dump file """ + self.language = None self.filename = filename self.rawTokens = [] self.platform = None @@ -1194,6 +1240,8 @@ def __init__(self, filename): for event, node in ElementTree.iterparse(self.filename, events=('start', 'end')): if platform_done and rawtokens_done and suppressions_done: break + if node.tag == 'dumps': + self.language = node.get('language') if node.tag == 'platform' and event == 'start': self.platform = Platform(node) platform_done = True @@ -1242,6 +1290,9 @@ def iterconfigurations(self): # Iterating iter_typedef_info = False + # Iterating + iter_directive = False + # Use iterable objects to traverse XML tree for dump files incrementally. # Iterative approach is required to avoid large memory consumption. # Calling .clear() is necessary to let the element be garbage collected. @@ -1251,7 +1302,7 @@ def iterconfigurations(self): if event == 'start': cfg = Configuration(node.get('cfg')) continue - elif event == 'end': + if event == 'end': cfg.setIdMap(cfg_arguments) yield cfg cfg = None @@ -1273,8 +1324,12 @@ def iterconfigurations(self): cfg.standards.set_posix(node) # Parse directives list - elif node.tag == 'directive' and event == 'start': - cfg.directives.append(Directive(node)) + elif node.tag == 'directive': + if event == 'start': + cfg.directives.append(Directive(node)) + iter_directive = True + elif event == 'end': + iter_directive = False # Parse macro usage elif node.tag == 'macro' and event == 'start': cfg.macro_usage.append(MacroUsage(node)) @@ -1286,7 +1341,7 @@ def iterconfigurations(self): # Parse tokens elif node.tag == 'tokenlist' and event == 'start': continue - elif node.tag == 'token' and event == 'start': + elif node.tag == 'token' and event == 'start' and not iter_directive and not iter_typedef_info: cfg.tokenlist.append(Token(node)) # Parse scopes @@ -1307,7 +1362,7 @@ def iterconfigurations(self): if event == 'start': cfg_function = Function(node, cfg.scopes[-1]) continue - elif event == 'end': + if event == 'end': cfg.functions.append(cfg_function) cfg_function = None @@ -1351,7 +1406,7 @@ def iterconfigurations(self): if event == 'start': cfg_valueflow = ValueFlow(node) continue - elif event == 'end': + if event == 'end': cfg.valueflow.append(cfg_valueflow) cfg_valueflow = None @@ -1547,8 +1602,7 @@ def __nonzero__(self): def __getattr__(self, k): if k in self._keys: return None - else: - raise AttributeError + raise AttributeError def bind_split(s): if '@' in s: @@ -1612,11 +1666,19 @@ def is_suppressed(location, message, errorId): return True return False -def reportError(location, severity, message, addon, errorId, extra=''): +def log_checker(message, addon): + if '--cli' in sys.argv: + msg = { 'addon': addon, + 'severity': 'none', + 'message': message, + 'errorId': 'logChecker'} + sys.stdout.write(json.dumps(msg) + '\n') + +def reportError(location, severity, message, addon, errorId, extra='', columnOverride=None): if '--cli' in sys.argv: msg = { 'file': location.file, 'linenr': location.linenr, - 'column': location.column, + 'column': location.column if columnOverride is None else columnOverride, 'severity': severity, 'message': message, 'addon': addon, @@ -1634,11 +1696,14 @@ def reportError(location, severity, message, addon, errorId, extra=''): EXIT_CODE = 1 def reportSummary(dumpfile, summary_type, summary_data): - # dumpfile ends with ".dump" - ctu_info_file = dumpfile[:-4] + "ctu-info" - with open(ctu_info_file, 'at') as f: - msg = {'summary': summary_type, 'data': summary_data} - f.write(json.dumps(msg) + '\n') + msg = {'summary': summary_type, 'data': summary_data} + if '--cli' in sys.argv: + sys.stdout.write(json.dumps(msg) + '\n') + else: + # dumpfile ends with ".dump" + ctu_info_file = dumpfile[:-4] + "ctu-info" + with open(ctu_info_file, 'at') as f: + f.write(json.dumps(msg) + '\n') def get_path_premium_addon(): @@ -1654,8 +1719,9 @@ def get_path_premium_addon(): def cmd_output(cmd): with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p: - comm = p.communicate() - out = comm[0] - if p.returncode == 1 and len(comm[1]) > 2: - out = comm[1] - return out.decode(encoding='utf-8', errors='ignore') + stdout, stderr = p.communicate() + rc = p.returncode + out = stdout + if rc == 1 and len(stderr) > 2: + out = stderr + return out.decode(encoding='utf-8', errors='ignore') diff --git a/addons/doc/y2038.md b/addons/doc/y2038.md new file mode 100644 index 00000000000..5566c3936ba --- /dev/null +++ b/addons/doc/y2038.md @@ -0,0 +1,166 @@ +# README of the Y2038 cppcheck addon + +## Contents + +- [README of the Y2038 cppcheck addon](#readme-of-the-y2038-cppcheck-addon) + - [Contents](#contents) + - [What is Y2038?](#what-is-y2038) + - [What is the Y2038 cppcheck addon?](#what-is-the-y2038-cppcheck-addon) + - [How does the Y2038 cppcheck addon work?](#how-does-the-y2038-cppcheck-addon-work) + - [Primary Usage: Cppcheck Addon Integration (`y2038.py`)](#primary-usage-cppcheck-addon-integration-y2038py) + - [Implementation Details](#implementation-details) + - [Requirements](#requirements) + - [How to use the Y2038 cppcheck addon](#how-to-use-the-y2038-cppcheck-addon) + - [**Auditing Your Project for Y2038 Compliance**](#auditing-your-project-for-y2038-compliance) + - [**CI/CD Integration**](#cicd-integration) + - [Testing](#testing) + - [Running Y2038 Addon Tests](#running-y2038-addon-tests) + - [Test Coverage](#test-coverage) + - [Test Structure](#test-structure) + +--- + +## What is Y2038? + +In a few words: + +Most operating systems and programming environments represent the current time as the number of seconds since the Unix epoch. In C and C++ this is exposed by time() and std::time(), with the Unix epoch defined as 00:00:00 UTC on 1 January 1970. + +Typically this representation is stored as a 64-bit signed quantity. +Some systems, mainly embedded systems and older systems, still use a 32-bit signed +time_t representation. + +On January 19th, 2038 at 03:14:07 GMT, such 32-bit representations will reach +their maximum positive value. + +What happens then is unpredictable: system time might roll back to December +13th, 1901 at 19:55:13, or it might keep running on until February 7th, 2106 +at 06:28:15 GMT, or the computer may freeze, or just about anything you can +think of, plus a few ones you can't. + +The workaround for this is to switch to a 64-bit signed representation of time +as seconds from the Unix epoch. This representation will work for more than 250 +billion years. + +Working around Y2038 requires fixing the Linux kernel, the C libraries, and +any user code around which uses 32-bit epoch representations. + +There is Y2038-proofing work in progress on the Linux and GNU glibc front. + +## What is the Y2038 cppcheck addon? + +The Y2038 cppcheck addon is a tool to help detect code which might need fixing +because it is Y2038-unsafe. This may be because it uses types or functions from +GNU libc or from the Linux kernel which are known not to be Y2038-proof. + +## How does the Y2038 cppcheck addon work? + +The Y2038 addon is a comprehensive tool designed to audit your project for Y2038 compliance. It provides a streamlined, intelligent approach to Y2038 analysis. + +### Primary Usage: Cppcheck Integration with Project Files + +The Y2038 addon integrates seamlessly with cppcheck's core project parsing infrastructure. For optimal analysis, use the addon with project files: + +```bash +cppcheck --project=build/compile_commands.json --addon=y2038 +``` + +For single files, you can also use: +```bash +cppcheck --addon=y2038 source_file.c +``` + +#### Implementation Details + +The addon leverages cppcheck's built-in project parsing capabilities: + +- **Core Integration**: Y2038-related compiler flags are extracted by cppcheck core during project parsing and passed through dump file configuration +- **Automatic Flag Detection**: Cppcheck automatically detects Y2038-relevant flags (`-D_TIME_BITS=64`, `-D_FILE_OFFSET_BITS=64`, `-D_USE_TIME_BITS64`) from compilation commands +- **Clean Architecture**: No redundant file parsing - cppcheck handles project files once, addon focuses on analysis +- **Priority Logic**: Dump file configuration (from cppcheck's project parsing) takes precedence over source code `#define` statements +- **Source Fallback**: When no project configuration is available, the addon analyzes source code `#define` statements + +This architecture ensures optimal performance and maintains clean separation of concerns between cppcheck core (project parsing) and addon (analysis logic). + +The output is the standard Cppcheck analysis report, focused on Y2038-related issues. + +## Requirements + +The Y2038 addon works with any cppcheck installation and requires no additional dependencies beyond cppcheck itself. + +For optimal Y2038 analysis, ensure your project uses a supported build system that generates `compile_commands.json`: + +- **CMake**: Use `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` +- **Bear**: For Make/Autotools projects, use `bear` to generate compile commands +- **Ninja**: Use `ninja -t compdb` to generate compile commands +- **Bazel**: Use `bazel aquery` with appropriate flags + +If using `bear` for Make-based projects, install it via your package manager: + +```bash +# On Debian/Ubuntu +sudo apt-get install bear + +# On Fedora +sudo dnf install bear + +# On macOS (using Homebrew) +brew install bear +``` + +## How to use the Y2038 cppcheck addon + +### **Auditing Your Project for Y2038 Compliance** + +The Y2038 addon seamlessly integrates with your existing cppcheck workflow. + +**For projects with compile_commands.json (recommended):** + +```bash +cppcheck --project=build/compile_commands.json --addon=y2038 +``` + +**For single file analysis:** + +```bash +cppcheck --addon=y2038 source_file.c +``` + +**For project-wide analysis without compile_commands.json:** + +```bash +cppcheck --addon=y2038 src/ +``` + +The integration automatically: + +1. **Extracts Y2038 flags** from your project's compilation commands via cppcheck's project parsing +2. **Passes flag information** through dump file configuration to the addon +3. **Analyzes source code** with proper Y2038 context from both build system and source directives +4. **Reports Y2038 issues** using cppcheck's standard error reporting format + +### **CI/CD Integration** + +For CI/CD integration, use the Y2038 addon with your project's build configuration: + +```sh +# Example CI script with compile_commands.json +#!/bin/bash +# Generate compile_commands.json (if not already available) +cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build +# or: bear -- make + +# Run Y2038 analysis +cppcheck --project=build/compile_commands.json --addon=y2038 --error-exitcode=1 + +# The addon will return a non-zero exit code if Y2038 issues are found. +# The output is the standard Cppcheck report. +``` + +**For projects without compile_commands.json:** + +```sh +# Example CI script for source-only analysis +#!/bin/bash +cppcheck --addon=y2038 --error-exitcode=1 src/ +``` diff --git a/addons/doc/y2038.txt b/addons/doc/y2038.txt deleted file mode 100644 index 990b24bd483..00000000000 --- a/addons/doc/y2038.txt +++ /dev/null @@ -1,151 +0,0 @@ -README of the Y2038 cppcheck addon -================================== - -Contents - -1. What is Y2038? -2. What is the Y2038 cppcheck addon? -3. How does the Y2038 cppcheck addon work? -4. How to use the Y2038 cppcheck addon - ---- - -1. What is Y2038? - -In a few words: - -In Linux, the current date and time is kept as the number of seconds elapsed -since the Unix epoch, that is, since January 1st, 1970 at 00:00:00 GMT. - -Most of the time, this representation is stored as a 32-bit signed quantity. - -On January 19th, 2038 at 03:14:07 GMT, such 32-bit representations will reach -their maximum positive value. - -What happens then is unpredictable: system time might roll back to December -13th, 1901 at 19:55:13, or it might keep running on until February 7th, 2106 -at 06:28:15 GMT, or the computer may freeze, or just about anything you can -think of, plus a few ones you can't. - -The workaround for this is to switch to a 64-bit signed representation of time -as seconds from the Unix epoch. This representation will work for more than 250 -billion years. - -Working around Y2038 requires fixing the Linux kernel, the C libraries, and -any user code around which uses 32-bit epoch representations. - -There is Y2038-proofing work in progress on the Linux and GNU glibc front. - -2. What is the Y2038 cppcheck addon? - -The Y2038 cppcheck addon is a tool to help detect code which might need fixing -because it is Y2038-unsafe. This may be because it uses types or functions from -GNU libc or from the Linux kernel which are known not to be Y2038-proof. - -3. How does the Y2038 cppcheck addon work? - -The Y2038 cppcheck addon takes XML dumps produced by cppcheck from source code -files and looks for the names of types or functions which are known to be Y2038- -unsafe, and emits diagnostics whenever it finds one. - -Of course, this is of little use if your code uses a Y2038-proof glibc and -correctly configured Y2038-proof time support. - -This is why y2038.py takes into account two preprocessor directives: -_TIME_BITS and __USE_TIME_BITS64. - -_TIME_BITS is defined equal to 64 by user code when it wants 64-bit time -support from the GNU glibc. Code which does not define _TIME_BITS equal to 64 -(or defines it to something else than 64) runs a risk of not being Y2038-proof. - -__USE_TIME_BITS64 is defined by the GNU glibc when it actually provides 64-bit -time support. When this is defined, then all glibc symbols, barring bugs, are -Y2038-proof (but your code might have its own Y2038 bugs, if it handles signed -32-bit Unix epoch values). - -The Y2038 cppcheck performs the following checks: - - 1. Upon meeting a definition for _TIME_BITS, if that definition does not - set it equal to 64, this error diagnostic is emitted: - - Error: _TIME_BITS must be defined equal to 64 - - This case is very unlikely but might result from a typo, so pointing - it out is quite useful. Note that definitions of _TIME_BITS as an - expression evaluating to 64 will be flagged too. - - 2. Upon meeting a definition for _USE_TIME_BITS64, if _TIME_BITS is not - defined equal to 64, this information diagnostic is emitted: - - Warning: _USE_TIME_BITS64 is defined but _TIME_BITS was not - - This reflects the fact that even though the glibc checked default to - 64-bit time support, this was not requested by the user code, and - therefore the user code might fail Y2038 if built against a glibc - which defaults to 32-bit time support. - - 3. Upon meeting a symbol (type or function) which is known to be Y2038- - unsafe, if _USE_TIME_BITS64 is undefined or _TIME_BITS not properly - defined, this warning diagnostic is emitted: - - Warning: is Y2038-unsafe - - This reflects the fact that the user code is referring to a symbol - which, when glibc defaults to 32-bit time support, might fail Y2038. - -General note: y2038.py will handle multiple configurations, and will -emit diagnostics for each configuration in turn. - -4. How to use the Y2038 cppcheck addon - -The Y2038 cppcheck addon is used like any other cppcheck addon: - - cppcheck --dump file1.c [ file2.c [...]]] - y2038.py file1.c [ file2.c [...]]] - -Sample test C file is provided: - - test/y2038-test-1-bad-time-bits.c - test/y2038-test-2-no-time-bits.c - test/y2038-test-3-no-use-time-bits.c - test/y2038-test-4-good.c - -These cover the cases described above. You can run them through cppcheck -and y2038.py to see for yourself how the addon diagnostics look like. If -this README is not outdated (and if it is, feel free to submit a patch), -you can run cppcheck on these files as on any others: - - cppcheck --dump addons/y2038/test/y2038-*.c - y2038.py addons/y2038/test/y2038-*.dump - -If you have not installed cppcheck yet, you will have to run these -commands from the root of the cppcheck repository: - - make - sudo make install - ./cppcheck --dump addons/y2038/test/y2038-*.c - PYTHONPATH=addons python addons/y2038/y2038.py addons/y2038/test/y2038-*.c.dump - -In both cases, y2038.py execution should result in the following: - -Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump... -Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump, config ""... -Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump... -Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump, config ""... -Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump... -Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump, config ""... -Checking addons/y2038/test/y2038-test-4-good.c.dump... -Checking addons/y2038/test/y2038-test-4-good.c.dump, config ""... -# Configuration "": -# Configuration "": -[addons/y2038/test/y2038-test-1-bad-time-bits.c:8]: (error) _TIME_BITS must be defined equal to 64 -[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not -[addons/y2038/test/y2038-test-1-bad-time-bits.c:10]: (information) addons/y2038/test/y2038-inc.h was included from here -[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not -[addons/y2038/test/y2038-test-2-no-time-bits.c:8]: (information) addons/y2038/test/y2038-inc.h was included from here -[addons/y2038/test/y2038-test-3-no-use-time-bits.c:13]: (warning) timespec is Y2038-unsafe -[addons/y2038/test/y2038-test-3-no-use-time-bits.c:15]: (warning) clock_gettime is Y2038-unsafe - -Note: y2038.py recognizes option --template as cppcheck does, including -pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also -recognized. diff --git a/addons/findcasts.py b/addons/findcasts.py index 41fbf2d9b77..d4842b229a6 100755 --- a/addons/findcasts.py +++ b/addons/findcasts.py @@ -4,7 +4,6 @@ # import cppcheck -import sys @cppcheck.checker def cast(cfg, data): diff --git a/addons/misc.py b/addons/misc.py index 15a742c28f9..670d6152ff5 100644 --- a/addons/misc.py +++ b/addons/misc.py @@ -16,7 +16,7 @@ VERIFY_ACTUAL = [] def reportError(token, severity, msg, id): - if id == 'debug' and DEBUG == False: + if id == 'debug' and not DEBUG: return if VERIFY: VERIFY_ACTUAL.append(str(token.linenr) + ':' + id) diff --git a/addons/misra.py b/addons/misra.py index eaea81dfb9d..cea5596d47d 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 # -# MISRA C 2012 checkers -# Partially reused for "MISRA C++ 2008" checking +# MISRA C 2012 checkers (including amendment 1 and 2) # # Example usage of this addon (scan a sourcefile main.cpp) # cppcheck --dump main.cpp # python misra.py --rule-texts= main.cpp.dump # -# Limitations: This addon is released as open source. Rule texts can't be freely -# distributed. https://www.misra.org.uk/forum/viewtopic.php?f=56&t=1189 +# Limitations: This addon is released as open source. We are not allowed by +# MISRA to distribute rule texts openly. # # The MISRA standard documents may be obtained from https://www.misra.org.uk # @@ -23,7 +22,6 @@ import re import os import argparse -import codecs import string import copy @@ -46,7 +44,28 @@ def grouped(iterable, n): ['int', 'uint', 'int_least', 'uint_least', 'int_fast', 'uint_fast'], [8, 16, 32, 64])] +STDINT_H_DEFINES_MIN = ['%s%d_MIN' % (n, v) for n, v in itertools.product( + ['INT', 'INT_LEAST', 'INT_FAST',], + [8, 16, 32, 64])] + +STDINT_H_DEFINES_MAX = ['%s%d_MAX' % (n, v) for n, v in itertools.product( + ['INT', 'UINT','INT_LEAST','UINT_LEAST', 'INT_FAST', 'UINT_FAST',], + [8, 16, 32, 64])] + +STDINT_H_DEFINES_C = ['%s%d_C' % (n, v) for n, v in itertools.product( + ['INT', 'UINT'], + [8, 16, 32, 64])] + +INTTYPES_H_DEFINES = ['%s%d' % (n, v) for n, v in itertools.product( + ['PRId', 'PRIi', 'PRIo', 'PRIu', 'PRIx', 'PRIX', 'SCNd', + 'SCNi', 'SCNo', 'SCNu', 'SCNx', 'PRIdLEAST', 'PRIiLEAST', + 'PRIoLEAST', 'PRIuLEAST', 'PRIxLEAST', 'PRIXLEAST', + 'SCNdLEAST', 'SCNiLEAST', 'SCNoLEAST', 'SCNuLEAST', + 'SCNxLEAST', 'PRIdFAST', 'PRIiFAST', 'PRIoFAST', 'PRIuFAST', + 'PRIxFAST', 'PRIXFAST', 'SCNdFAST', 'SCNiFAST', 'SCNoFAST', + 'SCNuFAST', 'SCNxFAST', ], + [8, 16, 32, 64])] typeBits = { 'CHAR': None, 'SHORT': None, @@ -170,7 +189,8 @@ def rawlink(rawtoken): # Identifiers described in Section 7 "Library" of C99 Standard -# Based on ISO/IEC 9899 WF14/N1256 Annex B -- Library summary +# Based on ISO/IEC 9899:1999 (E) Annex B -- Library summary +# (https://www.dii.uchile.cl/~daespino/files/Iso_C_1999_definition.pdf) C99_STDLIB_IDENTIFIERS = { # B.1 Diagnostics 'assert.h': C90_STDLIB_IDENTIFIERS['assert.h'], @@ -221,9 +241,13 @@ def rawlink(rawtoken): 'float.h': C90_STDLIB_IDENTIFIERS['float.h'] + ['FLT_EVAL_METHOD'], # B.7 Format conversion of integer types 'inttypes.h': [ + 'PRIdMAX', 'PRIiMAX', 'PRIoMAX', 'PRIuMAX', 'PRIxMAX', 'PRIXMAX', + 'SCNdMAX', 'SCNiMAX', 'SCNoMAX', 'SCNuMAX', 'SCNxMAX', 'PRIdPTR', + 'PRIiPTR', 'PRIoPTR', 'PRIuPTR', 'PRIxPTR', 'PRIXPTR', 'SCNdPTR', + 'SCNiPTR', 'SCNoPTR', 'SCNuPTR', 'SCNxPTR', 'imaxdiv_t', 'imaxabs', 'imaxdiv', 'strtoimax', 'strtoumax', 'wcstoimax', 'wcstoumax', - ], + ] + INTTYPES_H_DEFINES, # B.8 Alternative spellings 'iso646.h': [ 'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not', 'not_eq', @@ -247,11 +271,12 @@ def rawlink(rawtoken): 'acoshl', 'asinh', 'asinhf', 'asinhl', 'atanh', 'atanhf', 'atanhl', 'cosh', 'coshf', 'coshl', 'sinh', 'sinhf', 'sinhl', 'tanh', 'tanhf', 'tanhl', 'expf', 'expl', 'exp2', 'exp2f', 'exp2l', 'expm1', 'expm1f', - 'expm1l', 'frexpf', 'frexpl', 'ilogb', 'ilogbf', 'ilogbl', 'float', + 'expm1l', 'frexpf', 'frexpl', 'ilogb', 'ilogbf', 'ilogbl', 'ldexpf', 'ldexpl', 'logf', 'logl', 'log10f', 'log10l', 'log1p', 'log1pf', 'log1pl', 'log2', 'log2f', 'log2l', 'logb', 'logbf', 'logbl', 'modff', 'modfl', 'scalbn', 'scalbnf', 'scalbnl', 'scalbln', 'scalblnf', - 'scalblnl', 'hypotl', 'powf', 'powl', 'sqrtf', 'sqrtl', 'erf', 'erff', + 'scalblnl','cbrt', 'cbrtf','cbrtl', 'fabs', 'fabsf', 'fabsl', + 'hypotl', 'hypotf', 'powf', 'powl', 'sqrtf', 'sqrtl', 'erf', 'erff', 'erfl', 'erfc', 'erfcf', 'erfcl', 'lgamma', 'lgammaf', 'lgammal', 'tgamma', 'tgammaf', 'tgammal', 'ceilf', 'ceill', 'floorf', 'floorl', 'nearbyint', 'nearbyintf', 'nearbyintl', 'rint', 'rintf', 'rintl', @@ -262,7 +287,7 @@ def rawlink(rawtoken): 'remquol', 'copysign', 'copysignf', 'copysignl', 'nan', 'nanf', 'nanl', 'nextafter', 'nextafterf', 'nextafterl', 'nexttoward', 'nexttowardf', 'nexttowardl', 'fdim', 'fdimf', 'fdiml', 'fmax', - 'fmaxf', 'fmaxl', 'fmin', 'fminf', 'fminl', 'fmal', 'isgreater', + 'fmaxf', 'fmaxl', 'fmin', 'fminf', 'fminl', 'fmaf','fmal', 'isgreater', 'isgreaterequal', 'isless', 'islessequal', 'islessgreater', 'isunordered', ], @@ -285,11 +310,11 @@ def rawlink(rawtoken): 'UINTMAX_MAX', 'PTRDIFF_MIN', 'PTRDIFF_MAX', 'SIG_ATOMIC_MIN', 'SIG_ATOMIC_MAX', 'SIZE_MAX', 'WCHAR_MIN', 'WCHAR_MAX', 'WINT_MIN', 'WINT_MAX', 'INTN_C', 'UINTN_C', 'INTMAX_C', 'UINTMAX_C', - ] + STDINT_TYPES, + ] + STDINT_TYPES + STDINT_H_DEFINES_MIN + STDINT_H_DEFINES_MAX + STDINT_H_DEFINES_C, # B.18 Input/output 'stdio.h': C90_STDLIB_IDENTIFIERS['stdio.h'] + [ 'mode', 'restrict', 'snprintf', 'vfscanf', 'vscanf', - 'vsnprintf', 'vsscanf', + 'vsnprintf', 'vsscanf','ftell' ], # B.19 General utilities 'stdlib.h': C90_STDLIB_IDENTIFIERS['stdlib.h'] + [ @@ -318,28 +343,154 @@ def rawlink(rawtoken): 'vfwprintf', 'vfwscanf', 'vswprintf', 'vswscanf', 'vwprintf', 'vwscanf', 'wprintf', 'wscanf', 'fgetwc', 'fgetws', 'fputwc', 'fputws', 'fwide', 'getwc', 'getwchar', 'putwc', 'putwchar', 'ungetwc', 'wcstod', - 'wcstof', 'double', 'int', 'long', 'long', 'long', 'wcscpy', 'wcsncpy', - 'wmemcpy', 'wmemmove', 'wcscat', 'wcsncat', 'wcscmp', 'wcscoll', + 'wcstof', 'wcstold', 'wcstol', 'wcstoll', 'wcstoul', 'wcstoull', 'wcscpy', + 'wcsncpy', 'wmemcpy', 'wmemmove', 'wcscat', 'wcsncat', 'wcscmp', 'wcscoll', 'wcsncmp', 'wcsxfrm', 'wmemcmp', 'wcschr', 'wcscspn', 'wcspbrk', 'wcsrchr', 'wcsspn', 'wcsstr', 'wcstok', 'wmemchr', 'wcslen', 'wmemset', 'wcsftime', 'btowc', 'wctob', 'mbsinit', 'mbrlen', 'mbrtowc', 'wcrtomb', 'mbsrtowcs', 'wcsrtombs', ], + # B.24 Wide character classification and mapping utilities + 'wctype.h': ['wint_t', 'wctrans_t', 'wctype_t', 'WEOF', + 'iswalnum', 'iswalpha', 'iswblank', 'iswcntrl', 'iswdigit', + 'iswgraph', 'iswlower', 'iswprint', 'iswpunct', 'iswspace', 'iswupper', + 'iswxdigit', 'iswctype', 'wctype', 'towlower', 'towupper', 'towctrans', + 'wctrans'], +} + +# Identifiers described in Section 7 "Library" of C11 Standard +# Based on ISO/IEC 9899:201x N1570 (Draft 12.04.2011) Annex B -- Library summary +# (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) +C11_STDLIB_IDENTIFIERS = { + # B.1 Diagnostics + 'assert.h': C99_STDLIB_IDENTIFIERS['assert.h']+ ['static_assert'], + # B.2 Complex + 'complex.h': C99_STDLIB_IDENTIFIERS['complex.h']+['__STDC_NO_COMPLEX__','CMPLX','CMPLXF','CMPLXL'], + # B.3 Character handling + 'ctype.h': C99_STDLIB_IDENTIFIERS['ctype.h'], + # B.4 Errors + 'errno.h': C99_STDLIB_IDENTIFIERS['errno.h']+['__STDC_WANT_LIB_EXT1__', 'errno_t'], + # B.5 Floating-point environment + 'fenv.h': C99_STDLIB_IDENTIFIERS['fenv.h'], + # B.6 Characteristics of floating types + 'float.h': C99_STDLIB_IDENTIFIERS['float.h']+[ + 'FLT_HAS_SUBNORM','DBL_HAS_SUBNORM','LDBL_HAS_SUBNORM', + 'FLT_DECIMAL_DIG','DBL_DECIMAL_DIG','LDBL_DECIMAL_DIG', + 'FLT_TRUE_MIN','DBL_TRUE_MIN','LDBL_TRUE_MIN'], + # B.7 Format conversion of integer types + 'inttypes.h': C99_STDLIB_IDENTIFIERS["inttypes.h"], + # B.8 Alternative spellings + 'iso646.h': C99_STDLIB_IDENTIFIERS["iso646.h"], + # B.9 Size of integer types + 'limits.h': C99_STDLIB_IDENTIFIERS['limits.h'], + # B.10 Localization + 'locale.h': C99_STDLIB_IDENTIFIERS['locale.h'], + # B.11 Mathematics + 'math.h': C99_STDLIB_IDENTIFIERS['math.h'], + # B.12 Nonlocal jumps + 'setjmp.h': C99_STDLIB_IDENTIFIERS['setjmp.h'], + # B.13 Signal handling + 'signal.h': C99_STDLIB_IDENTIFIERS['signal.h'], + # B.14 Alignment + 'stdalign.h': ['alignas','__alignas_is_defined'], + # B.15 Variable arguments + 'stdarg.h': C99_STDLIB_IDENTIFIERS['stdarg.h'], + # B.16 Atomics + 'stdatomic.h': ['ATOMIC_BOOL_LOCK_FREE', 'ATOMIC_CHAR_LOCK_FREE', + 'ATOMIC_CHAR16_T_LOCK_FREE', 'ATOMIC_CHAR32_T_LOCK_FREE', 'ATOMIC_WCHAR_T_LOCK_FREE', + 'ATOMIC_SHORT_LOCK_FREE', 'ATOMIC_INT_LOCK_FREE', 'ATOMIC_LONG_LOCK_FREE', + 'ATOMIC_LLONG_LOCK_FREE', 'ATOMIC_POINTER_LOCK_FREE', 'ATOMIC_FLAG_INIT', + 'memory_order', 'atomic_flag', 'memory_order_relaxed', 'memory_order_consume', + 'memory_order_acquire', 'memory_order_release', 'memory_order_acq_rel', 'memory_order_seq_cst', + 'atomic_bool', 'atomic_char', 'atomic_schar', 'atomic_uchar', 'atomic_short', 'atomic_ushort', + 'atomic_int', 'atomic_uint', 'atomic_long', 'atomic_ulong', 'atomic_llong', 'atomic_ullong', + 'atomic_char16_t', 'atomic_char32_t', 'atomic_wchar_t', 'atomic_int_least8_t', + 'atomic_uint_least8_t', 'atomic_int_least16_t', 'atomic_uint_least16_t', + 'atomic_int_least32_t', 'atomic_uint_least32_t', 'atomic_int_least64_t', + 'atomic_uint_least64_t', 'atomic_int_fast8_t', 'atomic_uint_fast8_t', + 'atomic_int_fast16_t', 'atomic_uint_fast16_t', 'atomic_int_fast32_t', + 'atomic_uint_fast32_t', 'atomic_int_fast64_t', 'atomic_uint_fast64_t', + 'atomic_intptr_t', 'atomic_uintptr_t', 'atomic_size_t', 'atomic_ptrdiff_t', + 'atomic_intmax_t', 'atomic_uintmax_t', 'ATOMIC_VAR_INIT', 'type kill_dependency', + 'atomic_thread_fence', 'atomic_signal_fence', 'atomic_is_lock_free', + 'atomic_store', 'atomic_store_explicit', 'atomic_load', 'atomic_load_explicit', + 'atomic_exchange', 'atomic_exchange_explicit', 'atomic_compare_exchange_strong', + 'atomic_compare_exchange_strong_explicit', 'atomic_compare_exchange_weak', + 'atomic_compare_exchange_weak_explicit', 'atomic_fetch_key', 'atomic_fetch_key_explicit', + 'atomic_flag_test_and_set', 'atomic_flag_test_and_set_explicit', + 'atomic_flag_clear', 'atomic_flag_clear_explicit', ], + # B.17 Boolean type and values + 'stdbool.h': C99_STDLIB_IDENTIFIERS['stdbool.h'], + # B.18 Common definitions + 'stddef.h': C99_STDLIB_IDENTIFIERS['stddef.h'] + + ['max_align_t','__STDC_WANT_LIB_EXT1__', 'rsize_t'], + # B.19 Integer types + 'stdint.h': C99_STDLIB_IDENTIFIERS['stdint.h']+ + ['__STDC_WANT_LIB_EXT1__', 'RSIZE_MAX'], + # B.20 Input/output + 'stdio.h': C99_STDLIB_IDENTIFIERS['stdio.h'] + + ['__STDC_WANT_LIB_EXT1__', 'L_tmpnam_s', 'TMP_MAX_S', 'errno_t', 'rsize_t', + 'tmpfile_s', 'tmpnam_s', 'fopen_s', 'freopen_s', 'fprintf_s', 'fscanf_s', + 'printf_s','scanf_s','snprintf_s','sprintf_s','sscanf_s','vfprintf_s', + 'vfscanf_s', 'vsprintf_s', 'vsscanf_s', 'gets_s' + ], + # B.21 General utilities + 'stdlib.h': C99_STDLIB_IDENTIFIERS['stdlib.h'] + + ['constraint_handler_t', 'set_constraint_handler_s', 'abort_handler_s', + 'ignore_handler_s', 'getenv_s', 'bsearch_s', 'qsort_s', 'wctomb_s', + 'mbstowcs_s', 'wcstombs_s'], + # B.22 Noretrun + 'stdnoreturn.h': ['noreturn'], + # B.23 String handling + 'string.h': C99_STDLIB_IDENTIFIERS['string.h'] + + ['memcpy_s', 'memmoce_s', 'strcpy_s', 'strncpy_s','strcat_s', + 'strtok_s', 'memset_s', 'strerror_s', 'strerrorlen_s', 'strnlen_s'], + # B.24 Type-generic math + 'tgmath.h': C99_STDLIB_IDENTIFIERS['tgmath.h'], + # B.25 Threads + 'threads.h': ['thread_local', 'ONCE_FLAG_INIT', 'TSS_DTOR_ITERATIONS', + 'cnd_t', 'thrd_t', 'tss_t', 'mtx_t', 'tss_dtor_t', 'thrd_start_t', + 'once_flag', 'mtx_plain', 'mtx_recursive', 'mtx_timed', 'thrd_timedout', + 'thrd_success', 'thrd_busy', 'thrd_error', 'thrd_nomem', 'call_once', + 'cnd_broadcast', 'cnd_destroy','cnd_init', 'cnd_signal', 'cnd_timedwait', + 'cnd_wait','mtx_destroy', 'mtx_init', 'mtx_lock', 'mtx_timedlock', + 'mtx_trylock', 'mtx_unlock', 'thrd_create', 'thrd_current', + 'thrd_detach', 'thrd_equal', 'thrd_exit', 'thrd_join', 'thrd_sleep', + 'thrd_yield', 'tss_create', 'tss_delete', 'tss_get', 'tss_set' ], + # B.26 Date and time + 'time.h': C99_STDLIB_IDENTIFIERS['time.h'] + [ + 'asctime_s', 'ctime_s', 'gmtime_s', 'localtime_s' + ], + # B.27 Unicode utilities + 'uchar.h': ['mbstate_t', 'size_t', 'char16_t', 'char32_t', + 'mbrtoc16', 'c16rtomb', 'mbrtoc32', 'c32rtomb' + ], + # B.28 Extended multibyte/wide character utilities + 'wchar.h': C99_STDLIB_IDENTIFIERS["wchar.h"]+[ + 'fwprintf_s', 'fwscanf_s', 'snwprintf_s', 'swprintf_s', 'swscanf_s', + 'vfwprintf_s', 'vfwscanf_s', 'vsnwprintf_s', 'vswprintf_s', 'vswscanf_s', + 'vwprintf_s', 'vwscanf_s', 'wprintf_s', 'wscanf_s', 'wcscpy_s', 'wcsncpy_s', + 'wmemcpy_s', 'wmemmove_s', 'wcscat_s', 'wcsncat_s', 'wcstok_s', 'wcsnlen_s', + 'wcrtomb_s', 'mbsrtowcs_s', 'wcsrtombs_s', + ], + # B.29 Wide character classification and mapping utilities + 'wctype.h': C99_STDLIB_IDENTIFIERS['wctype.h'], } +def getStdLib(standard): + if standard == 'c89': + return C90_STDLIB_IDENTIFIERS + if standard == 'c99': + return C99_STDLIB_IDENTIFIERS + return C11_STDLIB_IDENTIFIERS def isStdLibId(id_, standard='c99'): - id_lists = [] - if standard == 'c89': - id_lists = C90_STDLIB_IDENTIFIERS.values() - elif standard in ('c99', 'c11'): - id_lists = C99_STDLIB_IDENTIFIERS.values() + id_lists = getStdLib(standard).values() for l in id_lists: if id_ in l: return True return False - # Reserved keywords defined in ISO/IEC9899:1990 -- ch 6.1.1 C90_KEYWORDS = { 'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', @@ -350,16 +501,23 @@ def isStdLibId(id_, standard='c99'): } -# Reserved keywords defined in ISO/IEC 9899 WF14/N1256 -- ch. 6.4.1 +# Reserved keywords defined in Section 6.4.1 "Language" of C99 Standard +# Based on ISO/IEC 9899:1999 (E) 6.4.1 Keywords +# Adding the expanding macros from Section 7 too +# (https://www.dii.uchile.cl/~daespino/files/Iso_C_1999_definition.pdf) C99_ADDED_KEYWORDS = { 'inline', 'restrict', '_Bool', '_Complex', '_Imaginary', 'bool', 'complex', 'imaginary' } +# Reserved keywords defined in Section 6.4.1 "Language" of C11 Standard +# Based on ISO/IEC 9899:201x N1570 (Draft 12.04.2011) 6.4.1 Keywords +# Adding the expanding macros from Section 7 too +# (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) C11_ADDED_KEYWORDS = { '_Alignas', '_Alignof', '_Atomic', '_Generic', '_Noreturn', - '_Statis_assert', '_Thread_local' , - 'alignas', 'alignof', 'noreturn', 'static_assert' + '_Static_assert', '_Thread_local' , + 'alignas', 'alignof', 'noreturn', 'static_assert','thread_local' } def isKeyword(keyword, standard='c99'): @@ -430,11 +588,11 @@ def is_composite_expr(expr, composite_operator=False): return False if not composite_operator: - if (expr.str in ('+', '-', '*', '/', '%', '&', '|', '^', '>>', "<<", "?", ":", '~')): - return is_composite_expr(expr.astOperand1,True) or is_composite_expr(expr.astOperand2, True) if expr.str == '?' and simpleMatch(expr.astOperand2, ':'): colon = expr.astOperand2 return is_composite_expr(colon.astOperand1,True) or is_composite_expr(colon.astOperand2, True) + if (expr.str in ('+', '-', '*', '/', '%', '&', '|', '^', '>>', "<<", "?", ":", '~')): + return is_composite_expr(expr.astOperand1,True) or is_composite_expr(expr.astOperand2, True) return False # non constant expression? @@ -466,9 +624,15 @@ def getEssentialTypeCategory(expr): return expr.valueType.sign if expr.valueType and expr.valueType.typeScope and expr.valueType.typeScope.className: return "enum<" + expr.valueType.typeScope.className + ">" + # Unwrap membership, dereferences and array indexing vartok = expr - while simpleMatch(vartok, '[') or (vartok and vartok.str == '*' and vartok.astOperand2 is None): - vartok = vartok.astOperand1 + while True: + if simpleMatch(vartok, '[') or (vartok and vartok.str == '*' and vartok.astOperand2 is None): + vartok = vartok.astOperand1 + elif simpleMatch(vartok, '.'): + vartok = vartok.astOperand2 + else: + break if vartok and vartok.variable: typeToken = vartok.variable.typeStartToken while typeToken and typeToken.isName: @@ -489,6 +653,13 @@ def getEssentialTypeCategory(expr): return 'char' return expr.valueType.sign + if (expr.isCast and expr.str == "("): + castTok = expr.next + while castTok.isName or castTok.str == "*": + if castTok.str == 'char' and not castTok.isSigned and not castTok.isUnsigned: + return 'char' + castTok = castTok.next + if expr.valueType: return expr.valueType.sign return None @@ -588,8 +759,7 @@ def getEssentialType(expr): return e if bitsOfEssentialType(e2) >= bitsOfEssentialType(e1): return e2 - else: - return e1 + return e1 elif expr.str == "~": e1 = getEssentialType(expr.astOperand1) @@ -622,7 +792,6 @@ def bitsOfEssentialType(ty): def get_function_pointer_type(tok): ret = '' - par = 0 while tok and (tok.isName or tok.str == '*'): ret += ' ' + tok.str tok = tok.next @@ -634,7 +803,8 @@ def get_function_pointer_type(tok): ret += '(' tok = tok.next.next while tok and (tok.str not in '()'): - ret += ' ' + tok.str + if tok.varId is None: + ret += ' ' + tok.str tok = tok.next if (tok is None) or tok.str != ')': return None @@ -700,7 +870,28 @@ def getForLoopExpressions(forToken): lpar.astOperand2.astOperand2.astOperand2] -def getForLoopCounterVariables(forToken): +def get_function_scope(cfg, func): + if func: + for scope in cfg.scopes: + if scope.function == func: + return scope + return None + + +def is_variable_changed(start_token, end_token, var): + """Check if variable is updated between body_start and body_end""" + tok = start_token + while tok != end_token: + if tok.isAssignmentOp: + vartok = tok.astOperand1 + while vartok.astOperand1: + vartok = vartok.astOperand1 + if vartok and vartok.variable == var: + return True + tok = tok.next + return False + +def getForLoopCounterVariables(forToken, cfg): """ Return a set of Variable objects defined in ``for`` statement and satisfy requirements to loop counter term from section 8.14 of MISRA document. @@ -726,9 +917,43 @@ def getForLoopCounterVariables(forToken): if tn.next and countSideEffectsRecursive(tn.next) > 0: vars_modified.add(tn.variable) elif tn.previous and tn.previous.str in ('++', '--'): - vars_modified.add(tn.variable) - if cur_clause == 1 and tn.isAssignmentOp and tn.astOperand1.variable: - vars_initialized.add(tn.astOperand1.variable) + tn_ast = tn.astParent + if tn_ast and tn_ast == tn.previous: + vars_modified.add(tn.variable) + elif tn_ast and tn_ast.str == '.' and tn_ast.astOperand2 and tn_ast.astOperand2.variable: + vars_modified.add(tn_ast.astOperand2.variable) + if cur_clause == 1 and tn.isAssignmentOp: + var_token = tn.astOperand1 + while var_token and var_token.str == '.': + var_token = var_token.astOperand2 + if var_token and var_token.variable: + vars_initialized.add(var_token.variable) + if cur_clause == 1 and tn.isName and tn.next.str == '(': + function_args_in_init = getArguments(tn.next) + function_scope = get_function_scope(cfg, tn.function) + for arg_nr in range(len(function_args_in_init)): + init_arg = function_args_in_init[arg_nr] + if init_arg is None or not init_arg.isUnaryOp('&'): + continue + var_token = init_arg.astOperand1 + while var_token and var_token.str == '.': + var_token = var_token.astOperand2 + if var_token is None or var_token.variable is None: + continue + changed = False + if function_scope is None: + changed = True + elif tn.function is None: + changed = True + else: + function_body_start = function_scope.bodyStart + function_body_end = function_scope.bodyEnd + args = tn.function.argument[arg_nr + 1] + if function_scope is None or is_variable_changed(function_body_start, function_body_end, args): + changed = True + if changed: + vars_initialized.add(var_token.variable) + if tn.str == ';': cur_clause += 1 tn = tn.next @@ -762,6 +987,7 @@ def isFloatCounterInWhileLoop(whileToken): lpar = whileToken.next rpar = lpar.link counterTokens = findCounterTokens(lpar.astOperand2) + tok_varid = tuple(tok.varId for tok in counterTokens if tok.varId) whileBodyStart = None if simpleMatch(rpar, ') {'): whileBodyStart = rpar.next @@ -772,13 +998,21 @@ def isFloatCounterInWhileLoop(whileToken): token = whileBodyStart while token != whileBodyStart.link: token = token.next - for counterToken in counterTokens: - if not counterToken.valueType or not counterToken.valueType.isFloat(): - continue - if token.isAssignmentOp and token.astOperand1.str == counterToken.str: + if not token.varId: + continue + if token.varId not in tok_varid: + continue + if not token.astParent or not token.valueType or not token.valueType.isFloat(): + continue + parent = token.astParent + if parent.str in ('++', '--'): + return True + while parent: + if parent.isAssignmentOp and parent.str != "=" and parent.astOperand1 == token: return True - if token.str == counterToken.str and token.astParent and token.astParent.str in ('++', '--'): + if parent.str == "=" and parent.astOperand1.str == token.str and parent.astOperand1 != token: return True + parent = parent.astParent return False @@ -829,6 +1063,14 @@ def isConstantExpression(expr): return False return True +def isUnknownConstantExpression(expr): + if expr.isName and not isEnumConstant(expr) and expr.variable is None: + return True + if expr.astOperand1 and isUnknownConstantExpression(expr.astOperand1): + return True + if expr.astOperand2 and isUnknownConstantExpression(expr.astOperand2): + return True + return False def isUnsignedInt(expr): return expr and expr.valueType and expr.valueType.type in ('short', 'int') and expr.valueType.sign == 'unsigned' @@ -1100,11 +1342,12 @@ def getAddonRules(): """Returns dict of MISRA rules handled by this addon.""" addon_rules = [] compiled = re.compile(r'.*def[ ]+misra_([0-9]+)_([0-9]+)[(].*') - for line in open(__file__): - res = compiled.match(line) - if res is None: - continue - addon_rules.append(res.group(1) + '.' + res.group(2)) + with open(__file__) as f: + for line in f: + res = compiled.match(line) + if res is None: + continue + addon_rules.append(res.group(1) + '.' + res.group(2)) return addon_rules @@ -1207,7 +1450,7 @@ def remove_file_prefix(file_path, prefix): return result -class Rule(object): +class Rule(): """Class to keep rule text and metadata""" MISRA_SEVERITY_LEVELS = ['Required', 'Mandatory', 'Advisory'] @@ -1241,7 +1484,7 @@ def __repr__(self): return "%d.%d (%s)" % (self.num1, self.num2, self.misra_severity) -class MisraSettings(object): +class MisraSettings(): """Hold settings for misra.py script.""" __slots__ = ["verify", "quiet", "show_summary"] @@ -1282,17 +1525,17 @@ def __init__(self, settings, stdversion="c89"): self.settings = settings # Test validation rules lists - self.verify_expected = list() - self.verify_actual = list() + self.verify_expected = [] + self.verify_actual = [] # List of formatted violation messages - self.violations = dict() + self.violations = {} # if --rule-texts is specified this dictionary # is loaded with descriptions of each rule # by rule number (in hundreds). # ie rule 1.2 becomes 102 - self.ruleTexts = dict() + self.ruleTexts = {} self.ruleText_filename = None # Dictionary of dictionaries for rules to suppress @@ -1303,13 +1546,13 @@ def __init__(self, settings, stdversion="c89"): # or an item of None which indicates suppress rule for the entire file. # The line and symbol name tuple may have None as either of its elements but # should not be None for both. - self.suppressedRules = dict() + self.suppressedRules = {} # Prefix to ignore when matching suppression files. self.filePrefix = None # Number of all violations suppressed per rule - self.suppressionStats = dict() + self.suppressionStats = {} self.stdversion = stdversion @@ -1336,8 +1579,7 @@ def __repr__(self): def get_num_significant_naming_chars(self, cfg): if cfg.standards and cfg.standards.c == "c89": return 31 - else: - return 63 + return 63 def _save_ctu_summary_typedefs(self, dumpfile, typedef_info): if self._ctu_summary_typedefs: @@ -1438,7 +1680,7 @@ def _save_ctu_summary_usage(self, dumpfile, cfg): for token in cfg.tokenlist: if not token.isName: continue - if token.function and token.scope.isExecutable: + if token.function and token != token.function.tokenDef: if (not token.function.isStatic) and (token.str not in names): names.append({'name': token.str, 'file': token.file}) elif token.variable: @@ -1451,11 +1693,20 @@ def _save_ctu_summary_usage(self, dumpfile, cfg): cppcheckdata.reportSummary(dumpfile, 'MisraUsage', names) + def misra_1_2(self, cfg): + # gcc language extensions: https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html + for token in cfg.tokenlist: + if simpleMatch(token, '? :'): + self.reportError(token, 1, 2) + elif simpleMatch(token, '( {') and simpleMatch(token.next.link.previous, '; } )'): + self.reportError(token, 1, 2) + + def misra_1_4(self, cfg): for token in cfg.tokenlist: if token.str in ('_Atomic', '_Noreturn', '_Generic', '_Thread_local', '_Alignas', '_Alignof'): self.reportError(token, 1, 4) - if token.str.endswith('_s') and isFunctionCall(token.next): + if token.str.endswith('_s') and isFunctionCall(token.next, cfg.standards.c): # See C specification C11 - Annex K, page 578 if token.str in ('tmpfile_s', 'tmpnam_s', 'fopen_s', 'freopen_s', 'fprintf_s', 'fscanf_s', 'printf_s', 'scanf_s', 'snprintf_s', 'sprintf_s', 'sscanf_s', 'vfprintf_s', 'vfscanf_s', 'vprintf_s', 'vscanf_s', @@ -1495,17 +1746,29 @@ def misra_2_4(self, dumpfile, cfg): self._save_ctu_summary_tagnames(dumpfile, cfg) def misra_2_5(self, dumpfile, cfg): - used_macros = list() + used_macros = [] + unused_macro = {} for m in cfg.macro_usage: used_macros.append(m.name) - summary = [] for directive in cfg.directives: - res = re.match(r'#define[ \t]+([a-zA-Z_][a-zA-Z_0-9]*).*', directive.str) - if res: - macro_name = res.group(1) - summary.append({'name': macro_name, 'used': (macro_name in used_macros), 'file': directive.file, 'line': directive.linenr, 'column': directive.column}) - if len(summary) > 0: - cppcheckdata.reportSummary(dumpfile, 'MisraMacro', summary) + res_define = re.match(r'#define[ \t]+([a-zA-Z_][a-zA-Z_0-9]*).*', directive.str) + res_undef = re.match(r'#undef[ \t]+([a-zA-Z_][a-zA-Z_0-9]*).*', directive.str) + if res_define: + macro_name = res_define.group(1) + unused_macro[macro_name] = {'name': macro_name, 'used': (macro_name in used_macros), + 'file': directive.file, 'line': directive.linenr, 'column': directive.column} + elif res_undef: + macro_name = res_undef.group(1) + # assuming that if we have #undef, we also have #define somewhere + if macro_name in unused_macro: + unused_macro[macro_name]['used'] = True + else: + unused_macro[macro_name] = {'name': macro_name, 'used': True, 'file': directive.file, + 'line': directive.linenr, 'column': directive.column} + used_macros.append(macro_name) + + if unused_macro: + cppcheckdata.reportSummary(dumpfile, 'MisraMacro', list(unused_macro.values())) def misra_2_7(self, data): for func in data.functions: @@ -1513,7 +1776,7 @@ def misra_2_7(self, data): if len(func.argument) == 0: continue # Setup list of function parameters - func_param_list = list() + func_param_list = [] for arg in func.argument: func_arg = func.argument[arg] if func_arg.typeStartToken and func_arg.typeStartToken.str == '...': @@ -1559,20 +1822,6 @@ def misra_3_1(self, rawTokens): self.reportError(token, 3, 1) break - def misra_3_2(self, rawTokens): - for token in rawTokens: - if token.str.startswith('//'): - # Check for comment ends with trigraph which might be replaced - # by a backslash. - if token.str.endswith('??/'): - self.reportError(token, 3, 2) - # Check for comment which has been merged with subsequent line - # because it ends with backslash. - # The last backslash is no more part of the comment token thus - # check if next token exists and compare line numbers. - elif (token.next is not None) and (token.linenr == token.next.linenr): - self.reportError(token, 3, 2) - def misra_4_1(self, rawTokens): for token in rawTokens: if (token.str[0] != '"') and (token.str[0] != '\''): @@ -1599,8 +1848,7 @@ def misra_4_1(self, rawTokens): if (isHexEscapeSequence(sequence) or isOctalEscapeSequence(sequence) or isSimpleEscapeSequence(sequence)): continue - else: - self.reportError(token, 4, 1) + self.reportError(token, 4, 1) def misra_4_2(self, rawTokens): for token in rawTokens: @@ -1754,7 +2002,7 @@ def misra_6_1(self, data): for token in data.tokenlist: if not token.valueType: continue - if token.valueType.bits == 0: + if token.valueType.bits is None: continue if not token.variable: continue @@ -1766,7 +2014,7 @@ def misra_6_1(self, data): if data.standards.c == 'c89': if token.valueType.type != 'int' and not isUnsignedType(token.variable.typeStartToken.str): self.reportError(token, 6, 1) - elif data.standards.c == 'c99': + elif data.standards.c in ('c99', 'c11', 'c17', 'c18'): if token.valueType.type == 'bool': continue @@ -1811,7 +2059,9 @@ def misra_7_2(self, data): self.reportError(token, 7, 2) def misra_7_3(self, rawTokens): - compiled = re.compile(r'^[0-9.]+[Uu]*l+[Uu]*$') + # Match decimal digits, hex digits, decimal point, and e/E p/P floating + # point constant exponent separators. + compiled = re.compile(r'^(0[xX])?[0-9a-fA-FpP.]+[Uu]*l+[Uu]*$') for tok in rawTokens: if compiled.match(tok.str): self.reportError(tok, 7, 3) @@ -1839,7 +2089,7 @@ def reportErrorIfVariableIsNotConst(variable, stringLiteral): self.reportError(token, 7, 4) # Check use as function parameter - if isFunctionCall(token) and token.astOperand1 and token.astOperand1.function: + if isFunctionCall(token, data.standards.c) and token.astOperand1 and token.astOperand1.function: functionDeclaration = token.astOperand1.function if functionDeclaration.tokenDef: @@ -1985,7 +2235,10 @@ def checkDefinitionArgumentsViolations(func, startCall, endCall): rawTokensFollowingPtr[2].str == ')'): self.reportError(var.nameToken, 8, 2) - + def insert_in_dict(self, dict_name,key, value): + if key not in dict_name: + dict_name[key] = [] + dict_name[key].append(value) def misra_8_4(self, cfg): for func in cfg.functions: if func.isStatic: @@ -1999,10 +2252,8 @@ def misra_8_4(self, cfg): if func.tokenDef.str == 'main': continue self.reportError(func.tokenDef, 8, 4) - - extern_vars = [] - var_defs = [] - + extern_var_with_def = {} + extern_var_without_def = {} for var in cfg.variables: if not var.isGlobal: continue @@ -2010,13 +2261,30 @@ def misra_8_4(self, cfg): continue if var.nameToken is None: continue - if var.isExtern: - extern_vars.append(var.nameToken.str) + tok = var.nameToken + if tok.next.str == ";": + if tok.next.isSplittedVarDeclEq: + self.insert_in_dict(extern_var_with_def, tok.str, tok) + else: + self.insert_in_dict(extern_var_without_def, tok.str, tok) else: - var_defs.append(var.nameToken) - for vartok in var_defs: - if vartok.str not in extern_vars: - self.reportError(vartok, 8, 4) + self.insert_in_dict(extern_var_without_def, var.nameToken.str, var.nameToken) + + for var in extern_var_with_def: + if var not in extern_var_without_def: + for t in extern_var_with_def[var]: + self.reportError(t, 8, 4) + + for var_str, var_tok in extern_var_without_def.items(): + warn = True + if var_str not in extern_var_with_def: + for t in var_tok: + if t.variable.isExtern: + warn = False + break + if warn: + for t in var_tok: + self.reportError(t, 8, 4) def misra_8_5(self, dumpfile, cfg): self._save_ctu_summary_identifiers(dumpfile, cfg) @@ -2204,10 +2472,9 @@ def get_category(essential_type): rhs_category = get_category(rhs) if lhs_category and rhs_category and lhs_category != rhs_category and rhs_category not in ('signed','unsigned'): self.reportError(tok, 10, 3) - if bitsOfEssentialType(lhs) < bitsOfEssentialType(rhs): + if bitsOfEssentialType(lhs) < bitsOfEssentialType(rhs) and (lhs != "bool" or tok.astOperand2.str not in ('0','1')): self.reportError(tok, 10, 3) - def misra_10_4(self, data): op = {'+', '-', '*', '/', '%', '&', '|', '^', '+=', '-=', ':'} for token in data.tokenlist: @@ -2301,6 +2568,9 @@ def misra_10_6(self, data): e = getEssentialType(token.astOperand2) if not e: continue + if e == "char" and vt1.type == "int": + # When arithmetic operations are performed on char values, they are usually promoted to int + continue lhsbits = vt1.bits if vt1.bits else bitsOfEssentialType(vt1.type) if lhsbits > bitsOfEssentialType(e): self.reportError(token, 10, 6) @@ -2430,6 +2700,20 @@ def misra_11_3(self, data): self.reportError(token, 11, 3) def misra_11_4(self, data): + # Get list of macro definitions + macros = {} + for directive in data.directives: + #define X ((peripheral_t *)0x40000U) + res = re.match(r'#define ([A-Za-z0-9_]+).*', directive.str) + if res: + if res.group(1) in macros: + macros[res.group(1)].append(directive) + else: + macros[res.group(1)] = [directive] + + # If macro definition is non-compliant then warn about the macro definition instead of + # the macro usages. To reduce diagnostics for a non-compliant macro. + bad_macros = [] for token in data.tokenlist: if not isCast(token): continue @@ -2440,6 +2724,17 @@ def misra_11_4(self, data): if vt2.pointer > 0 and vt1.pointer == 0 and (vt1.isIntegral() or vt1.isEnum()) and vt2.type != 'void': self.reportError(token, 11, 4) elif vt1.pointer > 0 and vt2.pointer == 0 and (vt2.isIntegral() or vt2.isEnum()) and vt1.type != 'void': + if token.macroName is not None and \ + token.macroName == token.astOperand1.macroName and \ + token.astOperand1.isInt and \ + token.link.previous.str == '*' and \ + token.macroName == token.link.previous.macroName and \ + token.macroName in macros and \ + len(macros[token.macroName]) == 1: + if token.macroName not in bad_macros: + bad_macros.append(token.macroName) + self.reportError(macros[token.macroName][0], 11, 4) + continue self.reportError(token, 11, 4) def misra_11_5(self, data): @@ -2467,13 +2762,11 @@ def misra_11_6(self, data): for token in data.tokenlist: if not isCast(token): continue - if token.astOperand1.astOperand1: - continue vt1 = token.valueType vt2 = token.astOperand1.valueType if not vt1 or not vt2: continue - if vt1.pointer == 1 and vt1.type == 'void' and vt2.pointer == 0 and token.astOperand1.str != "0": + if vt1.pointer == 1 and vt1.type == 'void' and vt2.pointer == 0 and token.astOperand1.getKnownIntValue() != 0: self.reportError(token, 11, 6) elif vt1.pointer == 0 and vt1.type != 'void' and vt2.pointer == 1 and vt2.type == 'void': self.reportError(token, 11, 6) @@ -2621,42 +2914,61 @@ def misra_12_3(self, data): if prev.str == ';': self.reportError(token, 12, 3) break - elif prev.str in ')}]': - prev = prev.link - elif prev.str in '({[': + if prev.str in '({[': break + if prev.str in ')}]': + prev = prev.link prev = prev.previous + def misra_12_4_check_expr(self, expr): + if not expr.astOperand2 or not expr.astOperand1: + return + if expr.valueType is None: + return + if expr.valueType.sign is None or expr.valueType.sign != 'unsigned': + return + if expr.valueType.pointer > 0: + return + if not expr.valueType.isIntegral(): + return + op1 = expr.astOperand1.getKnownIntValue() + if op1 is None: + return + op2 = expr.astOperand2.getKnownIntValue() + if op2 is None: + return + bits = bitsOfEssentialType('unsigned ' + expr.valueType.type) + if bits <= 0 or bits >= 64: + return + max_value = (1 << bits) - 1 + if not is_constant_integer_expression(expr): + return + if expr.str == '+' and op1 + op2 > max_value: + self.reportError(expr, 12, 4) + elif expr.str == '-' and op1 - op2 < 0: + self.reportError(expr, 12, 4) + elif expr.str == '*' and op1 * op2 > max_value: + self.reportError(expr, 12, 4) def misra_12_4(self, cfg): - for expr in cfg.tokenlist: - if not expr.astOperand2 or not expr.astOperand1: - continue - if expr.valueType is None: - continue - if expr.valueType.sign is None or expr.valueType.sign != 'unsigned': - continue - if expr.valueType.pointer > 0: - continue - if not expr.valueType.isIntegral(): - continue - op1 = expr.astOperand1.getKnownIntValue() - if op1 is None: - continue - op2 = expr.astOperand2.getKnownIntValue() - if op2 is None: - continue - bits = bitsOfEssentialType('unsigned ' + expr.valueType.type) - if bits <= 0 or bits >= 64: - continue - max_value = (1 << bits) - 1 - if not is_constant_integer_expression(expr): - continue - if expr.str == '+' and op1 + op2 > max_value: - self.reportError(expr, 12, 4) - elif expr.str == '-' and op1 - op2 < 0: - self.reportError(expr, 12, 4) - elif expr.str == '*' and op1 * op2 > max_value: - self.reportError(expr, 12, 4) + if not cfg.tokenlist: + return + expr = cfg.tokenlist[0] + while expr.next: + expr = expr.next + if expr.str == "?" and expr.astOperand2.str == ":": + known_value = expr.astOperand1.getKnownIntValue() + if known_value == 1: + tok = expr + while tok != expr.astOperand2: + self.misra_12_4_check_expr(tok) + tok = tok.next + expr = tok + while expr.str not in (";", "{", "}"): + expr = expr.next + continue + if known_value == 0: + expr = expr.astOperand2 + self.misra_12_4_check_expr(expr) def misra_13_1(self, data): @@ -2677,8 +2989,7 @@ def misra_13_1(self, data): if tn and tn.next and tn.next.str == '=': tn = tn.next.next continue - else: - break + break if tn.str == '.' and tn.next and tn.next.isName: tn = tn.next if tn.next and tn.next.str == '=': @@ -2741,13 +3052,14 @@ def misra_14_2(self, data): if not expressions: continue if expressions[0] and not expressions[0].isAssignmentOp: - self.reportError(token, 14, 2) + if expressions[0].str != "(" or not expressions[0].previous.isName: + self.reportError(token, 14, 2) if countSideEffectsRecursive(expressions[1]) > 0: self.reportError(token, 14, 2) if countSideEffectsRecursive(expressions[2]) > 1: self.reportError(token, 14, 2) - counter_vars_first_clause, counter_vars_exit_modified = getForLoopCounterVariables(token) + counter_vars_first_clause, counter_vars_exit_modified = getForLoopCounterVariables(token, data) if len(counter_vars_exit_modified) == 0: # if it's not possible to identify a loop counter, all 3 clauses must be empty for idx in range(len(expressions)): @@ -2782,7 +3094,9 @@ def misra_14_4(self, data): continue if not token.astOperand1 or not (token.astOperand1.str in ['if', 'while']): continue - if not isBoolExpression(token.astOperand2): + if isBoolExpression(token.astOperand2): + continue + if token.astOperand2.valueType: self.reportError(token, 14, 4) def misra_15_1(self, data): @@ -2990,15 +3304,15 @@ def misra_16_3(self, rawTokens): STATE_OK = 2 # a case/default is allowed (we have seen 'break;'/'comment'/'{'/attribute) STATE_SWITCH = 3 # walking through switch statement scope - define = None + directive = None state = STATE_NONE end_switch_token = None # end '}' for the switch scope for token in rawTokens: - if simpleMatch(token, '# define'): - define = token - if define: - if token.linenr != define.linenr: - define = None + if simpleMatch(token, '# define') or simpleMatch(token, '# pragma'): + directive = token + if directive: + if token.linenr != directive.linenr: + directive = None else: continue @@ -3064,7 +3378,7 @@ def misra_16_5(self, data): for token in data.tokenlist: if token.str != 'default': continue - if token.previous and token.previous.str == '{': + if token.previous and (token.previous.str == '{'): continue tok2 = token while tok2: @@ -3102,7 +3416,7 @@ def misra_16_7(self, data): def misra_17_1(self, data): for token in data.tokenlist: - if isFunctionCall(token) and token.astOperand1.str in ( + if isFunctionCall(token, data.standards.c) and token.astOperand1.str in ( 'va_list', 'va_arg', 'va_start', 'va_end', 'va_copy'): self.reportError(token, 17, 1) elif token.str == 'va_list': @@ -3159,10 +3473,80 @@ def find_recursive_call(search_for_function, direct_call, calls_map, visited=Non tok = tok.next def misra_17_3(self, cfg): + # Check for Clang warnings related to implicit function declarations for w in cfg.clang_warnings: if w['message'].endswith('[-Wimplicit-function-declaration]'): self.reportError(cppcheckdata.Location(w), 17, 3) + # Additional check for implicit function calls in expressions + for token in cfg.tokenlist: + if token.isName and token.function is None and token.valueType is None: + if token.next and token.next.str == "(" and token.next.valueType is None: + if token.next.next.str == "*" and \ + token.next.next.next.isName and token.next.next.next.valueType is not None and \ + token.next.next.next.valueType.pointer > 0 : + # this is a function pointer definition the tokens look like this int16_t ( * misra_8_2_p_a ) () + # and the int16_t causes the detection as the '(' follows + continue + if not isKeyword(token.str,cfg.standards.c) and not isStdLibId(token.str,cfg.standards.c): + self.reportError(token, 17, 3) + + def misra_config(self, data): + for var in data.variables: + if not var.isArray or var.nameToken is None or not cppcheckdata.simpleMatch(var.nameToken.next, '['): + continue + tok = var.nameToken.next + while tok.str == '[': + sz = tok.astOperand2 + if sz and sz.getKnownIntValue() is None: + has_var = False + unknown_constant = False + tokens = [sz] + while len(tokens) > 0: + t = tokens[-1] + tokens = tokens[:-1] + if t: + if t.isName and t.getKnownIntValue() is None: + if t.varId or t.variable: + has_var = True + continue + unknown_constant = True + self.report_config_error(tok, 'Unknown constant {}, please review configuration'.format(t.str)) + if t.isArithmeticalOp: + tokens += [t.astOperand1, t.astOperand2] + if not unknown_constant and not has_var: + self.report_config_error(tok, 'Unknown array size, please review configuration') + tok = tok.link.next + + for token in data.tokenlist: + if token.str not in ("while", "if"): + continue + tok = token.next + if token is None or tok.str != "(": + continue + end_token = tok.link + while tok != end_token: + tok = tok.next + if tok.str == 'sizeof' and tok.next.str == '(': + tok = tok.next.link + continue + if tok.str == "(" and tok.isCast: + tok = tok.link + continue + if not tok.isName: + continue + if tok.function or tok.variable or tok.varId or tok.valueType or tok.typeScope: + continue + if tok.next.str == "(" or tok.str in ["EOF"]: + continue + if isKeyword(tok.str, data.standards.c) or isStdLibId(tok.str, data.standards.c): + continue + if tok.astParent is None: + continue + if tok.astParent.str == "." and tok.astParent.valueType: + continue + self.report_config_error(tok, "Variable '%s' is unknown" % tok.str) + def misra_17_6(self, rawTokens): for token in rawTokens: if simpleMatch(token, '[ static'): @@ -3174,7 +3558,9 @@ def misra_17_7(self, data): continue if token.str != '(' or token.astParent: continue - if not token.previous.isName or token.previous.varId: + if token.astOperand1 is None or not token.astOperand1.isName: + continue + if token.astOperand1.varId and (token.astOperand1.variable is None or get_function_pointer_type(token.astOperand1.variable.typeStartToken) is None): continue if token.valueType is None: continue @@ -3231,7 +3617,10 @@ def misra_18_7(self, data): if token.str == '{': token = token.link - if cppcheckdata.simpleMatch(token, "[ ]"): + # skip function pointer parameter types + if token.astOperand1 is None: + pass + elif cppcheckdata.simpleMatch(token, "[ ]"): self.reportError(token, 18, 7) break token = token.next @@ -3247,7 +3636,7 @@ def misra_18_8(self, data): # Unknown define or syntax error if not typetok.astOperand2: continue - if not isConstantExpression(typetok.astOperand2): + if not isConstantExpression(typetok.astOperand2) and not isUnknownConstantExpression(typetok.astOperand2): self.reportError(var.nameToken, 18, 8) def misra_19_2(self, data): @@ -3415,7 +3804,7 @@ def misra_20_9(self, cfg): break for s in cond.E.split(' '): if (s[0] >= 'A' and s[0] <= 'Z') or (s[0] >= 'a' and s[0] <= 'z'): - if isKeyword(s): + if isKeyword(s, cfg.standards.c): continue if s in defined: continue @@ -3549,7 +3938,7 @@ def misra_21_2(self, cfg): def misra_21_3(self, data): for token in data.tokenlist: - if isFunctionCall(token) and (token.astOperand1.str in ('malloc', 'calloc', 'realloc', 'free')): + if isFunctionCall(token, data.standards.c) and (token.astOperand1.str in ('malloc', 'calloc', 'realloc', 'free')): self.reportError(token, 21, 3) def misra_21_4(self, data): @@ -3563,21 +3952,22 @@ def misra_21_5(self, data): self.reportError(directive, 21, 5) def misra_21_6(self, data): - dir_stdio = findInclude(data.directives, '') - dir_wchar = findInclude(data.directives, '') - if dir_stdio: - self.reportError(dir_stdio, 21, 6) - if dir_wchar: - self.reportError(dir_wchar, 21, 6) + for token in data.tokenlist: + if not isFunctionCall(token) or token.previous.function: + continue + standard_id = getStdLib(data.standards.c) + funcname = token.previous.str + if funcname in standard_id.get("stdio.h", []) or funcname in standard_id.get("wchar.h", []): + self.reportError(token, 21, 6) def misra_21_7(self, data): for token in data.tokenlist: - if isFunctionCall(token) and (token.astOperand1.str in ('atof', 'atoi', 'atol', 'atoll')): + if isFunctionCall(token, data.standards.c) and (token.astOperand1.str in ('atof', 'atoi', 'atol', 'atoll')): self.reportError(token, 21, 7) def misra_21_8(self, data): for token in data.tokenlist: - if isFunctionCall(token) and (token.astOperand1.str in ('abort', 'exit', 'getenv')): + if isFunctionCall(token, data.standards.c) and (token.astOperand1.str in ('abort', 'exit', 'getenv')): self.reportError(token, 21, 8) def misra_21_9(self, data): @@ -3604,7 +3994,7 @@ def misra_21_12(self, data): for token in data.tokenlist: if token.str == 'fexcept_t' and token.isName: self.reportError(token, 21, 12) - if isFunctionCall(token) and (token.astOperand1.str in ( + if isFunctionCall(token, data.standards.c) and (token.astOperand1.str in ( 'feclearexcept', 'fegetexceptflag', 'feraiseexcept', @@ -3616,7 +4006,7 @@ def misra_21_14(self, data): # buffers used in strcpy/strlen/etc function calls string_buffers = [] for token in data.tokenlist: - if token.str[0] == 's' and isFunctionCall(token.next): + if token.str[0] == 's' and isFunctionCall(token.next, data.standards.c): name, args = cppcheckdata.get_function_call_name_args(token) if name is None: continue @@ -3687,7 +4077,7 @@ def misra_21_16(self, cfg): continue if arg.valueType.pointer > 1: continue - if arg.valueType.sign in ('unsigned', 'signed'): + if getEssentialTypeCategory(arg) in ('unsigned', 'signed', 'bool'): continue if arg.valueType.isEnum(): continue @@ -3739,7 +4129,7 @@ def misra_21_20(self, cfg): # Calling dangerous function if token.str in ('asctime', 'ctime', 'gmtime', 'localtime', 'localeconv', 'getenv', 'setlocale', 'strerror'): - name, args = cppcheckdata.get_function_call_name_args(token) + name, _ = cppcheckdata.get_function_call_name_args(token) if name and name == token.str: # make assigned pointers invalid for varId in assigned.get(name, ()): @@ -3813,7 +4203,7 @@ def misra_22_9(self, cfg): errno_is_set = False for token in cfg.tokenlist: if token.str == '(' and not simpleMatch(token.link, ') {'): - name, args = cppcheckdata.get_function_call_name_args(token.previous) + name, _ = cppcheckdata.get_function_call_name_args(token.previous) if name is None: continue errno_is_set = is_errno_setting_function(name) @@ -3830,8 +4220,8 @@ def misra_22_9(self, cfg): def misra_22_10(self, cfg): last_function_call = None for token in cfg.tokenlist: - if token.str == '(' and not simpleMatch(token.link, ') {'): - name, args = cppcheckdata.get_function_call_name_args(token.previous) + if token.isName and token.next and token.next.str == '(' and not simpleMatch(token.next.link, ') {'): + name, _ = cppcheckdata.get_function_call_name_args(token) last_function_call = name if token.str == '}': last_function_call = None @@ -3854,8 +4244,7 @@ def get_violations(self, violation_type=None): """Return the list of violations for a normal checker run""" if violation_type is None: return self.violations.items() - else: - return self.violations[violation_type] + return self.violations[violation_type] def get_violation_types(self): """Return the list of violations for a normal checker run""" @@ -3895,10 +4284,10 @@ def addSuppressedRule(self, ruleNum, # If the rule is not in the dict already then add it if ruleNum not in self.suppressedRules: - ruleItemList = list() + ruleItemList = [] ruleItemList.append(line_symbol) - fileDict = dict() + fileDict = {} fileDict[normalized_filename] = ruleItemList self.suppressedRules[ruleNum] = fileDict @@ -3914,7 +4303,7 @@ def addSuppressedRule(self, ruleNum, # If the filename is not in the dict already add it if normalized_filename not in fileDict: - ruleItemList = list() + ruleItemList = [] ruleItemList.append(line_symbol) fileDict[normalized_filename] = ruleItemList @@ -4018,7 +4407,7 @@ def showSuppressedRules(self): Print out rules in suppression list sorted by Rule Number """ print("Suppressed Rules List:") - outlist = list() + outlist = [] for ruleNum in self.suppressedRules: fileDict = self.suppressedRules[ruleNum] @@ -4067,6 +4456,15 @@ def setSuppressionList(self, suppressionlist): self.addSuppressedRule(ruleNum) + def report_config_error(self, location, errmsg): + errmsg = 'Because of missing configuration, misra checking is incomplete. There can be false negatives! ' + errmsg + cppcheck_severity = 'error' + error_id = 'config' + if self.settings.verify: + self.verify_actual.append('%s:%d %s' % (location.file, location.linenr, error_id)) + else: + cppcheckdata.reportError(location, cppcheck_severity, errmsg, 'misra', error_id) + def reportError(self, location, num1, num2): ruleNum = num1 * 100 + num2 @@ -4094,11 +4492,6 @@ def reportError(self, location, num1, num2): errmsg = 'misra violation (use --rule-texts= to get proper output)' else: errmsg = 'misra violation (rule-texts-file not found: ' + self.ruleText_filename + ')' - if self.path_premium_addon: - for line in cppcheckdata.cmd_output([self.path_premium_addon, '--cli', '--get-rule-text=' + errorId]).split('\n'): - if len(line) > 1 and not line.startswith('{'): - errmsg = line.strip() - break else: errmsg = 'misra violation %s with no text in the supplied rule-texts-file' % (ruleNum) @@ -4121,10 +4514,8 @@ def loadRuleTexts(self, filename): num1 = 0 num2 = 0 appendixA = False - ruleText = False - expect_more = False - Rule_pattern = re.compile(r'^Rule ([0-9]+).([0-9]+)') + Rule_pattern = re.compile(r'^Rule ([0-9]+)\.([0-9]+)') severity_pattern = re.compile(r'.*[ ]*(Advisory|Required|Mandatory)$') xA_Z_pattern = re.compile(r'^[#A-Z].*') a_z_pattern = re.compile(r'^[a-z].*') @@ -4133,10 +4524,11 @@ def loadRuleTexts(self, filename): encodings = ['ascii', 'utf-8', 'windows-1250', 'windows-1252'] for e in encodings: try: - file_stream = codecs.open(filename, 'r', encoding=e) + file_stream = open(filename, 'r', encoding=e) file_stream.readlines() file_stream.seek(0) except UnicodeDecodeError: + file_stream.close() file_stream = None else: break @@ -4151,12 +4543,13 @@ def loadRuleTexts(self, filename): file_stream = open(filename, 'rt') rule = None - have_severity = False - severity_loc = 0 + rule_line_number = 0 for line in file_stream: - line = line.replace('\r', '').replace('\n', '') + line = line.strip() + if len(line) == 0: + continue if not appendixA: if line.find('Appendix A') >= 0 and line.find('Summary of guidelines') >= 10: @@ -4164,57 +4557,50 @@ def loadRuleTexts(self, filename): continue if line.find('Appendix B') >= 0: break - if len(line) == 0: - continue # Parse rule declaration. res = Rule_pattern.match(line) if res: - have_severity = False - expect_more = False - severity_loc = 0 + rule_line_number = 0 num1 = int(res.group(1)) num2 = int(res.group(2)) rule = Rule(num1, num2) - if not have_severity and rule is not None: res = severity_pattern.match(line) - if res: rule.misra_severity = res.group(1) - have_severity = True - else: - severity_loc += 1 - - # Only look for severity on the Rule line - # or the next non-blank line after - # If it's not in either of those locations then - # assume a severity was not provided. - - if severity_loc < 2: - continue - else: - rule.misra_severity = '' - have_severity = True + rule_line_number = 1 + continue if rule is None: continue - # Parse continuing of rule text. - if expect_more: - if a_z_pattern.match(line): - self.ruleTexts[rule.num].text += ' ' + line + rule_line_number += 1 + + if rule_line_number == 1: + res = severity_pattern.match(line) + + if res: + rule.misra_severity = res.group(1) continue - expect_more = False - continue + rule_line_number = 2 # Parse beginning of rule text. - if xA_Z_pattern.match(line): - rule.text = line + if not rule.text and xA_Z_pattern.match(line): + rule.text = line.strip() self.ruleTexts[rule.num] = rule - expect_more = True + continue + + # Parse continuing of rule text. + if a_z_pattern.match(line): + self.ruleTexts[rule.num].text += ' ' + line.strip() + continue + + rule = None + + file_stream.close() def verifyRuleTexts(self): """Prints rule numbers without rule text.""" @@ -4256,6 +4642,10 @@ def executeCheck(self, rule_num, check_function, *args): 1901) # misra-c2012-19.1 : misra c++2008 2-13-3 if (not self.is_cpp) or rule_num in misra_cpp: + # log checker + errmsg = 'Misra C: %i.%i' % (rule_num // 100, rule_num % 100) + cppcheckdata.log_checker(errmsg, 'misra') + check_function(*args) def parseDump(self, dumpfile, path_premium_addon=None): @@ -4264,7 +4654,7 @@ def fillVerifyExpected(verify_expected, tok): rule_re = re.compile(r'[0-9]+\.[0-9]+') if tok.str.startswith('//') and 'TODO' not in tok.str: for word in tok.str[2:].split(' '): - if rule_re.match(word): + if rule_re.match(word) or word == "config": verify_expected.append('%s:%d %s' % (tok.file, tok.linenr, word)) data = cppcheckdata.parsedump(dumpfile) @@ -4296,12 +4686,13 @@ def fillVerifyExpected(verify_expected, tok): else: self.printStatus('Checking ' + dumpfile + '...') - self.is_cpp = data.files and data.files[0].endswith('.cpp') + self.is_cpp = data.language == 'cpp' for cfgNumber, cfg in enumerate(data.iterconfigurations()): if not self.settings.quiet: self.printStatus('Checking %s, config %s...' % (dumpfile, cfg.name)) + self.executeCheck(102, self.misra_1_2, cfg) if not path_premium_addon: self.executeCheck(104, self.misra_1_4, cfg) self.executeCheck(202, self.misra_2_2, cfg) @@ -4312,7 +4703,7 @@ def fillVerifyExpected(verify_expected, tok): # data.rawTokens is same for all configurations if cfgNumber == 0: self.executeCheck(301, self.misra_3_1, data.rawTokens) - self.executeCheck(302, self.misra_3_2, data.rawTokens) + #self.executeCheck(302, self.misra_3_2, data.rawTokens) self.executeCheck(401, self.misra_4_1, data.rawTokens) self.executeCheck(402, self.misra_4_2, data.rawTokens) self.executeCheck(501, self.misra_5_1, cfg) @@ -4401,6 +4792,7 @@ def fillVerifyExpected(verify_expected, tok): self.executeCheck(1701, self.misra_17_1, cfg) self.executeCheck(1702, self.misra_17_2, cfg) self.executeCheck(1703, self.misra_17_3, cfg) + self.misra_config(cfg) if cfgNumber == 0: self.executeCheck(1706, self.misra_17_6, data.rawTokens) self.executeCheck(1707, self.misra_17_7, cfg) @@ -4448,6 +4840,19 @@ def fillVerifyExpected(verify_expected, tok): self.executeCheck(2209, self.misra_22_9, cfg) self.executeCheck(2210, self.misra_22_10, cfg) + def read_ctu_info_line(self, line): + if not line.startswith('{'): + return None + try: + ctu_info = json.loads(line) + except json.decoder.JSONDecodeError: + return None + if 'summary' not in ctu_info: + return None + if 'data' not in ctu_info: + return None + return ctu_info + def analyse_ctu_info(self, ctu_info_files): all_typedef_info = {} all_tagname_info = {} @@ -4463,15 +4868,17 @@ def analyse_ctu_info(self, ctu_info_files): def is_different_location(loc1, loc2): return loc1['file'] != loc2['file'] or loc1['line'] != loc2['line'] + def is_different_file(loc1, loc2): + return loc1['file'] != loc2['file'] + try: for filename in ctu_info_files: for line in open(filename, 'rt'): - if not line.startswith('{'): + s = self.read_ctu_info_line(line) + if s is None: continue - - s = json.loads(line) - summary_type = s['summary'] - summary_data = s['data'] + summary_type = s.get('summary', '') + summary_data = s.get('data', None) if summary_type == 'MisraTypedefInfo': for new_typedef_info in summary_data: @@ -4509,7 +4916,7 @@ def is_different_location(loc1, loc2): all_macro_info[key] = new_macro if summary_type == 'MisraExternalIdentifiers': - for s in summary_data: + for s in sorted(summary_data, key=lambda d: "%s %s %s" %(d['file'],d['line'], d['column'] )): is_declaration = s['decl'] if is_declaration: all_external_identifiers = all_external_identifiers_decl @@ -4517,10 +4924,13 @@ def is_different_location(loc1, loc2): all_external_identifiers = all_external_identifiers_def name = s['name'] - if name in all_external_identifiers and is_different_location(s, all_external_identifiers[name]): - num = 5 if is_declaration else 6 - self.reportError(Location(s), 8, num) - self.reportError(Location(all_external_identifiers[name]), 8, num) + if name in all_external_identifiers: + if is_declaration and is_different_location(s, all_external_identifiers[name]): + self.reportError(Location(s), 8, 5) + self.reportError(Location(all_external_identifiers[name]), 8, 5) + elif is_different_file(s, all_external_identifiers[name]): + self.reportError(Location(s), 8, 6) + self.reportError(Location(all_external_identifiers[name]), 8, 6) all_external_identifiers[name] = s if summary_type == 'MisraInternalIdentifiers': @@ -4721,7 +5131,7 @@ def main(): for misra_id in ids: rules_violated[misra_id] = rules_violated.get(misra_id, 0) + 1 print("MISRA rules violated:") - convert = lambda text: int(text) if text.isdigit() else text + convert = lambda text: int(text) if text.isdigit() else 0 misra_sort = lambda key: [convert(c) for c in re.split(r'[\.-]([0-9]*)', key)] for misra_id in sorted(rules_violated.keys(), key=misra_sort): res = re.match(r'misra-c2012-([0-9]+)\\.([0-9]+)', misra_id) diff --git a/addons/misra_9.py b/addons/misra_9.py index 220bf7a13dc..1ca1b7ce3e0 100644 --- a/addons/misra_9.py +++ b/addons/misra_9.py @@ -1,5 +1,3 @@ -import cppcheckdata - # Holds information about an array, struct or union's element definition. class ElementDef: def __init__(self, elementType, name, valueType, dimensions = None): @@ -140,8 +138,7 @@ def getChildByValueElement(self, ed): def getEffectiveLevel(self): if self.parent and self.parent.elementType == "array": return self.parent.getEffectiveLevel() + 1 - else: - return 0 + return 0 def setInitialized(self, designated=False, positional=False): if designated: @@ -203,11 +200,10 @@ def isMisra93Compliant(self): self.isOnlyDesignated()) and all([not (child.isDesignated or child.isPositional) or child.isMisra93Compliant() for child in self.children])) return result - elif self.elementType == 'record': + if self.elementType == 'record': result = all([child.isMisra93Compliant() for child in self.children]) return result - else: - return True + return True def isMisra94Compliant(self): return self.numInits <= 1 and all([child.isMisra94Compliant() for child in self.children]) @@ -255,7 +251,7 @@ def parseInitializer(self, root, token): isFirstElement = False isDesignated = True - elif self.token.isString and self.ed.isArray: + elif self.token.isString and self.ed and self.ed.isArray: self.ed.setInitialized(isDesignated) if self.token == self.token.astParent.astOperand1 and self.token.astParent.astOperand2: self.token = self.token.astParent.astOperand2 @@ -293,7 +289,7 @@ def parseInitializer(self, root, token): # Fake dummy as nextChild (of current root) nextChild = dummyRoot - if self.token.astOperand1: + if nextChild and self.token.astOperand1: self.root = nextChild self.token = self.token.astOperand1 isFirstElement = True @@ -311,7 +307,6 @@ def parseInitializer(self, root, token): if self.ed and self.ed.isValue: if not isDesignated and len(self.rootStack) > 0 and self.rootStack[-1][1] == self.root: self.rootStack[-1][0].markStuctureViolation(self.token) - if isFirstElement and self.token.str == '0' and self.token.next.str == '}': # Zero initializer causes recursive initialization self.root.initializeChildren() @@ -328,7 +323,7 @@ def parseInitializer(self, root, token): self.ed.parent.initializeChildren() else: - if self.ed.parent != self.root: + if self.root is not None and self.ed.parent != self.root: # Check if token is correct value type for self.root.children[?] child = self.root.getChildByValueElement(self.ed) if self.token.valueType: @@ -346,15 +341,9 @@ def parseInitializer(self, root, token): parent = parent.parent isDesignated = False - if self.token.isString: - if self.token == self.token.astParent.astOperand1 and self.token.astParent.astOperand2: - self.token = self.token.astParent.astOperand2 - self.ed.markAsCurrent() - self.ed = self.root.getNextChild() - else: - self.unwindAndContinue() - else: - self.unwindAndContinue() + if self.token.isString and self.ed.parent.isArray: + self.ed = self.ed.parent + self.unwindAndContinue() def pushToRootStackAndMarkAsDesignated(self): new = self.ed.parent @@ -379,61 +368,32 @@ def unwindAndContinue(self): while self.token: if self.token.astParent.astOperand1 == self.token and self.token.astParent.astOperand2: if self.ed: - self.ed.markAsCurrent() - self.ed = self.ed.getNextValueElement(self.root) + if self.token.astParent.astOperand2.str == "{" and self.ed.isDesignated: + self.popFromStackIfExitElement() + else: + self.ed.markAsCurrent() + self.ed = self.ed.getNextValueElement(self.root) self.token = self.token.astParent.astOperand2 break - else: - self.token = self.token.astParent - if self.token.str == '{': - if self.root: - self.ed = self.root.getLastValueElement() - self.ed.markAsCurrent() - # Cleanup if root is dummy node representing excess levels in initializer - if self.root.name == '<-': - self.root.children[0].parent = self.root.parent + self.token = self.token.astParent + if self.token.str == '{': + if self.root: + self.ed = self.root.getLastValueElement() + self.ed.markAsCurrent() - self.root = self.root.parent + # Cleanup if root is dummy node representing excess levels in initializer + if self.root.name == '<-': + self.root.children[0].parent = self.root.parent - if self.token.astParent is None: - self.token = None - break + self.root = self.root.parent + + if self.token.astParent is None: + self.token = None + break def misra_9_x(self, data, rule, rawTokens = None): - # If there are arrays with unknown size constants then we need to warn about missing configuration - # and bailout - has_config_errors = False - for var in data.variables: - if not var.isArray or var.nameToken is None or not cppcheckdata.simpleMatch(var.nameToken.next,'['): - continue - tok = var.nameToken.next - while tok.str == '[': - sz = tok.astOperand2 - if sz and sz.getKnownIntValue() is None: - has_var = False - unknown_constant = False - tokens = [sz] - while len(tokens) > 0: - t = tokens[-1] - tokens = tokens[:-1] - if t: - if t.isName and t.getKnownIntValue() is None: - if t.varId or t.variable: - has_var = True - continue - unknown_constant = True - cppcheckdata.reportError(sz, 'error', f'Unknown constant {t.str}, please review configuration', 'misra', 'config') - has_config_errors = True - if t.isArithmeticalOp: - tokens += [t.astOperand1, t.astOperand2] - if not unknown_constant and not has_var: - cppcheckdata.reportError(sz, 'error', 'Unknown array size, please review configuration', 'misra', 'config') - has_config_errors = True - tok = tok.link.next - if has_config_errors: - return parser = InitializerParser() @@ -464,7 +424,6 @@ def misra_9_x(self, data, rule, rawTokens = None): # without it. if ed.valueType is None and not variable.isArray: continue - parser.parseInitializer(ed, eq.astOperand2) # print(rule, nameToken.str + '=', ed.getInitDump()) if rule == 902 and not ed.isMisra92Compliant(): @@ -539,11 +498,29 @@ def createRecordChildrenDefs(ed, var): child = ElementDef("pointer", var.nameToken, var.nameToken.valueType) ed.addChild(child) return + child_dict = {} for variable in valueType.typeScope.varlist: if variable is var: continue child = getElementDef(variable.nameToken) - ed.addChild(child) + child_dict[variable.nameToken] = child + for scopes in valueType.typeScope.nestedList: + varscope = False + if scopes.nestedIn == valueType.typeScope: + for variable in valueType.typeScope.varlist: + if variable.nameToken and variable.nameToken.valueType and variable.nameToken.valueType.typeScope == scopes: + varscope = True + break + if not varscope: + ed1 = ElementDef("record", scopes.Id, valueType) + for variable in scopes.varlist: + child = getElementDef(variable.nameToken) + ed1.addChild(child) + child_dict[scopes.bodyStart] = ed1 + sorted_keys = sorted(list(child_dict.keys()), key=lambda k: (k.file, k.linenr, k.column)) + for _key in sorted_keys: + ed.addChild(child_dict[_key]) + def getElementByDesignator(ed, token): if not token.str in [ '.', '[' ]: diff --git a/addons/naming.py b/addons/naming.py index 948f158b6f4..2893779f2e0 100755 --- a/addons/naming.py +++ b/addons/naming.py @@ -17,7 +17,7 @@ def validate_regex(expr): re.compile(expr) except re.error: print('Error: "{}" is not a valid regular expression.'.format(expr)) - exit(1) + sys.exit(1) RE_VARNAME = None @@ -37,6 +37,7 @@ def validate_regex(expr): elif arg[:11] == '--function=': RE_FUNCTIONNAME = arg[11:] validate_regex(RE_FUNCTIONNAME) + # TODO: bail out on unknown parameter def reportError(token, severity, msg, errorId): diff --git a/addons/naming.json b/addons/namingng.config.json similarity index 61% rename from addons/naming.json rename to addons/namingng.config.json index 26cb4bbce7a..0abba4f15ac 100644 --- a/addons/naming.json +++ b/addons/namingng.config.json @@ -2,6 +2,15 @@ "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"], "RE_PRIVATE_MEMBER_VARIABLE": null, "RE_FUNCTIONNAME": ["[a-z0-9A-Z]*\\Z"], + "include_guard": { + "input": "path", + "prefix": "", + "suffix": "", + "case": "upper", + "max_linenr": 5, + "RE_HEADERFILE": "[^/].*\\.h\\Z", + "required": true + }, "var_prefixes": {"uint32_t": "ui32", "int*": "intp"}, "function_prefixes": {"uint16_t": "ui16", diff --git a/addons/namingng.json b/addons/namingng.json new file mode 100644 index 00000000000..83f9a5a55d8 --- /dev/null +++ b/addons/namingng.json @@ -0,0 +1,6 @@ +{ + "script":"namingng.py", + "args":[ + "--configfile=namingng.config.json" + ] +} diff --git a/addons/namingng.py b/addons/namingng.py index 73f1b08ec08..9da177321ef 100755 --- a/addons/namingng.py +++ b/addons/namingng.py @@ -3,6 +3,7 @@ # cppcheck addon for naming conventions # An enhanced version. Configuration is taken from a json file # It supports to check for type-based prefixes in function or variable names. +# Aside from include guard naming, include guard presence can also be tested. # # Example usage (variable name must start with lowercase, function name must start with uppercase): # $ cppcheck --dump path-to-src/ @@ -11,9 +12,18 @@ # JSON format: # # { -# "RE_VARNAME": "[a-z]*[a-zA-Z0-9_]*\\Z", +# "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"], # "RE_PRIVATE_MEMBER_VARIABLE": null, -# "RE_FUNCTIONNAME": "[a-z0-9A-Z]*\\Z", +# "RE_FUNCTIONNAME": ["[a-z0-9A-Z]*\\Z"], +# "_comment": "comments can be added to the config with underscore-prefixed keys", +# "include_guard": { +# "input": "path", +# "prefix": "GUARD_", +# "case": "upper", +# "max_linenr": 5, +# "RE_HEADERFILE": "[^/].*\\.h\\Z", +# "required": true +# }, # "var_prefixes": {"uint32_t": "ui32"}, # "function_prefixes": {"uint16_t": "ui16", # "uint32_t": "ui32"} @@ -24,230 +34,387 @@ import cppcheckdata import sys +import os import re -import argparse import json - # Auxiliary class class DataStruct: - def __init__(self, file, linenr, string): + def __init__(self, file, linenr, string, column=0): self.file = file self.linenr = linenr self.str = string + self.column = column + +def reportNamingError(location,message,errorId='namingConvention',severity='style',extra='',column=None): + cppcheckdata.reportError(location,severity,message,'namingng',errorId,extra,columnOverride=column) +def configError(error,fatal=True): + print('config error: %s'%error) + if fatal: + sys.exit(1) -def reportError(filename, linenr, severity, msg): - message = "[{filename}:{linenr}] ( {severity} ) naming.py: {msg}\n".format( - filename=filename, - linenr=linenr, - severity=severity, - msg=msg - ) - sys.stderr.write(message) - return message +def validateConfigREs(list_or_dict,json_key): + have_error = False + for item in list_or_dict: + try: + re.compile(item) + except re.error as err: + configError("item '%s' of '%s' is not a valid regular expression: %s"%(item,json_key,err),fatal=False) + have_error = True + continue + if not isinstance(list_or_dict,dict): + continue + # item is actually a dict key; check value + value = list_or_dict[item] + if (not isinstance(value,list) or len(value) != 2 + or not isinstance(value[0],bool) or not isinstance(value[1],str)): + configError("item '%s' of '%s' must be an array [bool,string]"%(item,json_key),fatal=False) + have_error = True + return have_error def loadConfig(configfile): - with open(configfile) as fh: - data = json.load(fh) - return data + if not os.path.exists(configfile): + configError("cannot find config file '%s'"%configfile) + + try: + with open(configfile) as fh: + data = json.load(fh) + except json.JSONDecodeError as e: + configError("error parsing config file as JSON at line %d: %s"%(e.lineno,e.msg)) + except Exception as e: + configError("error opening config file '%s': %s"%(configfile,e)) + + if not isinstance(data, dict): + configError('config file must contain a JSON object at the top level') + + # All errors are emitted before bailing out, to make the unit test more + # effective. + have_error = False + + # Put config items in a class, so that settings can be accessed using + # config.feature + class Config: + pass + config = Config() + + mapping = { + 'file': ('RE_FILE', (list,)), + 'namespace': ('RE_NAMESPACE', (list,dict)), + 'include_guard': ('include_guard', (dict,)), + 'variable': ('RE_VARNAME', (list,dict)), + 'variable_prefixes': ('var_prefixes', (dict,), {}), + 'private_member': ('RE_PRIVATE_MEMBER_VARIABLE', (list,dict)), + 'public_member': ('RE_PUBLIC_MEMBER_VARIABLE', (list,dict)), + 'global_variable': ('RE_GLOBAL_VARNAME', (list,dict)), + 'function_name': ('RE_FUNCTIONNAME', (list,dict)), + 'function_prefixes': ('function_prefixes', (dict,), {}), + 'class_name': ('RE_CLASS_NAME', (list,dict)), + 'skip_one_char_variables': ('skip_one_char_variables', (bool,)), + } + + # parse defined keys and store as members of config object + for key,opts in mapping.items(): + json_key = opts[0] + req_type = opts[1] + default = None if len(opts)<3 else opts[2] + + value = data.pop(json_key,default) + if value is not None and type(value) not in req_type: + req_typename = ' or '.join([tp.__name__ for tp in req_type]) + got_typename = type(value).__name__ + configError('%s must be %s (not %s), or not set'%(json_key,req_typename,got_typename),fatal=False) + have_error = True + continue + # type list implies that this is either a list of REs or a dict with RE keys + if list in req_type and value is not None: + re_error = validateConfigREs(value,json_key) + if re_error: + have_error = True -def checkTrueRegex(data, expr, msg, errors): - res = re.match(expr, data.str) - if res: - errors.append(reportError(data.file, data.linenr, 'style', msg)) + setattr(config,key,value) + # check remaining keys, only accept underscore-prefixed comments + for key,value in data.items(): + if key == '' or key[0] != '_': + configError("unknown config key '%s'"%key,fatal=False) + have_error = True -def checkFalseRegex(data, expr, msg, errors): - res = re.match(expr, data.str) - if not res: - errors.append(reportError(data.file, data.linenr, 'style', msg)) + if have_error: + sys.exit(1) + + # pylint: disable-next=no-member - TODO: fix this + if config.include_guard: + # pylint: disable-next=no-member - TODO: fix this + config.include_guard_header_re = config.include_guard.get('RE_HEADERFILE',"[^/].*\\.h\\Z") + + return config -def evalExpr(conf, exp, mockToken, msgType, errors): +def evalExpr(conf, exp, mockToken, msgType): + report_as_error = False + msg = msgType + ' ' + mockToken.str + ' violates naming convention' + if isinstance(conf, dict): - if conf[exp][0]: - msg = msgType + ' ' + mockToken.str + ' violates naming convention : ' + conf[exp][1] - checkTrueRegex(mockToken, exp, msg, errors) - elif ~conf[exp][0]: - msg = msgType + ' ' + mockToken.str + ' violates naming convention : ' + conf[exp][1] - checkFalseRegex(mockToken, exp, msg, errors) - else: - msg = msgType + ' ' + mockToken.str + ' violates naming convention : ' + conf[exp][0] - checkFalseRegex(mockToken, exp, msg, errors) + report_as_error = conf[exp][0] + msg += ': ' + conf[exp][1] + + res = re.match(exp,mockToken.str) + if bool(res) == report_as_error: + reportNamingError(mockToken,msg) + +def check_include_guard_name(conf,directive): + parts = directive.str.split() + if len(parts) != 2: + msg = 'syntax error' + reportNamingError(directive,msg,'syntax') + return None,None + guard_name = parts[1] + guard_column = 1+directive.str.find(guard_name) + + filename = directive.file + if conf.include_guard.get('input','path') == 'basename': + filename = os.path.basename(filename) + use_case = conf.include_guard.get('case','upper') + if use_case == 'upper': + filename = filename.upper() + elif use_case == 'lower': + filename = filename.lower() + elif use_case == 'keep': + pass # keep filename case as-is else: - msg = msgType + ' ' + mockToken.str + ' violates naming convention' - checkFalseRegex(mockToken, exp, msg, errors) - + print("invalid config value for 'case': '%s'"%use_case,file=sys.stderr) + sys.exit(1) -def process(dumpfiles, configfile, debugprint=False): + barename = re.sub('[^A-Za-z0-9]','_',filename).strip('_') + expect_guard_name = conf.include_guard.get('prefix','') + barename + conf.include_guard.get('suffix','') + if expect_guard_name != guard_name: + msg = 'include guard naming violation; %s != %s'%(guard_name,expect_guard_name) + reportNamingError(directive,msg,'includeGuardName',column=guard_column) + + return guard_name,guard_column + +def check_include_guards(conf,cfg,unguarded_include_files): + # Scan for '#ifndef FILE_H' as the first directive, in the first N lines. + # Then test whether the next directive #defines the found name. + # Various tests are done: + # - check include guards for their naming and consistency + # - test whether include guards are in place + max_linenr = conf.include_guard.get('max_linenr', 5) + + def report(directive,msg,errorId,severity='style',column=0): + reportNamingError(directive,msg,errorId,severity=severity,column=column) + + def report_pending_ifndef(directive,column): + report(directive,'include guard #ifndef is not followed by #define','includeGuardIncomplete',column=column) + + last_fn = None + pending_ifndef = None + guard_column = None + phase = 0 + for directive in cfg.directives: + if last_fn != directive.file: + if pending_ifndef: + report_pending_ifndef(pending_ifndef,guard_column) + pending_ifndef = None + last_fn = directive.file + phase = 0 + if phase == -1: + # ignore (the remainder of) this file + continue + if not re.match(conf.include_guard_header_re,directive.file): + phase = -1 + continue - errors = [] + if directive.linenr > max_linenr: + if phase == 0 and conf.include_guard.get('required',1): + report(directive,'include guard not found before line %d'%max_linenr,'includeGuardMissing') + phase = -1 + continue + if phase == 0: + # looking for '#ifndef FILE_H' + if not directive.str.startswith('#ifndef'): + if conf.include_guard.get('required',1): + report(directive,'first preprocessor directive should be include guard #ifndef','includeGuardMissing') + phase = -1 + continue + guard_name,guard_column = check_include_guard_name(conf,directive) + if guard_name is None: + phase = -1 + continue + pending_ifndef = directive + phase = 1 + elif phase == 1: + pending_ifndef = None + # looking for '#define FILE_H' + if not directive.str.startswith('#define'): + report(directive,'second preprocessor directive should be include guard #define','includeGuardIncomplete') + phase = -1 + continue + parts = directive.str.split() + if len(parts) == 1: + report(directive,'syntax error','syntax') + phase = -1 + continue + if guard_name != parts[1]: + report(directive,'include guard does not guard; %s != %s'%(guard_name,parts[1]),'includeGuardAwayFromDuty',severity='warning',column=guard_column) + + unguarded_include_files.remove(directive.file) + + phase = -1 + if pending_ifndef: + report_pending_ifndef(pending_ifndef,guard_column) + +def process(dumpfiles, configfile, cli, debugprint): conf = loadConfig(configfile) for afile in dumpfiles: if not afile[-5:] == '.dump': continue - print('Checking ' + afile + '...') + if not cli: + print('Checking ' + afile + '...') data = cppcheckdata.CppcheckData(afile) + process_data(conf,data,cli,debugprint) + +def check_file_naming(conf,data): + for source_file in data.files: + basename = os.path.basename(source_file) + good = False + for exp in conf.file: + good |= bool(re.match(exp, source_file)) + good |= bool(re.match(exp, basename)) + if not good: + mockToken = DataStruct(source_file, 0, basename) + reportNamingError(mockToken, 'File name ' + basename + ' violates naming convention') + +def check_namespace_naming(conf,data): + for tk in data.rawTokens: + if tk.str != 'namespace': + continue + mockToken = DataStruct(tk.next.file, tk.next.linenr, tk.next.str, tk.next.column) + for exp in conf.namespace: + evalExpr(conf.namespace, exp, mockToken, 'Namespace') - # Check File naming - if "RE_FILE" in conf and conf["RE_FILE"]: - mockToken = DataStruct(afile[:-5], "0", afile[afile.rfind('/') + 1:-5]) - msgType = 'File name' - for exp in conf["RE_FILE"]: - evalExpr(conf["RE_FILE"], exp, mockToken, msgType, errors) - - # Check Namespace naming - if "RE_NAMESPACE" in conf and conf["RE_NAMESPACE"]: - for tk in data.rawTokens: - if tk.str == 'namespace': - mockToken = DataStruct(tk.next.file, tk.next.linenr, tk.next.str) - msgType = 'Namespace' - for exp in conf["RE_NAMESPACE"]: - evalExpr(conf["RE_NAMESPACE"], exp, mockToken, msgType, errors) - - for cfg in data.configurations: - print('Checking %s, config %s...' % (afile, cfg.name)) - if "RE_VARNAME" in conf and conf["RE_VARNAME"]: - for var in cfg.variables: - if var.nameToken and var.access != 'Global' and var.access != 'Public' and var.access != 'Private': - prev = var.nameToken.previous - varType = prev.str - while "*" in varType and len(varType.replace("*", "")) == 0: - prev = prev.previous - varType = prev.str + varType - - if debugprint: - print("Variable Name: " + str(var.nameToken.str)) - print("original Type Name: " + str(var.nameToken.valueType.originalTypeName)) - print("Type Name: " + var.nameToken.valueType.type) - print("Sign: " + str(var.nameToken.valueType.sign)) - print("variable type: " + varType) - print("\n") - print("\t-- {} {}".format(varType, str(var.nameToken.str))) - - if conf["skip_one_char_variables"] and len(var.nameToken.str) == 1: - continue - if varType in conf["var_prefixes"]: - if not var.nameToken.str.startswith(conf["var_prefixes"][varType]): - errors.append(reportError( - var.typeStartToken.file, - var.typeStartToken.linenr, - 'style', - 'Variable ' + - var.nameToken.str + - ' violates naming convention')) - - mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) - msgType = 'Variable' - for exp in conf["RE_VARNAME"]: - evalExpr(conf["RE_VARNAME"], exp, mockToken, msgType, errors) - - # Check Private Variable naming - if "RE_PRIVATE_MEMBER_VARIABLE" in conf and conf["RE_PRIVATE_MEMBER_VARIABLE"]: - # TODO: Not converted yet - for var in cfg.variables: - if (var.access is None) or var.access != 'Private': - continue - mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) - msgType = 'Private member variable' - for exp in conf["RE_PRIVATE_MEMBER_VARIABLE"]: - evalExpr(conf["RE_PRIVATE_MEMBER_VARIABLE"], exp, mockToken, msgType, errors) - - # Check Public Member Variable naming - if "RE_PUBLIC_MEMBER_VARIABLE" in conf and conf["RE_PUBLIC_MEMBER_VARIABLE"]: - for var in cfg.variables: - if (var.access is None) or var.access != 'Public': - continue - mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) - msgType = 'Public member variable' - for exp in conf["RE_PUBLIC_MEMBER_VARIABLE"]: - evalExpr(conf["RE_PUBLIC_MEMBER_VARIABLE"], exp, mockToken, msgType, errors) - - # Check Global Variable naming - if "RE_GLOBAL_VARNAME" in conf and conf["RE_GLOBAL_VARNAME"]: - for var in cfg.variables: - if (var.access is None) or var.access != 'Global': - continue - mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str) - msgType = 'Public member variable' - for exp in conf["RE_GLOBAL_VARNAME"]: - evalExpr(conf["RE_GLOBAL_VARNAME"], exp, mockToken, msgType, errors) - - # Check Functions naming - if "RE_FUNCTIONNAME" in conf and conf["RE_FUNCTIONNAME"]: - for token in cfg.tokenlist: - if token.function: - if token.function.type in ('Constructor', 'Destructor', 'CopyConstructor', 'MoveConstructor'): - continue - retval = token.previous.str - prev = token.previous - while "*" in retval and len(retval.replace("*", "")) == 0: - prev = prev.previous - retval = prev.str + retval - if debugprint: - print("\t:: {} {}".format(retval, token.function.name)) - - if retval and retval in conf["function_prefixes"]: - if not token.function.name.startswith(conf["function_prefixes"][retval]): - errors.append(reportError( - token.file, token.linenr, 'style', 'Function ' + token.function.name + ' violates naming convention')) - mockToken = DataStruct(token.file, token.linenr, token.function.name) - msgType = 'Function' - for exp in conf["RE_FUNCTIONNAME"]: - evalExpr(conf["RE_FUNCTIONNAME"], exp, mockToken, msgType, errors) - - # Check Class naming - if "RE_CLASS_NAME" in conf and conf["RE_CLASS_NAME"]: - for fnc in cfg.functions: - # Check if it is Constructor/Destructor - if fnc.type == 'Constructor' or fnc.type == 'Destructor': - mockToken = DataStruct(fnc.tokenDef.file, fnc.tokenDef.linenr, fnc.name) - msgType = 'Class ' + fnc.type - for exp in conf["RE_CLASS_NAME"]: - evalExpr(conf["RE_CLASS_NAME"], exp, mockToken, msgType, errors) - return errors +def check_variable_naming(conf,cfg,debugprint): + for var in cfg.variables: + if not var.nameToken: + continue + if var.access in ('Global','Public','Private'): + continue + prev = var.nameToken.previous + varType = prev.str + while "*" in varType and len(varType.replace("*", "")) == 0: + prev = prev.previous + varType = prev.str + varType + + if debugprint: + print("Variable Name: " + str(var.nameToken.str)) + print("original Type Name: " + str(var.nameToken.valueType.originalTypeName)) + print("Type Name: " + var.nameToken.valueType.type) + print("Sign: " + str(var.nameToken.valueType.sign)) + print("variable type: " + varType) + print("\n") + print("\t-- {} {}".format(varType, str(var.nameToken.str))) + + if conf.skip_one_char_variables and len(var.nameToken.str) == 1: + continue + if varType in conf.variable_prefixes: + prefix = conf.variable_prefixes[varType] + if not var.nameToken.str.startswith(prefix): + reportNamingError(var.typeStartToken, + 'Variable ' + + var.nameToken.str + + ' violates naming convention', + column=var.nameToken.column) + + mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str, var.nameToken.column) + for exp in conf.variable: + evalExpr(conf.variable, exp, mockToken, 'Variable') + +# Naming check for Global, Private and Public member variables +def check_gpp_naming(conf_list,cfg,access,message): + for var in cfg.variables: + if var.access != access: + continue + mockToken = DataStruct(var.typeStartToken.file, var.typeStartToken.linenr, var.nameToken.str, var.nameToken.column) + for exp in conf_list: + evalExpr(conf_list, exp, mockToken, message) +def check_function_naming(conf,cfg,debugprint): + for token in cfg.tokenlist: + if not token.function: + continue + if token.function.type in ('Constructor', 'Destructor', 'CopyConstructor', 'MoveConstructor'): + continue + retval = token.previous.str + prev = token.previous + while "*" in retval and len(retval.replace("*", "")) == 0: + prev = prev.previous + retval = prev.str + retval + if debugprint: + print("\t:: {} {}".format(retval, token.function.name)) + + if retval and retval in conf.function_prefixes: + if not token.function.name.startswith(conf.function_prefixes[retval]): + reportNamingError(token, 'Function ' + token.function.name + ' violates naming convention', column=token.column) + mockToken = DataStruct(token.file, token.linenr, token.function.name, token.column) + msgType = 'Function' + for exp in conf.function_name: + evalExpr(conf.function_name, exp, mockToken, msgType) + +def check_class_naming(conf,cfg): + for fnc in cfg.functions: + if fnc.type not in ('Constructor','Destructor'): + continue + mockToken = DataStruct(fnc.tokenDef.file, fnc.tokenDef.linenr, fnc.name, fnc.tokenDef.column) + msgType = 'Class ' + fnc.type + for exp in conf.class_name: + evalExpr(conf.class_name, exp, mockToken, msgType) + +def process_data(conf,data,cli,debugprint): + if conf.file: + check_file_naming(conf,data) + + if conf.namespace: + check_namespace_naming(conf,data) + + unguarded_include_files = [] + if conf.include_guard and conf.include_guard.get('required',1): + unguarded_include_files = [fn for fn in data.files if re.match(conf.include_guard_header_re,fn)] + + for cfg in data.configurations: + if not cli: + print('Checking config %s...' % cfg.name) + if conf.variable: + check_variable_naming(conf,cfg,debugprint) + if conf.private_member: + check_gpp_naming(conf.private_member,cfg,'Private','Private member variable') + if conf.public_member: + check_gpp_naming(conf.public_member,cfg,'Public','Public member variable') + if conf.global_variable: + check_gpp_naming(conf.global_variable,cfg,'Global','Global variable') + if conf.function_name: + check_function_naming(conf,cfg,debugprint) + if conf.class_name: + check_class_naming(conf,cfg) + if conf.include_guard: + check_include_guards(conf,cfg,unguarded_include_files) + + for fn in unguarded_include_files: + mockToken = DataStruct(fn,0,os.path.basename(fn)) + reportNamingError(mockToken,'Missing include guard','includeGuardMissing') if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Naming verification') - parser.add_argument('dumpfiles', type=str, nargs='+', - help='A set of dumpfiles to process') + parser = cppcheckdata.ArgumentParser() parser.add_argument("--debugprint", action="store_true", default=False, help="Add debug prints") - parser.add_argument("--configfile", type=str, default="naming.json", + parser.add_argument("--configfile", type=str, default="namingng.config.json", help="Naming check config file") - parser.add_argument("--verify", action="store_true", default=False, - help="verify this script. Must be executed in test folder !") args = parser.parse_args() - errors = process(args.dumpfiles, args.configfile, args.debugprint) - - if args.verify: - print(errors) - if len(errors) < 6: - print("Not enough errors found") - sys.exit(1) - target = [ - '[namingng_test.c:8] ( style ) naming.py: Variable badui32 violates naming convention\n', - '[namingng_test.c:11] ( style ) naming.py: Variable a violates naming convention\n', - '[namingng_test.c:29] ( style ) naming.py: Variable badui32 violates naming convention\n', - '[namingng_test.c:20] ( style ) naming.py: Function ui16bad_underscore violates naming convention\n', - '[namingng_test.c:25] ( style ) naming.py: Function u32Bad violates naming convention\n', - '[namingng_test.c:37] ( style ) naming.py: Function Badui16 violates naming convention\n'] - diff = set(errors) - set(target) - if len(diff): - print("Not the right errors found {}".format(str(diff))) - sys.exit(1) - print("Verification done\n") - sys.exit(0) - - if len(errors): - print('Found errors: {}'.format(len(errors))) - sys.exit(1) + process(args.dumpfile, args.configfile, args.cli, args.debugprint) sys.exit(0) diff --git a/addons/runaddon.py b/addons/runaddon.py index 536abe864f7..26ad7e9fa73 100644 --- a/addons/runaddon.py +++ b/addons/runaddon.py @@ -1,4 +1,8 @@ -import cppcheckdata, cppcheck, runpy, sys, os +import cppcheckdata +import cppcheck +import runpy +import sys +import os if __name__ == '__main__': addon = sys.argv[1] diff --git a/addons/test/misra/config1.c b/addons/test/misra/config1.c new file mode 100644 index 00000000000..31aa2a4d6b5 --- /dev/null +++ b/addons/test/misra/config1.c @@ -0,0 +1,10 @@ + +struct S { + uint32_t some[100]; +}; + +void foo( void ) +{ + if (((S *)0x8000)->some[0] != 0U) { } +} + diff --git a/addons/test/misra/crash10.c b/addons/test/misra/crash10.c new file mode 100644 index 00000000000..455d86e57ec --- /dev/null +++ b/addons/test/misra/crash10.c @@ -0,0 +1,12 @@ +//#12267 + +extern uint32_t end; + +//#define KEEP // if uncomment this then wont crash + +KEEP static const int32_t ptr_to_end = &end; + +void foo(void) +{ + (void)ptr_to_end; +} diff --git a/addons/test/misra/crash11.c b/addons/test/misra/crash11.c new file mode 100644 index 00000000000..b758e69f31e --- /dev/null +++ b/addons/test/misra/crash11.c @@ -0,0 +1,2 @@ +// #12651 +__arm__ diff --git a/addons/test/misra/crash12.c b/addons/test/misra/crash12.c new file mode 100644 index 00000000000..b16198ea2e7 --- /dev/null +++ b/addons/test/misra/crash12.c @@ -0,0 +1,33 @@ +// 13140 +#line 78 "tmp.h" +typedef struct +{ +int vara [30] ; +int varb [5] ; +} S0 ; + + + +typedef struct +{ +bool var1 ; +S2 var2 ; +S2 var3 ; +S2 var4 ; +short var5 ; +short var6 ; +S1 var7 ; +S1 var8 ; +S1 var9 ; +S1 var10 ; +S1 var11 ; +float var12 ; +short var13 [ 3 ] ; +} S3 ; + +#line 33 "tmp.c" +static const S3 s3 = +{ +0 , +{ 0, 0 } , +} ; \ No newline at end of file diff --git a/addons/test/misra/crash7.c b/addons/test/misra/crash7.c new file mode 100644 index 00000000000..210cfeb4df8 --- /dev/null +++ b/addons/test/misra/crash7.c @@ -0,0 +1,8 @@ + + +static const struct id3_frametype wordlist[] = +{ + {0, "Encryption method registration"}, + {1, "Popularimeter"}, +}; + diff --git a/addons/test/misra/crash8.c b/addons/test/misra/crash8.c new file mode 100644 index 00000000000..970d72540f0 --- /dev/null +++ b/addons/test/misra/crash8.c @@ -0,0 +1,10 @@ + +struct three_d_filter_t { + char name[16]; + double elem[2]; +}; + +static three_d_filter_t base_filters[] = { + {"Identity", { 1.0, 0.0 } }, + {"Echo", { 0.4, 0.0 } } +}; diff --git a/addons/test/misra/crash9.c b/addons/test/misra/crash9.c new file mode 100644 index 00000000000..5abf2b8ad02 --- /dev/null +++ b/addons/test/misra/crash9.c @@ -0,0 +1,3 @@ + +#line 3 "" +typedef int8_t flex_int8_t; diff --git a/addons/test/misra/crash_misra9_parseInitializer.c b/addons/test/misra/crash_misra9_parseInitializer.c new file mode 100644 index 00000000000..8e3dcfd5757 --- /dev/null +++ b/addons/test/misra/crash_misra9_parseInitializer.c @@ -0,0 +1,18 @@ +union { + struct { + uint8_t a; + uint8_t b; + } a; +} bar; + +struct foo { + uint8_t a; + union bar w; + uint8_t b; +}; + +struct foo asdf = { + 0, + {{0,0}}, + 1 +}; diff --git a/addons/test/misra/misra-ctu-1-test.c b/addons/test/misra/misra-ctu-1-test.c index 3b708af5c20..a003e66ae01 100644 --- a/addons/test/misra/misra-ctu-1-test.c +++ b/addons/test/misra/misra-ctu-1-test.c @@ -1,5 +1,5 @@ // Test with command: -// ./cppcheck --enable=information --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c +// ./cppcheck --enable=information --enable=style --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c #include "misra-ctu-test.h" @@ -7,6 +7,9 @@ extern MISRA_2_3_A misra_2_3_a; x = MISRA_2_5_OK_1; +// cppcheck-suppress misra-c2012-20.5 +#undef MISRA_2_5_OK_3 + // cppcheck-suppress misra-c2012-2.3 // cppcheck-suppress misra-c2012-5.6 typedef int MISRA_5_6_VIOLATION; @@ -46,3 +49,7 @@ extern int misra_8_5; int32_t misra_8_6 = 1; void misra_8_7_external(void) {} + +// #12362 +void misra_8_7_compliant( void ){} +static void misra_8_7_call(void) { misra_8_7_compliant(); } \ No newline at end of file diff --git a/addons/test/misra/misra-ctu-2-test.c b/addons/test/misra/misra-ctu-2-test.c index cae9ea82b7b..e08bd6d04a7 100644 --- a/addons/test/misra/misra-ctu-2-test.c +++ b/addons/test/misra/misra-ctu-2-test.c @@ -1,5 +1,5 @@ // Test with command: -// ./cppcheck --enable=information --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c +// ./cppcheck --enable=information --enable=style --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c #include "misra-ctu-test.h" @@ -43,7 +43,9 @@ extern int misra_8_5; // cppcheck-suppress misra-c2012-8.4 // cppcheck-suppress misra-c2012-8.6 int32_t misra_8_6 = 2; - +int32_t misra_8_6_1; +// cppcheck-suppress misra-c2012-8.7 +int32_t misra_8_6_1 = 2; // cppcheck-suppress misra-c2012-8.4 // cppcheck-suppress misra-c2012-8.7 void misra_8_7(void) {} @@ -52,3 +54,6 @@ static void misra_8_7_caller(void) { misra_8_7_external(); } +// #12362 +typedef void(*misra_8_7_func_ptr)( void ); +static const misra_8_7_func_ptr ptrs[] = { misra_8_7_compliant, NULL }; \ No newline at end of file diff --git a/addons/test/misra/misra-ctu-test.h b/addons/test/misra/misra-ctu-test.h index c9d2a7ba8a0..803e850b1f2 100644 --- a/addons/test/misra/misra-ctu-test.h +++ b/addons/test/misra/misra-ctu-test.h @@ -18,4 +18,7 @@ void misra_8_7_external(void); // cppcheck-suppress misra-c2012-2.5 #define MISRA_2_5_VIOLATION 0 +// #12362 +extern void misra_8_7_compliant( void ); +#define MISRA_2_5_OK_3 This \ No newline at end of file diff --git a/addons/test/misra/misra-suppressions1-test.c b/addons/test/misra/misra-suppressions1-test.c index 6c86495ced3..403d71f73ea 100644 --- a/addons/test/misra/misra-suppressions1-test.c +++ b/addons/test/misra/misra-suppressions1-test.c @@ -4,6 +4,7 @@ // This needs to stay at line number 7 to make the test pass // If it is changed update suppressions.txt with the new line number +// cppcheck-suppress-file misra-c2012-5.2 #include //21.6 extern int misra_5_2_var_hides_var______31x;//8.4 @@ -13,6 +14,8 @@ static void misra_5_2_function_hides_var_31y(void) {}//5.2 static void foo(void) { int i; + // cppcheck-suppress-begin misra-c2012-16.4 + // cppcheck-suppress misra-c2012-16.6 switch(misra_5_2_func1()) //16.4 16.6 { case 1: @@ -21,13 +24,14 @@ static void foo(void) { for(i = 0; i < 10; i++) { - if(misra_5_2_func3()) //14.4 + if(misra_5_2_func3()) //17.3 { int misra_5_2_var_hides_var_1____31x; int misra_5_2_var_hides_var_1____31y;//5.2 } } - } while(misra_5_2_func2()); //14.4 + } while(misra_5_2_func2()); //17.3 } } + // cppcheck-suppress-end misra-c2012-16.4 } diff --git a/addons/test/misra/misra-suppressions2-test.c b/addons/test/misra/misra-suppressions2-test.c index e32e2ab9781..79d3f68191e 100644 --- a/addons/test/misra/misra-suppressions2-test.c +++ b/addons/test/misra/misra-suppressions2-test.c @@ -2,6 +2,7 @@ // ../../cppcheck --suppressions-list=suppressions.txt --dump misra-suppressions*-test.c && python ../misra.py misra-suppressions*-test.c.dump // There should be no violations reported +// cppcheck-suppress-file misra-c2012-5.2 union misra_5_2_field_hides_field__63x { //19.2 int misra_5_2_field_hides_field__31x; int misra_5_2_field_hides_field__31y;//5.2 diff --git a/addons/test/misra/misra-test-avr8.c b/addons/test/misra/misra-test-avr8.c index e5ba751d496..faa6eb6b615 100644 --- a/addons/test/misra/misra-test-avr8.c +++ b/addons/test/misra/misra-test-avr8.c @@ -1,12 +1,26 @@ // To test: -// ~/cppcheck/cppcheck --addon=misra --platform=avr8 misra-test-avr8.c +// ~/cppcheck/cppcheck--dump -DDUMMY --suppress=uninitvar misra/misra-test-avr8.c --std=c89 --platform=avr8 && python3 ../misra.py -verify misra/misra-test-avr8.c.dump static void misra_10_4(void) { // #10480 - const char buf[1] = {'f'}; + const char buf1[1] = {a}; const char c = '0'; - x = buf[0] - c; + x = buf1[0] - c; + + const char buf2[2] = {x,y}; + x = 'a' == buf2[0]; // no-warning + + typedef struct { + int t; + char buf[2]; + } foo_t; + const foo_t cmd = {0}; + x = 'b' == cmd.buf[0]; // no-warning + + const foo_t * pcmd = &cmd; + x='c' == pcmd->buf[0]; // no-warning + (void)cmd.t; } static void misra_12_2(void) { diff --git a/addons/test/misra/misra-test-c11.c b/addons/test/misra/misra-test-c11.c new file mode 100644 index 00000000000..031bc361e5f --- /dev/null +++ b/addons/test/misra/misra-test-c11.c @@ -0,0 +1,25 @@ +// To test: +// ~/cppcheck/cppcheck --dump misra/misra-test-c11.c --std=c11 +// ~/cppcheck/cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test-c11.c --std=c11 --platform=unix64 && python3 ../misra.py -verify misra/misra-test-c11.c.dump + +#include + +typedef unsigned int UINT_TYPEDEF; +struct struct_with_bitfields +{ + unsigned int a:2; // Compliant + signed int b:2; // Compliant + UINT_TYPEDEF c:2; // Compliant + int d:2; // 6.1 - plain int not compliant + signed long f:2; // Compliant in c99 or later - explicitly signed integer type + unsigned int g:1; // Compliant + signed int h:1; // 6.2 - signed int with size 1 is not compliant + uint16_t i:1; // Compliant + bool j:1; // Compliant in C99 or later +}; + +static void misra6_1_fn(void) { + // "Use" occurrence should not generate warnings + struct_with_bitfields s; + s.h = 61; +} diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index 2fd30c7e707..743637117a5 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -2,6 +2,8 @@ // ~/cppcheck/cppcheck --dump misra/misra-test.h --std=c89 // ~/cppcheck/cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64 && python3 ../misra.py -verify misra/misra-test.c.dump +#pragma ghs section rodata=default // no warning + #include "path\file.h" // 20.2 #include "file//.h" // 20.2 #include "file/*.h" // 20.2 @@ -35,8 +37,8 @@ #include // 21.4 #include // 21.5 -#include //21.6 -#include //21.6 +#include +#include #include // 21.10 #include // 21.11 #include @@ -58,11 +60,17 @@ typedef unsigned int u32; typedef signed int s32; typedef unsigned long long u64; +static void misra_1_2(bool expr) +{ + (void)(condition ? : 0); // 1.2 + a = 1 + ({if (!expr) {code;} 1;}); // 1.2 +} + static _Atomic int misra_1_4_var; // 1.4 static _Noreturn void misra_1_4_func(void) // 1.4 { - if (0 != _Generic(misra_1_4_var)) {} // 1.4 - printf_s("hello"); // 1.4 + if (0 != _Generic(misra_1_4_var)) {} // 1.4 17.3 + printf_s("hello"); // 1.4 17.3 } #define MISRA_2_2 (1*60) @@ -113,22 +121,6 @@ static void misra_2_7_b(int a, int b, int c, // 2.7 static void misra_2_7_c(int a, ...) { (void)a; } static void misra_2_7_d(int) { } // 2.7 8.2 -static void misra_3_2(int enable) -{ - // This won't generate a violation because of subsequent blank line \ - - int y = 0; - int x = 0; // 3.2 non-compliant comment ends with backslash \ - if (enable != 0) - { - ++x; // This is always executed - // 3.2 potentially non-compliant comment ends with trigraph resolved to backslash ??/ - ++y; // This is hidden if trigraph replacement is active - } - - (void)printf("x=%i, y=%i\n", x, y); -} - extern int misra_5_1_extern_var_hides_var_x; extern int misra_5_1_extern_var_hides_var_y; //5.1 int misra_5_1_var_hides_var________a; // 8.4 @@ -146,7 +138,7 @@ static void misra_5_2_function_hides_var_31y(void) {}//5.2 static void foo(void) { int i; - switch(misra_5_2_func1()) //16.4 16.6 + switch(misra_5_2_func1()) //16.4 16.6 17.3 { case 1: { @@ -154,13 +146,13 @@ static void foo(void) { for(i = 0; i < 10; i++) { - if(misra_5_2_func3()) //14.4 + if(misra_5_2_func3()) //17.3 { int misra_5_2_var_hides_var_1____31x; int misra_5_2_var_hides_var_1____31y;//5.2 } } - } while(misra_5_2_func2()); //14.4 + } while(misra_5_2_func2()); //17.3 } break; } @@ -201,9 +193,9 @@ int c41_15 = 'a'; // 10.3 8.4 static void misra_4_1(void) { - (void)printf("\x41g"); // 4.1 - (void)printf("\x41\x42"); - (void)printf("\x41" "g"); + (void)printf("\x41g"); // 4.1 21.6 + (void)printf("\x41\x42"); //21.6 + (void)printf("\x41" "g"); //21.6 } const char *s42_1 = "String containing trigraphs ??-??-??"; // 4.2 8.4 @@ -212,8 +204,8 @@ const char *s42_3 = "No trigraph?(?'?)"; // 8.4 static void misra_4_2(void) { - (void)printf("??=Trigraph\n"); // 4.2 - (void)printf("No?/Trigraph\n"); + (void)printf("??=Trigraph\n"); // 4.2 21.6 + (void)printf("No?/Trigraph\n"); //21.6 } #define misra_5_4_macro_hides_macro__31x 1 @@ -240,17 +232,17 @@ int x; }; static void misra_5_5_func1(void) { - switch(misra_5_5_func2()) //16.4 16.6 + switch(misra_5_5_func2()) //16.4 16.6 17.3 { case 1: { do { - if(misra_5_5_func3()) //14.4 + if(misra_5_5_func3()) //17.3 { int misra_5_5_hides_macro________31y; //5.5 } - } while(misra_5_5_func2()); //14.4 + } while(misra_5_5_func2()); //17.3 } break; } @@ -267,6 +259,7 @@ struct struct_with_bitfields unsigned int g:1; // Compliant signed int h:1; // 6.2 - signed int with size 1 is not compliant uint16_t i:1; // Compliant + bool j:1; // 6.1 - bool not legal until c99 }; static void misra6_1_fn(void) { @@ -293,6 +286,20 @@ struct misra_7_3_s { uint32_t ul_clka; uint32_t test123l; + float t = 6.02E23l; // 7.3 + float t1 = 6.02E23L; + float u = 0xa1B2.p12l; // 7.3 + float u1 = 0xa1B2.p12L; + float v = 0xa1B2.P12l; // 7.3 + float v1 = 0xa1B2.P12L; + float w = 6.02e23l; // 7.3 + float w1 = 6.02e23L; + unsigned long x = 0xabcul; // 7.3 + unsigned long x1 = 0xabcuL; + unsigned long y = 0xABCUl; // 7.3 + unsigned long y1 = 0xABCUL; + unsigned long z = 0XdeadBeEfUl; // 7.3 + unsigned long z1 = 0XdeadBeEfUL; }; static void misra_7_3(void) { @@ -352,7 +359,7 @@ static int misra_8_2_g ( /* comment */ ); // 8.2 static int misra_8_2_h ( /* comment 1 */ /* comment 2 */ ); // 8.2 static int misra_8_2_i ( /* comment */ void); static int misra_8_2_j ( /* comment */ void /* comment */); -static int misra_8_2_k ( // +static int misra_8_2_k ( // void); static int misra_8_2_l ( // 8.2 ); @@ -389,6 +396,13 @@ uint8_t misra_8_4_buf2[24]; // 8.4 typedef struct { uint16_t a; uint16_t b; } misra_8_4_struct; extern misra_8_4_struct bar[42]; misra_8_4_struct bar[42]; // compliant +extern uint16_t misra_8_4_speed = 6000u; //8.4 +uint8_t misra_8_4_pressure = 101u; //8.4 +int32_t misra_8_4_ext_val2; +int32_t misra_8_4_ext_val2 = 3; // compliant +int32_t misra_8_4_ext_val4; //8.4 +// #12978 +const stError_t * m8_4_pubTestPointer; //compliant static int32_t misra_8_8 = 123; extern int32_t misra_8_8; // 8.8 @@ -412,6 +426,21 @@ static void misra_8_14(char * restrict str) {(void)str;} // 8.14 struct S_9_3 { struct S_9_3* p; int x; }; struct S_9_3* s_9_3_array[] = { x, NULL }; // 8.4 +// #10854 +struct Entry_9_2{ + union{ // 19.2 + const int *p; + int x; + }; + int y; +}; + +static void misra_9_2_10854(void){ + struct Entry_9_2 e1[] = + { + {{ .x = 1 }, .y = 2 } + }; +} static void misra_9_empty_or_zero_initializers(void) { int a[2] = {}; // 9.2 int b[2][2] = {}; // 9.2 @@ -420,6 +449,10 @@ static void misra_9_empty_or_zero_initializers(void) { int e[2][2] = { { 1 , 2 }, {} }; // 9.2 int f[5] = { 0 }; + int f1[5] = { 0u }; // 9.3 + unsigned int f1[ 3 ][ 2 ] = { 0U }; // 9.3 9.2 + unsigned int f2[ 3 ] = { 0U }; // 9.3 + float f3[ 3 ][ 2 ] = { 0.0F }; // 9.3 9.2 int g[5][2] = { 0 }; int h[2][2] = { { 0 } }; // 9.3 int i[2][2] = { { 0 }, { 0 } }; @@ -476,6 +509,7 @@ static void misra_9_array_initializers_with_designators(void) { char c[2][2] = { [0] = {1, 2, 3} }; char d[1][2] = { [0] = 1 }; // 9.2 char e[2][2] = { { 1, 2 }, [1][0] = {3, 4} }; // 9.2 + int e1[2][2] = { [ 0 ][ 1 ] = 0, { 5, 6 } }; // no warning #12419 char f[2] = { [0] = 1, 2 }; char g[2] = { [1] = 2, [0] = 1 }; char h[2][2] = { { 1, 2 }, [1] = { 3 } }; // 9.3 @@ -572,13 +606,13 @@ static void misra_9_struct_initializers(void) { // Struct with fields of unknown type struct_with_unknown_fields ufa = { 1, { 1, 2 }, { 1, 2 } }; struct_with_unknown_fields ufb = { 1, 1, 2 }; // 9.2 - struct_with_unknown_fields[2] ufc = { {1, { 1, 2 }, { 1, 2 } }, + struct_with_unknown_fields ufc[2] = { {1, { 1, 2 }, { 1, 2 } }, { 2, { 1, 2 }, { 1, 2 } } }; - struct_with_unknown_fields[2][2] ufd = { {1, { 1, 2 }, { 1, 2 } }, + struct_with_unknown_fields ufd[2][2] = { {1, { 1, 2 }, { 1, 2 } }, // 9.2 9.3 { 2, { 1, 2 }, { 1, 2 } } }; - struct_with_unknown_fields[2] ufe = { 1, { 1, 2 }, { 1, 2 }, // TODO: 9.2 + struct_with_unknown_fields ufe[2] = { 1, { 1, 2 }, { 1, 2 }, // 9.2 9.3 2, { 1, 2 }, { 1, 2 } }; - struct_with_unknown_fields[3] uff = { { 1, { 1, 2 }, { 1, 2 }}, // TODO: 9.3 9.4 + struct_with_unknown_fields uff[3] = { { 1, { 1, 2 }, { 1, 2 }}, // 9.3 9.4 {2, { 1, 2 }, { 1, 2 }}, [1] = { 2, { 1, 2 }, { 1, 2 }} }; @@ -644,21 +678,21 @@ static void misra_10_1_ternary(void) int16_t i16; a = ui16 << ui16; // 10.6 - a = ui16 << (get_bool(42) ? ui16 : ui16); - a = ui16 << (get_bool(42) ? ui16 : (get_bool(34) ? ui16 : ui16)); // 10.4 - a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : ui16) : ui16); // 10.4 - a = ui16 << (get_bool(42) ? i16 : (get_bool(34) ? ui16 : ui16)); // 10.1 - a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : i16) : ui16); // 10.1 10.4 - a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : ui16) : i16); // 10.1 - a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8); // 10.4 - a = ui16 << (get_bool(42) ? (get_bool(34) ? i16 : ui8) : ui8); // 10.1 10.4 - a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8) << ui16; // 10.4 - a = (get_bool(42) ? (get_bool(34) ? i16 : ui8) : ui8) << ui16; // 10.1 10.4 - a = (get_bool(42) ? (get_bool(34) ? ui16 : i8) : ui8) << ui16; // 10.1 10.4 - a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : i8) << ui16; // 10.1 - a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8) << (get_bool(19) ? ui16 : ui8); // 10.4 - a = (get_bool(42) ? (get_bool(34) ? i16 : ui8) : ui8) << (get_bool(19) ? ui16 : ui8); // 10.1 10.4 - a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8) << (get_bool(19) ? i16 : ui8); // 10.1 10.4 + a = ui16 << (get_bool(42) ? ui16 : ui16); // 17.3 + a = ui16 << (get_bool(42) ? ui16 : (get_bool(34) ? ui16 : ui16)); // 17.3 + a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : ui16) : ui16); // 17.3 + a = ui16 << (get_bool(42) ? i16 : (get_bool(34) ? ui16 : ui16)); // 10.1 10.4 17.3 + a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : i16) : ui16); // 10.1 10.4 17.3 + a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : ui16) : i16); // 10.1 10.4 17.3 + a = ui16 << (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8); // 10.4 17.3 + a = ui16 << (get_bool(42) ? (get_bool(34) ? i16 : ui8) : ui8); // 10.1 10.4 17.3 + a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8) << ui16; // 10.4 17.3 + a = (get_bool(42) ? (get_bool(34) ? i16 : ui8) : ui8) << ui16; // 10.1 10.4 17.3 + a = (get_bool(42) ? (get_bool(34) ? ui16 : i8) : ui8) << ui16; // 10.1 10.4 17.3 + a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : i8) << ui16; // 10.1 17.3 + a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8) << (get_bool(19) ? ui16 : ui8); // 10.4 17.3 + a = (get_bool(42) ? (get_bool(34) ? i16 : ui8) : ui8) << (get_bool(19) ? ui16 : ui8); // 10.1 10.4 17.3 + a = (get_bool(42) ? (get_bool(34) ? ui16 : ui8) : ui8) << (get_bool(19) ? i16 : ui8); // 10.1 10.4 17.3 } static void misra_10_2(void) { @@ -690,6 +724,8 @@ static void misra_10_3(uint32_t u32a, uint32_t u32b) { res = 2U + 3U; // no warning, utlr=unsigned char res = 0.1f; // 10.3 const char c = '0'; // no-warning + bool b = true; // no-warning + uint32_t u = UINT32_C(10); // no-warning } static void misra_10_4(u32 x, s32 y) { @@ -703,12 +739,26 @@ static void misra_10_4(u32 x, s32 y) { z = x + y; //10.4 z = (a == misra_10_4_A3) ? x : y; //10.4 z = (a == misra_10_4_A3) ? y : y; // no-warning - + // #10499 const char buf[10] = {0}; if ('0' == buf[x]) // no-warning { } + + const struct foo_s{ + int t; + char buf[2]; + } cmd = {0}; + if ('\0' == cmd.buf[0]) //no-warning + { + } + + // #10652 + char c; + if ((char)'1' == c) {} // no warning + if ((unsigned char)'1' == c) {} //10.4 + if ((signed char)'1' == c) {} //10.4 } static void misra_10_5(uint16_t x) { @@ -727,8 +777,9 @@ struct misra_10_6_s { static void misra_10_6(u8 x, char c1, char c2) { u16 y1 = x+x; // 10.6 u16 y2 = (0x100u - 0x80u); // rhs is not a composite expression because it's a constant expression + int b = (y2 == y2) ? 0 : 1; // no-warning u16 z = ~u8 x ;//10.6 - s32 i = c1 - c2; // 10.3 FIXME: False positive for 10.6 (this is compliant). Trac #9488 + s32 i = c1 - c2; // 10.3 struct misra_10_6_s s; s.a = x & 1U; // no-warning (#10487) } @@ -746,7 +797,7 @@ static void misra_10_7(uint16_t u16a, uint16_t u16b) { res = u32a * (u16a + u16b); // 10.7 u32a *= u16a + u16b; // 10.7 u32a = ((uint32_t)4 * (uint32_t)2 * (uint32_t)4 ); // no-warning (#10488) - dostuff(&t, (2*60*1000)); // no-warning + dostuff(&t, (2*60*1000)); // 17.3 no-warning } static void misra_10_8(u8 x, s32 a, s32 b) { @@ -758,6 +809,13 @@ static void misra_10_8(u8 x, s32 a, s32 b) { int (*misra_11_1_p)(void); // 8.4 void *misra_11_1_bad1 = (void*)misra_11_1_p; // 11.1 8.4 +// #12172 +typedef void (*pfFunc_11_1)(uint32_t some); +extern pfFunc_11_1 data_11_1[10]; +void func_11_1(pfFunc_11_1 ptr){ //8.4 + data_11_1[index] = ptr; // no-warning +} + struct misra_11_2_s; struct misra_11_2_t; @@ -770,12 +828,15 @@ static void misra_11_3(u8* p, struct Fred *fred) { struct Wilma *wilma = (struct Wilma *)fred; // 11.3 } +typedef struct { uint32_t something; } struct_11_4; +#define A_11_4 ((struct_11_4 *)0x40000U) // 11.4 + static void misra_11_4(u8*p) { u64 y = (u64)p; // 11.4 u8 *misra_11_4_A = ( u8 * ) 0x0005;// 11.4 s32 misra_11_4_B; u8 *q = ( u8 * ) misra_11_4_B; // 11.4 - + dummy = A_11_4->something; // no-warning } static void misra_11_5(void *p) { @@ -784,12 +845,21 @@ static void misra_11_5(void *p) { p16 = p; // 11.5 } +static intptr_t get_intptr_constant(void) { return 456; } static void misra_11_6(void) { void *p; + struct { + int i; + } s = { .i = 7 }; p = (void*)123; // 11.6 x = (u64)p; // 11.6 + p = (void*)(1+1);// 11.6 + p = (void*)get_intptr_constant(); // 11.6 + p = (void*)s.i; // 11.6 p = ( void * )0; // no-warning (void)p; // no-warning + // # 12184 + p = (void*)0U; // no-warning } @@ -893,9 +963,9 @@ void misra_12_3(int a, int b, int c) { int a41 = MISRA_12_3_FN3_2(a34, a35), a42; // 12.3 int a43, a44 = MISRA_12_3_FN3_2(a34, a35); // 12.3 - MISRA_12_3_FN3_2_MSG(fprintf(stderr, "test\n")); // 12.3 - - f((1,2),3); // TODO + MISRA_12_3_FN3_2_MSG(fprintf(stderr, "test\n")); // 12.3 21.6 + // TODO + f((1,2),3); // 17.3 // third clause: 2 persistent side effects instead of 1 (14.2) for (i=0; i<10; i++, j++){} // 12.3 14.2 @@ -909,8 +979,8 @@ void misra_12_3(int a, int b, int c) { misra_12_3_fn4(misra_12_3_fn7(&a1, 32), &a1); misra_12_3_fn6(misra_12_3_fn5(&a1, 32), &a1); misra_12_3_fn6(misra_12_3_fn7(&a1, 32), &a1); - misra_12_3_fn7(maxlen, fn(va, unsigned long), false); - misra_12_3_fn8(maxlen, (unsigned long)((uintptr_t)fn(va, void*)), false); + misra_12_3_fn7(maxlen, fn(va, unsigned long), false); // 17.3 + misra_12_3_fn8(maxlen, (unsigned long)((uintptr_t)fn(va, void*)), false); // 17.3 const struct fun_t { @@ -930,6 +1000,9 @@ static void misra_12_4(uint8_t t) { x = MISRA12_4a + MISRA12_4b; // 12.4 x = 0u - 1u; // 12.4 x = t ? 0u : (0u-1u); // 12.4 + x = (0u==0u) ? 0u : (0u-1u); + x = (0u!=0u) ? 0u : (0u-1u); // 12.4 + x = (0u==0u) ? 0u : (2*(0u-1u)); // 10.4 } struct misra_13_1_t { int a; int b; }; @@ -1122,12 +1195,15 @@ static s13_4_t s13_4 = .string = STRING_DEF_13_4 // no-warning }; -static void misra_13_4(void) { +static void misra_13_4(int x, int z) { + int y; if (x != (y = z)) {} // 13.4 else {} } static void misra_13_5(void) { + int x = 0; + int y = 0; if (x && (y++ < 123)){} // 13.5 if (x || ((y += 19) > 33)){} // 13.5 if (x || ((y = 25) > 33)){} // 13.5 13.4 @@ -1155,13 +1231,42 @@ static void misra_14_1(void) { } while ( a < 10.0f ); // no-warning } +//13143 +static bool misra_14_1_is_increasing (const double* const x, const size_t n) +{ + double last = -INFINITY; + size_t i = ((size_t) 0); + while ((i < n) && isfinite(x[i]) && (x[i] > last)) { //no-warning for 14_1 + last = x[i]; + i++; + } + return i == n; +} + +static void misra_14_1_compliant1_foo(float x){ + int i = 0; + while(i < x){ // 10.4 + i += x + x; // 10.3 10.4 no-warning for 14_1 + } +} +static void misra_14_1_compliant2_foo(void){ + int i = 0; + float f = 0f; + while (f < 10 && i < 10) { //10.4 12.1 + float f = 0f; + f = f + i; // 10.3 10.4 no warning for 14_1 + i++; + } +} static void misra_14_2_init_value(int32_t *var) { *var = 0; } +static void misra_14_2_init_value_1(int32_t *var); + static void misra_14_2_fn1(bool b) { for (;i++<10;) {} // 14.2 - for (;i<10;dostuff()) {} // 14.2 + for (;i<10;dostuff()) {} // 14.2 17.3 int32_t g = 0; int g_arr[42]; g += 2; // no-warning @@ -1171,12 +1276,15 @@ static void misra_14_2_fn1(bool b) { g += 2; i2 ^= 2; // 14.2 if (i2 == 2) { - g += g_arr[i2]; + g += g_arr[i2]; // cppcheck-suppress legacyUninitvar } misra_14_2_init_value(&i2); // TODO: Fix false negative in function call } - - for (misra_14_2_init_value(&i); i < 10; ++i) {} // no-warning FIXME: False positive for 14.2 Trac #9491 + int i1; + int i2; + for (misra_14_2_init_value(&i1); i1 < 10; ++i1) {} // no-warning + for (misra_14_2_init_value_1(&i2); i2 < 10; ++i2) {} // no-warning + for (misra_14_2_init_value_2(&i2); i2 < 10; ++i2) {} // 17.3 no-warning bool abort = false; for (i = 0; (i < 10) && !abort; ++i) { // 14.2 as 'i' is not a variable @@ -1226,6 +1334,17 @@ static void misra_14_2_fn1(bool b) { } } } + + static struct + { + uint16_t block; + bool readSuccessful; + int32_t i; + } + opState; + for (opState.block = 0U; opState.block < 10U; opState.block++) {;} //no-warning + + for (misra_14_2_init_value(&opState.i); opState.i < 10; ++opState.i) {} //no-warning } static void misra_14_2_fn2(void) { @@ -1276,13 +1395,26 @@ struct { unsigned int y:1; } r14_4_struct; // 8.4 static void misra_14_4(bool b) { - if (x+4){} // 14.4 + if (x+4){} //config else {} if (b) {} else {} if (r14_4_struct.x) {} + + // #12079 + if (z) {} //config +} + +// #12417 +struct bar_12417{ int a; }; +static int foo_12417(void){ + int ret = 1; + if (sizeof(struct bar_12417) == 0U){ // no warning for misra-config + ret = 0; + } + return ret; } static void misra_15_1(void) { @@ -1295,7 +1427,9 @@ static void misra_15_2(void) { goto label; // 15.2 15.1 } -static void misra_15_3(void) { +static void misra_15_3(int a) { + int x = 0; + int y; if (x!=0) { goto L1; // 15.3 15.1 if (y!=0) { @@ -1410,14 +1544,14 @@ static void misra_15_4(void) { } } -static int misra_15_5(void) { +static int misra_15_5(int x) { if (x!=0) { return 1; // 15.5 } else {} return 2; } -static void misra_15_6(void) { +static void misra_15_6(int x) { if (x!=0); // 15.6 else{} @@ -1449,7 +1583,7 @@ static void misra_15_6_fp(void) #if defined(M_20_9) && M_20_9 > 1 // no-warning (#10380) #endif -static void misra_15_7(void) { +static void misra_15_7(int x, int a, int b) { uint32_t var = 0; uint32_t var2 = 0; @@ -1485,7 +1619,7 @@ static void misra_16_1(int32_t i) { } } -static void misra_16_2(void) { +static void misra_16_2(int y) { switch (x) { default: break; @@ -1497,7 +1631,8 @@ static void misra_16_2(void) { } } -static void misra_16_3(void) { +static void misra_16_3(int b) { + int a; switch (x) { case 1: case 2: @@ -1639,7 +1774,7 @@ static void misra_17_1(void) { va_arg(); // 17.1 va_start(); // 17.1 va_end(); // 17.1 - va_copy(); // 17.1 + va_copy(); // 17.1 17.3 } static void misra_17_2_ok_1(void) { ; } @@ -1669,11 +1804,31 @@ static void misra_17_2_5(void) { misra_17_2_1(); // no-warning } +bool (*dostuff)(); //8.2 8.4 +struct s173{ + int a; + int b; +} +static void misra_17_3(void) { + if (dostuff()) {} // no-warning + bool a = dostuff(); // no-warning + dostuff2(); // 17.3 + s173 ( *misra_8_2_p_a ) (void); // no-warning +} + +static void misra_config(const char* str) { + if (strlen(str) > 3){} //10.4 + if (sizeof(int) > 1){} //10.4 +} + static void misra_17_6(int x[static 20]) {(void)x;} // 17.6 static int calculation(int x) { return x + 1; } static void misra_17_7(void) { calculation(123); // 17.7 + int (*calc_ptr)(int) = &calculation; + calc_ptr(123); // 17.7 + int y = calc_ptr(123); } static void misra_17_8(int x) { @@ -1713,6 +1868,7 @@ struct { } r18_7_struct; // 8.4 struct { uint16_t len; + int (*array_param_func_ptr)(char const *argv[], int argc); // no-warning uint8_t data_1[ 19 ]; uint8_t data_2[ ]; // 18.7 } r18_7_struct; // 8.4 @@ -1726,6 +1882,8 @@ static void misra_18_8(int x) { int buf1[10]; int buf2[sizeof(int)]; int vla[x]; // 18.8 + // #9498 + int vlb[y]; // config static const unsigned char arr18_8_1[] = UNDEFINED_ID; static uint32_t enum_test_0[R18_8_ENUM_CONSTANT_0] = {0}; } @@ -1801,7 +1959,7 @@ static int misra_21_1(void) { int _a = 42; // no warning: only directives affected errno = EINVAL; // no warning _a ++; // no warning - _exit(1); // no warning + _exit(1); // 17.3 no warning return _a; // no warning } static int _misra_21_1_2(void); // no warning @@ -1865,6 +2023,24 @@ static void misra_21_16_f1(struct misra_21_16_S *s1, struct misra_21_16_S *s2) { static void misra_21_16_f2(char *x, char *y) { (void)memcmp(x, y, 10); // 21.16 } +typedef enum { R21_16_A, R21_16_B} r21_16_enum; +static void misra_21_16_f3(void) { + int const a[2] = {0}; + int const b[2] = {0}; + (void)memcmp(a, b, 2); // no-warning + uint8_t const c[2] = {0}; + uint8_t const d[2] = {0}; + (void)memcmp(c, d, 2); // no-warning + bool const e[2] = {0}; + bool const f[2] = {0}; + (void)memcmp(e, f, 2); // no-warning + r21_16_enum const g[2] = {0}; + r21_16_enum const h[2] = {0}; + (void)memcmp(g, h, 2); // no-warning + char const i[2] = {0}; + char const j[2] = {0}; + (void)memcmp(i, j, 2); // 21.16 +} static void misra_21_19(void) { char *s = setlocale(LC_ALL,0); // 21.19 @@ -1913,4 +2089,23 @@ static void misra_22_10(void) errno = 0; f = strtod ( "A.12", NULL ); if ( 0 == errno ) {} + + // #10855 + f = strtol(numbuf, 0, (formatHex == 0U) ? 0 : 16); + if (errno != 0) {} + + // #11752 + #define NULL_PTR ((void*)0) + f = strtod(inStr, NULL_PTR); + if(errno != 0) {} +} + +// #12448 +static void check_misra_config(void) +{ + if (sizeof(struct bar) == 0U) {} //no warning + if (sizeof(int abc) == 0U) {} //no warning + if (sizeof(xyz) == 0U) {} //no warning + if (sizeof(const pqr) == 0U) {} //no warning + if (sizeof(const int* const pqrs) == 0U) {} //no-warning } diff --git a/addons/test/misra/misra-test.h b/addons/test/misra/misra-test.h index fe5cbf5c380..b455134893c 100644 --- a/addons/test/misra/misra-test.h +++ b/addons/test/misra/misra-test.h @@ -4,4 +4,10 @@ struct misra_h_s { int foo; }; bool test(char *a); // OK int misra_8_2_no_fp(int a); void misra_8_4_bar(void); +// #12978 +typedef struct m8_4_stErrorDef +{ + uint8_t ubReturnVal; +} m8_4_stErrorDef; +extern const m8_4_stErrorDef * m8_4_pubTestPointer; #endif // MISRA_TEST_H diff --git a/addons/test/misra/misra_rules_structure.txt b/addons/test/misra/misra_rules_structure.txt index 41d2d456f85..a8223fde948 100644 --- a/addons/test/misra/misra_rules_structure.txt +++ b/addons/test/misra/misra_rules_structure.txt @@ -11,7 +11,10 @@ Here we go: Appendix A Summary of guidelines Rule 1.2 -Rule text. + Rule text. + +Rule 2.1 +Rule text for 2.1. Stop parsing after this line: Appendix B diff --git a/addons/test/misra/suppressions.txt b/addons/test/misra/suppressions.txt index 81493ae6a45..139e088552e 100644 --- a/addons/test/misra/suppressions.txt +++ b/addons/test/misra/suppressions.txt @@ -1,9 +1,6 @@ misra-c2012-21.6:*/misra-suppressions1-test.c:7 -misra-c2012-14.4 -misra-c2012-5.2 +misra-c2012-17.3 misra-c2012-8.4:*/misra-suppressions1-test.c -misra-c2012-16.4:*/misra-suppressions1-test.c -misra-c2012-16.6:*/misra-suppressions1-test.c misra-c2012-4.1:*/misra-suppressions2-test.c misra-c2012-8.4:*/misra-suppressions2-test.c misra-c2012-19.2:*/misra-suppressions2-test.c diff --git a/addons/test/test-misra.py b/addons/test/misra_test.py similarity index 53% rename from addons/test/test-misra.py rename to addons/test/misra_test.py index ba1dbaae74a..55a24cb4b27 100644 --- a/addons/test/test-misra.py +++ b/addons/test/misra_test.py @@ -1,30 +1,24 @@ -# Running the test with Python 2: -# Be sure to install pytest version 4.6.4 (newer should also work) -# Command in cppcheck directory: -# python -m pytest addons/test/test-misra.py -# # Running the test with Python 3: # Command in cppcheck directory: -# PYTHONPATH=./addons python3 -m pytest addons/test/test-misra.py +# PYTHONPATH=./addons python3 -m pytest addons/test/misra_test.py import pytest import re import sys +import os from .util import dump_create, dump_remove, convert_json_output +from addons.misra import C11_STDLIB_IDENTIFIERS, C99_STDLIB_IDENTIFIERS,C90_STDLIB_IDENTIFIERS, isStdLibId, isKeyword +TEST_SOURCE_FILES = [os.path.join('addons','test','misra','misra-test.c')] -TEST_SOURCE_FILES = ['./addons/test/misra/misra-test.c'] - -def setup_module(module): - for f in TEST_SOURCE_FILES: - dump_create(f) - - -def teardown_module(module): - for f in TEST_SOURCE_FILES: - dump_remove(f) +def remove_misra_config(s:str): + ret = '' + for line in s.splitlines(): + if '[misra-config]' not in line: + ret += line + '\n' + return ret @pytest.fixture(scope="function") @@ -36,11 +30,23 @@ def checker(): return MisraChecker(settings) +# FIXME: files are generates in the source tree so it will cause issues if tests are run with xdist. +@pytest.fixture +def test_files(): + for f in TEST_SOURCE_FILES: + dump_create(f) + yield + for f in TEST_SOURCE_FILES: + dump_remove(f) + + def test_loadRuleTexts_structure(checker): checker.loadRuleTexts("./addons/test/misra/misra_rules_structure.txt") assert(checker.ruleTexts.get(101, None) is None) assert(checker.ruleTexts[102].text == "Rule text.") assert(checker.ruleTexts.get(103, None) is None) + assert(checker.ruleTexts[201].text == "Rule text for 2.1.") + assert(checker.ruleTexts.get(202, None) is None) def test_loadRuleTexts_empty_lines(checker): @@ -55,7 +61,7 @@ def test_loadRuleTexts_mutiple_lines(checker): assert(checker.ruleTexts[102].text == "Multiple lines text.") assert(checker.ruleTexts[103].text == "Multiple lines text.") assert(checker.ruleTexts[104].text == "Should") - assert(checker.ruleTexts[105].text == "Should") + assert(checker.ruleTexts[105].text == "Should starts from lowercase letter.") assert(checker.ruleTexts[106].text == "Can contain empty lines.") @@ -75,7 +81,7 @@ def test_rules_misra_severity(checker): assert(checker.ruleTexts[2104].misra_severity == '') -def test_json_out(checker, capsys): +def test_json_out(checker, capsys, test_files): sys.argv.append("--cli") checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.parseDump("./addons/test/misra/misra-test.c.dump") @@ -88,20 +94,20 @@ def test_json_out(checker, capsys): assert("Advisory" in json_output['c2012-20.1'][0]['extra']) -def test_rules_cppcheck_severity(checker, capsys): +def test_rules_cppcheck_severity(checker, capsys, test_files): checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.parseDump("./addons/test/misra/misra-test.c.dump") captured = capsys.readouterr().err - assert("(error)" not in captured) + assert("(error)" not in remove_misra_config(captured)) assert("(warning)" not in captured) assert("(style)" in captured) -def test_rules_cppcheck_severity_custom(checker, capsys): +def test_rules_cppcheck_severity_custom(checker, capsys, test_files): checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.setSeverity("custom-severity") checker.parseDump("./addons/test/misra/misra-test.c.dump") captured = capsys.readouterr().err - assert("(error)" not in captured) + assert("(error)" not in remove_misra_config(captured)) assert("(warning)" not in captured) assert("(style)" not in captured) assert("(custom-severity)" in captured) @@ -112,15 +118,13 @@ def test_rules_suppression(checker, capsys): for src in test_sources: re_suppressed= r"\[%s\:[0-9]+\]" % src - dump_remove(src) - dump_create(src, "--suppressions-list=addons/test/misra/suppressions.txt") + dump_create(src, "--suppressions-list=addons/test/misra/suppressions.txt","--inline-suppr") checker.parseDump(src + ".dump") captured = capsys.readouterr().err found = re.search(re_suppressed, captured) assert found is None, 'Unexptected output:\n' + captured dump_remove(src) - def test_arguments_regression(): args_ok = ["-generate-table", "--rule-texts=./addons/test/assets/misra_rules_multiple_lines.txt", @@ -160,3 +164,81 @@ def test_arguments_regression(): sys.argv.remove(arg) finally: sys.argv = sys_argv_old + + +def test_read_ctu_info_line(checker): + assert checker.read_ctu_info_line('{') is None + assert checker.read_ctu_info_line('{"summary":"123"}') is None + assert checker.read_ctu_info_line('{"data":123}') is None + assert checker.read_ctu_info_line('{"summary":"123","data":123}') is not None + +def test_platform(checker): + test_file = os.path.join('addons','test','misra','misra-test.c') + dump_create(test_file, "--language=c++") + checker.parseDump(test_file + ".dump") + assert checker.is_cpp is True + + dump_create(test_file, "--language=c") + checker.parseDump(test_file + ".dump") + assert checker.is_cpp is False + +def test_std99_identifiers(): + for headerfile in C90_STDLIB_IDENTIFIERS: + for identifier in C90_STDLIB_IDENTIFIERS[headerfile]: + assert identifier in C99_STDLIB_IDENTIFIERS[headerfile], f"{identifier} of C90 not found in C99_STDLIB_IDENTIFIERS" + +def test_stdC11_identifiers(): + for headerfile in C90_STDLIB_IDENTIFIERS: + for identifier in C90_STDLIB_IDENTIFIERS[headerfile]: + assert identifier in C99_STDLIB_IDENTIFIERS[headerfile], f"{identifier} of C90 not found in C11_STDLIB_IDENTIFIERS" + for headerfile in C99_STDLIB_IDENTIFIERS: + for identifier in C99_STDLIB_IDENTIFIERS[headerfile]: + assert identifier in C11_STDLIB_IDENTIFIERS[headerfile], f"{identifier} of C99 not found in C11_STDLIB_IDENTIFIERS" + +def test_isStdLibId(): + # Check that Identifiers from C90 are correctly classified + assert isStdLibId("assert", 'c89') is True + assert isStdLibId("assert", 'c99') is True + assert isStdLibId("assert", 'c11') is True + assert isStdLibId("assert", 'c23') is True + + # Check that Identifiers from C99 are correctly classified + assert isStdLibId("UINT32_C", 'c89') is False + assert isStdLibId("UINT32_C", 'c99') is True + assert isStdLibId("UINT32_C", 'c11') is True + assert isStdLibId("UINT32_C", 'c23') is True + + # Check that Identifiers from C11 are correctly classified + assert isStdLibId("sprintf_s", 'c89') is False + assert isStdLibId("sprintf_s", 'c99') is False + assert isStdLibId("sprintf_s", 'c11') is True + assert isStdLibId("sprintf_s", 'c23') is True + + # Function Defaulting to C99 + assert isStdLibId("assert") is True + assert isStdLibId("UINT32_C") is True + assert isStdLibId("sprintf_s") is False + +def test_isKeyword(): + # Check that Keywords from C90 are correctly classified + assert isKeyword("if", 'c89') is True + assert isKeyword("if", 'c99') is True + assert isKeyword("if", 'c11') is True + assert isKeyword("if", 'c23') is True + + # Check that Keywords from C99 are correctly classified + assert isKeyword("inline", 'c89') is False + assert isKeyword("inline", 'c99') is True + assert isKeyword("inline", 'c11') is True + assert isKeyword("inline", 'c23') is True + + # Check that Keywords from C11 are correctly classified + assert isKeyword("static_assert", 'c89') is False + assert isKeyword("static_assert", 'c99') is False + assert isKeyword("static_assert", 'c11') is True + assert isKeyword("static_assert", 'c23') is True + + # Function Defaulting to C99 + assert isKeyword("if") is True + assert isKeyword("inline") is True + assert isKeyword("static_assert") is False diff --git a/addons/test/namingng_test.c b/addons/test/namingng_test.c deleted file mode 100644 index 2eaf3899666..00000000000 --- a/addons/test/namingng_test.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -uint32_t ui32Good (int abc) -{ - uint32_t ui32good; - int32_t i32good; - uint32_t badui32; - int32_t badi32; - - uint32_t a; // Short - return 5; -} - -uint16_t ui16Good (int a) -{ - return 5; -} - -uint16_t ui16bad_underscore (int a) -{ - return 5; -} - -uint32_t u32Bad (int a) -{ - uint32_t ui32good; - int32_t i32good; - uint32_t badui32; - int32_t badi32; - int * intpointer=NULL; - int ** intppointer=NULL; - int *** intpppointer=NULL; - return 5; -} - -uint16_t Badui16 (int a) -{ - return 5; -} - -void * Pointer() -{ - return NULL; -} - -void ** PPointer() -{ - return NULL; -} diff --git a/addons/test/util.py b/addons/test/util.py index 9413a2d0c5e..0f99534edc6 100644 --- a/addons/test/util.py +++ b/addons/test/util.py @@ -21,21 +21,22 @@ def find_cppcheck_binary(): def dump_create(fpath, *argv): cppcheck_binary = find_cppcheck_binary() cmd = [cppcheck_binary, "--dump", "-DDUMMY", "--quiet", fpath] + list(argv) - p = subprocess.Popen(cmd) - p.communicate() - if p.returncode != 0: - raise OSError("cppcheck returns error code: %d" % p.returncode) - subprocess.Popen(["sync"]) + with subprocess.Popen(cmd) as p: + p.communicate() + if p.returncode != 0: + raise OSError("cppcheck returns error code: %d" % p.returncode) def dump_remove(fpath): - subprocess.Popen(["rm", "-f", fpath + ".dump"]) + os.remove(fpath + ".dump") def convert_json_output(raw_json_strings): """Convert raw stdout/stderr cppcheck JSON output to python dict.""" json_output = {} for line in raw_json_strings: + if line.startswith('{"summary":'): + continue try: json_line = json.loads(line) # json_output[json_line['errorId']] = json_line diff --git a/addons/test/y2038/y2038-test-compiler-flags.c b/addons/test/y2038/y2038-test-compiler-flags.c new file mode 100644 index 00000000000..99baa0e1582 --- /dev/null +++ b/addons/test/y2038/y2038-test-compiler-flags.c @@ -0,0 +1,25 @@ +/* + * Shared test case for Y2038 addon compiler flag testing + * + * This file tests various compiler flag scenarios: + * - Proper Y2038 configuration: -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 -D_USE_TIME_BITS64 + * - Incorrect _TIME_BITS value: -D_TIME_BITS=32 + * - Incomplete configuration: -D_USE_TIME_BITS64 (without _TIME_BITS) + * + * The same source code is used for all scenarios - differentiation happens + * through the compiler flags passed to cppcheck during dump creation. + */ + +#include + +int main(int argc, char **argv) +{ + time_t current_time; + struct timespec ts; + + current_time = time(NULL); + clock_gettime(CLOCK_REALTIME, &ts); + + return 0; +} + diff --git a/addons/test/test-y2038.py b/addons/test/y2038_test.py similarity index 63% rename from addons/test/test-y2038.py rename to addons/test/y2038_test.py index f76a87613e7..861b006d8bf 100644 --- a/addons/test/test-y2038.py +++ b/addons/test/y2038_test.py @@ -21,18 +21,28 @@ './addons/test/y2038/y2038-test-4-good.c', './addons/test/y2038/y2038-test-5-good-no-time-used.c'] +# Build system test file (for testing build system integration) +BUILD_SYSTEM_TEST_FILE = './addons/test/y2038/y2038-test-buildsystem.c' + def setup_module(module): sys.argv.append("--cli") + + # Create dumps for regular test files for f in TEST_SOURCE_FILES: dump_create(f) + # For build system tests, we'll create dumps on-demand in each test + # to avoid conflicts from multiple dump_create calls on the same file + def teardown_module(module): sys.argv.remove("--cli") for f in TEST_SOURCE_FILES: dump_remove(f) + # Build system test dumps are cleaned up individually in each test method + def test_1_bad_time_bits(capsys): is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-1-bad-time-bits.c.dump', quiet=True) @@ -81,6 +91,7 @@ def test_3_no_use_time_bits(capsys): def test_4_good(capsys): + # pylint: disable-next=unused-variable - FIXME is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-4-good.c.dump', quiet=True) # assert(is_safe is True) # FIXME: This should be a "good" example returning "True" instead of "False" captured = capsys.readouterr() @@ -106,6 +117,31 @@ def test_5_good(capsys): assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0) +def test_build_system_integration(): + """Test that Y2038 flags are properly parsed from cppcheck dump file configuration""" + from addons.y2038 import parse_dump_config + + # Test Y2038-safe configuration string (as cppcheck would generate it) + config_string = "_TIME_BITS=64;_FILE_OFFSET_BITS=64;_USE_TIME_BITS64" + result = parse_dump_config(config_string) + # Y2038-safe flags should be detected + assert result['time_bits_defined'] is True + assert result['time_bits_value'] == 64 + assert result['use_time_bits64_defined'] is True + assert result['file_offset_bits_defined'] is True + assert result['file_offset_bits_value'] == 64 + + # Test partial Y2038 configuration + partial_config = "_TIME_BITS=32;_FILE_OFFSET_BITS=64" + result = parse_dump_config(partial_config) + # Should detect the flags with their actual values + assert result['time_bits_defined'] is True + assert result['time_bits_value'] == 32 # Not Y2038-safe value + assert result['use_time_bits64_defined'] is False + assert result['file_offset_bits_defined'] is True + assert result['file_offset_bits_value'] == 64 + + def test_arguments_regression(): args_ok = ["-t=foo", "--template=foo", "-q", "--quiet", @@ -136,4 +172,35 @@ def test_arguments_regression(): pytest.fail("Unexpected SystemExit with '%s'" % arg) sys.argv.remove(arg) finally: - sys.argv = sys_argv_old \ No newline at end of file + sys.argv = sys_argv_old + + +def test_parse_dump_config(): + """Test the parse_dump_config function for cppcheck dump file integration""" + from addons.y2038 import parse_dump_config + + # Test comprehensive Y2038 configuration + full_config = "_TIME_BITS=64;_FILE_OFFSET_BITS=64;_USE_TIME_BITS64;OTHER_FLAG=1" + result = parse_dump_config(full_config) + + assert result['time_bits_defined'] is True + assert result['time_bits_value'] == 64 + assert result['use_time_bits64_defined'] is True + assert result['file_offset_bits_defined'] is True + assert result['file_offset_bits_value'] == 64 + + # Test empty configuration + result = parse_dump_config("") + assert result['time_bits_defined'] is False + assert result['time_bits_value'] is None + assert result['use_time_bits64_defined'] is False + assert result['file_offset_bits_defined'] is False + assert result['file_offset_bits_value'] is None + # Test Y2038-unsafe configuration + unsafe_config = "_TIME_BITS=32;_FILE_OFFSET_BITS=32" + result = parse_dump_config(unsafe_config) + assert result['time_bits_defined'] is True + assert result['time_bits_value'] == 32 + assert result['use_time_bits64_defined'] is False + assert result['file_offset_bits_defined'] is True + assert result['file_offset_bits_value'] == 32 \ No newline at end of file diff --git a/addons/y2038.py b/addons/y2038.py index 2c3856c5d23..b17d41dd330 100755 --- a/addons/y2038.py +++ b/addons/y2038.py @@ -2,30 +2,58 @@ # # cppcheck addon for Y2038 safeness detection # +# This addon provides comprehensive Y2038 (Year 2038 Problem) detection for C/C++ code. +# It extracts compiler flags from cppcheck dump file configuration to determine +# Y2038 safety, suppressing warnings when proper configuration is detected. +# +# Key Features: +# - Extraction of Y2038-related flags from cppcheck dump file configuration +# - Compiler flag parsing and validation from cppcheck's project parsing +# - Warning suppression when proper Y2038 configuration is found +# - Support for both _TIME_BITS=64 and _FILE_OFFSET_BITS=64 requirements +# - Priority-based flag resolution (dump file configuration > source code directives) +# # Detects: # # 1. _TIME_BITS being defined to something else than 64 bits -# 2. _USE_TIME_BITS64 being defined when _TIME_BITS is not -# 3. Any Y2038-unsafe symbol when _USE_TIME_BITS64 is not defined. +# 2. _FILE_OFFSET_BITS being defined to something else than 64 bits +# 3. _USE_TIME_BITS64 being defined when _TIME_BITS is not +# 4. Any Y2038-unsafe symbol when proper Y2038 configuration is not present +# 5. Dump file configurations that affect Y2038 safety +# +# Warning Suppression: +# When both _TIME_BITS=64 AND _FILE_OFFSET_BITS=64 are detected (prioritizing dump file +# configuration over source code directives), Y2038 warnings are suppressed and an +# informational message is displayed instead. # # Example usage: # $ cppcheck --addon=y2038 path-to-src/test.c +# $ cppcheck --dump file.c && python3 y2038.py file.c.dump # from __future__ import print_function import cppcheckdata import sys -import os import re +# Y2038 flags are extracted by cppcheck core during project parsing +# and passed through dump file configuration - no redundant parsing needed + +# -------------------------------- +# Y2038 safety constants +# -------------------------------- + +# Y2038-safe bit values +Y2038_SAFE_TIME_BITS = 64 +Y2038_SAFE_FILE_OFFSET_BITS = 64 # -------------------------------------------- # #define/#undef detection regular expressions # -------------------------------------------- # test for '#define _TIME_BITS 64' -re_define_time_bits_64 = re.compile(r'^\s*#\s*define\s+_TIME_BITS\s+64\s*$') +re_define_time_bits_64 = re.compile(rf'^\s*#\s*define\s+_TIME_BITS\s+{Y2038_SAFE_TIME_BITS}\s*$') # test for '#define _TIME_BITS ...' (combine w/ above to test for 'not 64') re_define_time_bits = re.compile(r'^\s*#\s*define\s+_TIME_BITS\s+.*$') @@ -39,6 +67,34 @@ # test for '#undef _USE_TIME_BITS64' (if it ever happens) re_undef_use_time_bits64 = re.compile(r'^\s*#\s*undef\s+_USE_TIME_BITS64\s*$') +# test for '#define _FILE_OFFSET_BITS 64' +re_define_file_offset_bits_64 = re.compile(rf'^\s*#\s*define\s+_FILE_OFFSET_BITS\s+{Y2038_SAFE_FILE_OFFSET_BITS}\s*$') + +# test for '#define _FILE_OFFSET_BITS ...' (combine w/ above to test for 'not 64') +re_define_file_offset_bits = re.compile(r'^\s*#\s*define\s+_FILE_OFFSET_BITS\s+.*$') + +# test for '#undef _FILE_OFFSET_BITS' (if it ever happens) +re_undef_file_offset_bits = re.compile(r'^\s*#\s*undef\s+_FILE_OFFSET_BITS\s*$') + +# -------------------------------------------- +# Compiler flag parsing regular expressions +# -------------------------------------------- + +# test for '_TIME_BITS=64' in compiler flags +re_flag_time_bits_64 = re.compile(rf'_TIME_BITS={Y2038_SAFE_TIME_BITS}(?:\s|$|;)') + +# test for '_TIME_BITS=...' in compiler flags (combine w/ above to test for 'not 64') +re_flag_time_bits = re.compile(r'_TIME_BITS=(\d+)') + +# test for '_USE_TIME_BITS64' in compiler flags +re_flag_use_time_bits64 = re.compile(r'_USE_TIME_BITS64(?:\s|$|=|;)') + +# test for '_FILE_OFFSET_BITS=64' in compiler flags +re_flag_file_offset_bits_64 = re.compile(rf'_FILE_OFFSET_BITS={Y2038_SAFE_FILE_OFFSET_BITS}(?:\s|$|;)') + +# test for '_FILE_OFFSET_BITS=...' in compiler flags +re_flag_file_offset_bits = re.compile(r'_FILE_OFFSET_BITS=(\d+)') + # -------------------------------- # List of Y2038-unsafe identifiers # -------------------------------- @@ -58,7 +114,6 @@ 'timeval', 'utimbuf', 'itimerspec', - 'stat', 'clnt_ops', 'elf_prstatus', 'itimerval', @@ -149,13 +204,142 @@ } + + + + + + + +def parse_dump_config(config_name): + """ + Parse Y2038-related flags from cppcheck dump file configuration name. + + This function analyzes the cppcheck dump file configuration name (which contains + preprocessor definitions extracted by cppcheck from project files like compile_commands.json) + to extract Y2038-related definitions. It looks for _TIME_BITS, _USE_TIME_BITS64, and + _FILE_OFFSET_BITS definitions and validates their values. + + Args: + config_name (str): The cppcheck configuration name from dump file + (e.g., "_TIME_BITS=64;_FILE_OFFSET_BITS=64") + + Returns: + dict: Dictionary containing Y2038-related flag information with keys: + - 'time_bits_defined' (bool): Whether _TIME_BITS is defined + - 'time_bits_value' (int|None): Value of _TIME_BITS (None if not defined) + - 'use_time_bits64_defined' (bool): Whether _USE_TIME_BITS64 is defined + - 'file_offset_bits_defined' (bool): Whether _FILE_OFFSET_BITS is defined + - 'file_offset_bits_value' (int|None): Value of _FILE_OFFSET_BITS (None if not defined) + + Example: + >>> parse_dump_config("_TIME_BITS=64;_FILE_OFFSET_BITS=64") + { + 'time_bits_defined': True, + 'time_bits_value': 64, + 'use_time_bits64_defined': False, + 'file_offset_bits_defined': True, + 'file_offset_bits_value': 64 + } + """ + result = { + 'time_bits_defined': False, + 'time_bits_value': None, + 'use_time_bits64_defined': False, + 'file_offset_bits_defined': False, + 'file_offset_bits_value': None + } + + if not config_name: + return result + + try: + # Check for _TIME_BITS=64 (correct value) + if re_flag_time_bits_64.search(config_name): + result['time_bits_defined'] = True + result['time_bits_value'] = Y2038_SAFE_TIME_BITS + else: + # Check for _TIME_BITS=other_value + match = re_flag_time_bits.search(config_name) + if match: + result['time_bits_defined'] = True + try: + result['time_bits_value'] = int(match.group(1)) + except (ValueError, IndexError): + # Malformed _TIME_BITS value, treat as undefined + result['time_bits_defined'] = False + result['time_bits_value'] = None + + # Check for _USE_TIME_BITS64 + if re_flag_use_time_bits64.search(config_name): + result['use_time_bits64_defined'] = True + + # Check for _FILE_OFFSET_BITS=64 (correct value) + if re_flag_file_offset_bits_64.search(config_name): + result['file_offset_bits_defined'] = True + result['file_offset_bits_value'] = Y2038_SAFE_FILE_OFFSET_BITS + else: + # Check for _FILE_OFFSET_BITS=other_value + match = re_flag_file_offset_bits.search(config_name) + if match: + result['file_offset_bits_defined'] = True + try: + result['file_offset_bits_value'] = int(match.group(1)) + except (ValueError, IndexError): + # Malformed _FILE_OFFSET_BITS value, treat as undefined + result['file_offset_bits_defined'] = False + result['file_offset_bits_value'] = None + + except (AttributeError, TypeError, ValueError): + # If any unexpected error occurs during parsing, return empty result + # This ensures the addon continues to work even with malformed configurations + # Note: We catch specific exceptions rather than broad Exception for better debugging + pass + + return result + + def check_y2038_safe(dumpfile, quiet=False): + """ + Main function to check Y2038 safety of C/C++ code from cppcheck dump files. + + This function performs comprehensive Y2038 analysis including: + 1. Extraction of Y2038-related compiler flags from cppcheck dump file configuration + 2. Analysis of source code preprocessor directives + 3. Warning suppression when proper Y2038 configuration is detected + 4. Reporting of Y2038-unsafe symbols and configurations + + The function implements a priority-based approach for Y2038 flag detection: + - Dump file configuration (from cppcheck's project parsing - highest priority) + - Source code #define directives (fallback) + + Warning suppression occurs when both _TIME_BITS=64 AND _FILE_OFFSET_BITS=64 + are detected from any source. When warnings are suppressed, an informational + message is displayed indicating the configuration source and suppression count. + + Args: + dumpfile (str): Path to the cppcheck XML dump file (.dump extension) + quiet (bool, optional): If True, suppress informational messages. Defaults to False. + + Returns: + bool: True if code is Y2038-safe, False if Y2038 issues were detected + + Raises: + Exception: May raise exceptions from cppcheckdata parsing or file I/O operations + + Example: + >>> check_y2038_safe("test.c.dump") # Normal operation + True + >>> check_y2038_safe("test.c.dump", quiet=True) # Suppress info messages + False + """ # Assume that the code is Y2038 safe until proven otherwise y2038safe = True # load XML from .dump file data = cppcheckdata.CppcheckData(dumpfile) srcfile = data.files[0] + for cfg in data.iterconfigurations(): if not quiet: print('Checking %s, config %s...' % (srcfile, cfg.name)) @@ -164,56 +348,231 @@ def check_y2038_safe(dumpfile, quiet=False): time_bits_defined = False srclinenr = 0 + # Priority-based flag detection: dump file configuration > source code directives + # 1. Check dump file configuration (from cppcheck's project parsing - highest priority) + dump_config_flags = parse_dump_config(cfg.name) + # Initialize effective flags with dump file configuration + effective_flags = { + 'time_bits_defined': dump_config_flags['time_bits_defined'], + 'time_bits_value': dump_config_flags['time_bits_value'], + 'use_time_bits64_defined': dump_config_flags['use_time_bits64_defined'], + 'file_offset_bits_defined': dump_config_flags['file_offset_bits_defined'], + 'file_offset_bits_value': dump_config_flags['file_offset_bits_value'] + } + + # Determine configuration source for reporting + config_source = None + has_dump_config = (dump_config_flags['time_bits_defined'] or + dump_config_flags['file_offset_bits_defined'] or + dump_config_flags['use_time_bits64_defined']) + if has_dump_config: + config_source = "cppcheck configuration" + + # Track time_bits_defined for _USE_TIME_BITS64 validation + time_bits_defined = effective_flags['time_bits_defined'] + + # Check effective _TIME_BITS value (from dump file configuration) + if effective_flags['time_bits_defined']: + if effective_flags['time_bits_value'] != Y2038_SAFE_TIME_BITS: + fake_directive = type('FakeDirective', (), { + 'file': srcfile, 'linenr': 0, 'column': 0, + 'str': 'cppcheck configuration: _TIME_BITS=%s' % effective_flags['time_bits_value'] + })() + cppcheckdata.reportError(fake_directive, 'error', + '_TIME_BITS must be defined equal to 64 (found in cppcheck configuration: _TIME_BITS=%s)' % effective_flags['time_bits_value'], + 'y2038', + 'type-bits-not-64') + y2038safe = False + + # Check effective _FILE_OFFSET_BITS value (from dump file configuration) + if effective_flags['file_offset_bits_defined']: + if effective_flags['file_offset_bits_value'] != Y2038_SAFE_FILE_OFFSET_BITS: + fake_directive = type('FakeDirective', (), { + 'file': srcfile, 'linenr': 0, 'column': 0, + 'str': 'cppcheck configuration: _FILE_OFFSET_BITS=%s' % effective_flags['file_offset_bits_value'] + })() + cppcheckdata.reportError(fake_directive, 'error', + '_FILE_OFFSET_BITS must be defined equal to 64 (found in cppcheck configuration: _FILE_OFFSET_BITS=%s)' % effective_flags['file_offset_bits_value'], + 'y2038', + 'file-offset-bits-not-64') + y2038safe = False + + # Check effective _USE_TIME_BITS64 (from dump file configuration) + if effective_flags['use_time_bits64_defined']: + if not time_bits_defined: + # _USE_TIME_BITS64 defined without _TIME_BITS is problematic + fake_directive = type('FakeDirective', (), { + 'file': srcfile, 'linenr': 0, 'column': 0, + 'str': 'cppcheck configuration: _USE_TIME_BITS64' + })() + cppcheckdata.reportError(fake_directive, 'warning', + '_USE_TIME_BITS64 is defined in cppcheck configuration but _TIME_BITS was not', + 'y2038', + 'type-bits-undef') + y2038safe = False + else: + # _USE_TIME_BITS64 defined WITH _TIME_BITS - this is correct + safe = 0 # Start of file is safe + + # 2. Fallback to source code directives when dump file configuration is not available + source_time_bits_defined = False # pylint: disable=unused-variable + source_file_offset_bits_defined = False # pylint: disable=unused-variable + source_file_offset_bits_value = None # pylint: disable=unused-variable + source_use_time_bits64_defined = False # pylint: disable=unused-variable + + # Track which flags came from source code for mixed scenario reporting + source_flags_used = { + 'time_bits': False, + 'file_offset_bits': False, + 'use_time_bits64': False + } for directive in cfg.directives: # track source line number if directive.file == srcfile: srclinenr = directive.linenr + + # Process source code directives as fallback when dump config is not available # check for correct _TIME_BITS if present if re_define_time_bits_64.match(directive.str): - time_bits_defined = True + source_time_bits_defined = True + # Only use source directive if dump config doesn't define _TIME_BITS + if not effective_flags['time_bits_defined']: + effective_flags['time_bits_defined'] = True + effective_flags['time_bits_value'] = Y2038_SAFE_TIME_BITS + time_bits_defined = True + source_flags_used['time_bits'] = True elif re_define_time_bits.match(directive.str): - cppcheckdata.reportError(directive, 'error', - '_TIME_BITS must be defined equal to 64', - 'y2038', - 'type-bits-not-64') - time_bits_defined = False - y2038safe = False + source_time_bits_defined = False + # Only use source directive if dump config doesn't define _TIME_BITS + if not effective_flags['time_bits_defined']: + source_flags_used['time_bits'] = True + cppcheckdata.reportError(directive, 'error', + '_TIME_BITS must be defined equal to 64', + 'y2038', + 'type-bits-not-64') + y2038safe = False elif re_undef_time_bits.match(directive.str): - time_bits_defined = False + source_time_bits_defined = False + # Only use source directive if dump config doesn't define _TIME_BITS + if not effective_flags['time_bits_defined']: + time_bits_defined = False + source_flags_used['time_bits'] = True + # check for correct _FILE_OFFSET_BITS if present + if re_define_file_offset_bits_64.match(directive.str): + source_file_offset_bits_defined = True + source_file_offset_bits_value = Y2038_SAFE_FILE_OFFSET_BITS + # Only use source directive if dump config doesn't define _FILE_OFFSET_BITS + if not effective_flags['file_offset_bits_defined']: + effective_flags['file_offset_bits_defined'] = True + effective_flags['file_offset_bits_value'] = Y2038_SAFE_FILE_OFFSET_BITS + source_flags_used['file_offset_bits'] = True + elif re_define_file_offset_bits.match(directive.str): + source_file_offset_bits_defined = False + # Only use source directive if dump config doesn't define _FILE_OFFSET_BITS + if not effective_flags['file_offset_bits_defined']: + source_flags_used['file_offset_bits'] = True + cppcheckdata.reportError(directive, 'error', + '_FILE_OFFSET_BITS must be defined equal to 64', + 'y2038', + 'file-offset-bits-not-64') + y2038safe = False + elif re_undef_file_offset_bits.match(directive.str): + source_file_offset_bits_defined = False + source_file_offset_bits_value = None + # Only use source directive if dump config doesn't define _FILE_OFFSET_BITS + if not effective_flags['file_offset_bits_defined']: + effective_flags['file_offset_bits_defined'] = False + effective_flags['file_offset_bits_value'] = None + source_flags_used['file_offset_bits'] = True + # check for _USE_TIME_BITS64 (un)definition if re_define_use_time_bits64.match(directive.str): safe = int(srclinenr) - # warn about _TIME_BITS not being defined - if not time_bits_defined: - cppcheckdata.reportError(directive, 'warning', - '_USE_TIME_BITS64 is defined but _TIME_BITS was not', - 'y2038', - 'type-bits-undef') + source_use_time_bits64_defined = True + # Only use source directive if dump config doesn't define _USE_TIME_BITS64 + if not effective_flags['use_time_bits64_defined']: + effective_flags['use_time_bits64_defined'] = True + source_flags_used['use_time_bits64'] = True + # warn about _TIME_BITS not being defined (check effective flags) + if not time_bits_defined: + cppcheckdata.reportError(directive, 'warning', + '_USE_TIME_BITS64 is defined but _TIME_BITS was not', + 'y2038', + 'type-bits-undef') elif re_undef_use_time_bits64.match(directive.str): unsafe = int(srclinenr) + source_use_time_bits64_defined = False + # Only use source directive if dump config doesn't define _USE_TIME_BITS64 + if not effective_flags['use_time_bits64_defined']: + source_flags_used['use_time_bits64'] = True # do we have a safe..unsafe area? - if unsafe > safe > 0: + if unsafe > safe >= 0: safe_ranges.append((safe, unsafe)) safe = -1 # check end of source beyond last directive if len(cfg.tokenlist) > 0: unsafe = int(cfg.tokenlist[-1].linenr) - if unsafe > safe > 0: + if unsafe > safe >= 0: safe_ranges.append((safe, unsafe)) + # Determine if Y2038 warnings should be suppressed + # Require BOTH _TIME_BITS=64 AND _FILE_OFFSET_BITS=64 for complete Y2038 safety + y2038_safe_config = ( + effective_flags['time_bits_defined'] and + effective_flags['time_bits_value'] == Y2038_SAFE_TIME_BITS and + effective_flags['file_offset_bits_defined'] and + effective_flags['file_offset_bits_value'] == Y2038_SAFE_FILE_OFFSET_BITS + ) + + # Update config_source for suppression reporting based on mixed scenarios + if y2038_safe_config: + # Determine configuration source for mixed scenarios + dump_flags_count = sum([ + dump_config_flags['time_bits_defined'], + dump_config_flags['file_offset_bits_defined'], + dump_config_flags['use_time_bits64_defined'] + ]) + source_flags_count = sum(source_flags_used.values()) + + if dump_flags_count > 0 and source_flags_count > 0: + # Mixed scenario: both dump config and source directives used + config_source = "mixed configuration (cppcheck configuration and source code directives)" + elif dump_flags_count > 0: + # Only dump config used + config_source = "cppcheck configuration" + elif source_flags_count > 0: + # Only source directives used + config_source = "source code directives" + else: + # Fallback (shouldn't happen if y2038_safe_config is True) + config_source = "configuration" + # go through all tokens + warnings_suppressed = 0 for token in cfg.tokenlist: if token.str in id_Y2038: - if not any(lower <= int(token.linenr) <= upper - for (lower, upper) in safe_ranges): - cppcheckdata.reportError(token, 'warning', - token.str + ' is Y2038-unsafe', - 'y2038', - 'unsafe-call') - y2038safe = False + is_in_safe_range = any(lower <= int(token.linenr) <= upper + for (lower, upper) in safe_ranges) + + if not is_in_safe_range: + if y2038_safe_config: + # Count suppressed warnings but don't report them + warnings_suppressed += 1 + else: + # Report the warning as before + cppcheckdata.reportError(token, 'warning', + token.str + ' is Y2038-unsafe', + 'y2038', + 'unsafe-call') + y2038safe = False token = token.next + # Print suppression message if warnings were suppressed + if warnings_suppressed > 0 and config_source and not quiet: + print('Y2038 warnings suppressed: Found proper Y2038 configuration in %s (_TIME_BITS=%d and _FILE_OFFSET_BITS=%d)' % (config_source, Y2038_SAFE_TIME_BITS, Y2038_SAFE_FILE_OFFSET_BITS)) + print('Suppressed %d Y2038-unsafe function warning(s)' % warnings_suppressed) + return y2038safe diff --git a/build-pcre.txt b/build-pcre.txt index 3dad4274c92..9f4e8e06e29 100644 --- a/build-pcre.txt +++ b/build-pcre.txt @@ -2,19 +2,6 @@ PCRE is a library that is used by the optional "rules" feature for the command line version of cppcheck. It is readily available on Linux and Mac OS X, but must be obtained separately for Windows. -If you're using qmake to generate makefiles, the following behavior applies: - -- If you're not on Windows, it assumes by default that you have PCRE and want - to enable rules support. You can disable rules support (removing the PCRE - dependency) by passing HAVE_RULES=no to qmake. - -- If you are on Windows, but have PCRE available, you can enable rules support - by passing HAVE_RULES=yes to qmake. - - - Note: This includes using build.bat since it calls qmake - to use PCRE and - build.bat, you need to run set HAVE_RULES=yes before each run of build.bat - - Build instructions ------------------ diff --git a/cfg/avr.cfg b/cfg/avr.cfg index 0efb2d5c75b..bb21afac352 100644 --- a/cfg/avr.cfg +++ b/cfg/avr.cfg @@ -3,8 +3,6 @@ - - @@ -86,32 +84,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -137,9 +111,6 @@ - - - false diff --git a/cfg/boost.cfg b/cfg/boost.cfg index 0702bad74d7..d181860f0bc 100644 --- a/cfg/boost.cfg +++ b/cfg/boost.cfg @@ -28,15 +28,14 @@ - - + - + @@ -44,15 +43,15 @@ - + - - + + @@ -85,6 +84,7 @@ + @@ -93,12 +93,11 @@ - - + @@ -114,7 +113,7 @@ - + @@ -1269,4 +1268,17 @@ + + + boost::lock_guard + boost::mutex::scoped_lock + boost::recursive_mutex::scoped_lock + boost::unique_lock + boost::shared_lock + + + boost::mutex + boost::recursive_mutex + + diff --git a/cfg/bsd.cfg b/cfg/bsd.cfg index 751bb03c00e..158d7a8a885 100644 --- a/cfg/bsd.cfg +++ b/cfg/bsd.cfg @@ -518,6 +518,27 @@ + + + + + false + + + + + + 0: + + + + 0: + + + + reallocarray + free + diff --git a/cfg/cairo.cfg b/cfg/cairo.cfg index 85c2a8e0946..e077c2fc40d 100644 --- a/cfg/cairo.cfg +++ b/cfg/cairo.cfg @@ -6,6 +6,7 @@ + diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng index 004e931b418..a54c967aaac 100644 --- a/cfg/cppcheck-cfg.rng +++ b/cfg/cppcheck-cfg.rng @@ -26,6 +26,9 @@ + + + @@ -35,9 +38,12 @@ - + + + + @@ -50,7 +56,7 @@ - + @@ -69,15 +75,21 @@ + + + - + + + + @@ -87,7 +99,7 @@ - + @@ -122,7 +134,7 @@ - + @@ -194,6 +206,9 @@ + + + @@ -249,6 +264,11 @@ + + + + + @@ -573,7 +593,7 @@ - + @@ -651,7 +671,7 @@ 2 - + in @@ -698,8 +718,10 @@ push pop find + find-const insert erase + append change-content change-internal change @@ -719,7 +741,7 @@ empty - + 1 diff --git a/cfg/daca.cfg b/cfg/daca.cfg deleted file mode 100644 index b2c21d66494..00000000000 --- a/cfg/daca.cfg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - false - - arg1<arg2?arg1:arg2 - - - - - - - - - - false - - arg1>arg2?arg1:arg2 - - - - - - - - diff --git a/cfg/emscripten.cfg b/cfg/emscripten.cfg index 75f02f23f05..7a5c5903cf5 100644 --- a/cfg/emscripten.cfg +++ b/cfg/emscripten.cfg @@ -1,7 +1,108 @@ - - - - + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + emscripten_asm_const_ptr + emscripten_asm_const_ptr_sync_on_main_thread + free + + + + + + + + + + + + + + + + + + diff --git a/cfg/gnu.cfg b/cfg/gnu.cfg index 23aaf657071..1c8d1597a7f 100644 --- a/cfg/gnu.cfg +++ b/cfg/gnu.cfg @@ -64,6 +64,7 @@ + @@ -75,7 +76,6 @@ - @@ -182,6 +182,25 @@ + + + + false + + + + + + + + + + + + + + + @@ -193,26 +212,6 @@ - - - false - - - - - - - - - - - false - - - - - - @@ -228,26 +227,6 @@ - - - - false - - - - - - - - - - - - - - - - false @@ -258,7 +237,8 @@ - + + true @@ -637,7 +617,7 @@ - + - @@ -1326,9 +1307,9 @@ - + - @@ -1580,11 +1561,6 @@ - - - - true - false @@ -1693,6 +1669,32 @@ + + + + false + + + + + + + + + + + + + + + + + + + + + false + diff --git a/cfg/googletest.cfg b/cfg/googletest.cfg index c93862d64f6..c32eef7274b 100644 --- a/cfg/googletest.cfg +++ b/cfg/googletest.cfg @@ -29,9 +29,11 @@ - - - + + + + + diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg index d5c55b2ca14..722efb6b76b 100644 --- a/cfg/gtk.cfg +++ b/cfg/gtk.cfg @@ -2,10 +2,12 @@ - - - - + + + + + + @@ -49,6 +51,7 @@ + @@ -177,11 +180,14 @@ + + + @@ -199,690 +205,724 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - g_thread_new - g_thread_try_new + g_thread_new + g_thread_try_new g_thread_ref g_thread_unref g_thread_join - g_variant_iter_copy - g_variant_iter_new + g_variant_iter_copy + g_variant_iter_new g_variant_iter_free - g_source_new - g_idle_source_new - g_timeout_source_new - g_timeout_source_new_seconds - g_child_watch_source_new - g_cancellable_source_new - g_io_create_watch + g_source_new + g_idle_source_new + g_timeout_source_new + g_timeout_source_new_seconds + g_child_watch_source_new + g_cancellable_source_new + g_io_create_watch g_source_ref g_source_unref - g_date_time_new - g_date_time_new_now - g_date_time_new_now_local - g_date_time_new_now_utc - g_date_time_new_from_unix_local - g_date_time_new_from_unix_utc - g_date_time_new_from_timeval_local - g_date_time_new_from_timeval_utc - g_date_time_new_local - g_date_time_new_utc - g_date_time_add - g_date_time_add_years - g_date_time_add_months - g_date_time_add_weeks - g_date_time_add_days - g_date_time_add_hours - g_date_time_add_minutes - g_date_time_add_seconds - g_date_time_add_full - g_date_time_to_timezone - g_date_time_to_local - g_date_time_to_utc + g_date_time_new + g_date_time_new_now + g_date_time_new_now_local + g_date_time_new_now_utc + g_date_time_new_from_unix_local + g_date_time_new_from_unix_utc + g_date_time_new_from_timeval_local + g_date_time_new_from_timeval_utc + g_date_time_new_local + g_date_time_new_utc + g_date_time_add + g_date_time_add_years + g_date_time_add_months + g_date_time_add_weeks + g_date_time_add_days + g_date_time_add_hours + g_date_time_add_minutes + g_date_time_add_seconds + g_date_time_add_full + g_date_time_to_timezone + g_date_time_to_local + g_date_time_to_utc g_date_time_ref g_date_time_unref - g_dir_open + g_dir_open g_dir_rewind g_dir_close - g_timer_new + g_timer_new g_timer_destroy - g_file_attribute_info_list_new - g_file_attribute_info_list_dup + g_file_attribute_info_list_new + g_file_attribute_info_list_dup g_file_attribute_info_list_ref g_file_attribute_info_list_unref - g_slist_alloc - g_slist_copy - g_slist_copy_deep + g_slist_alloc + g_slist_copy + g_slist_copy_deep g_slist_free g_slist_free_1 g_slist_free_full - g_variant_new - g_variant_new_va - g_variant_new_boolean - g_variant_new_byte - g_variant_new_int16 - g_variant_new_uint16 - g_variant_new_int32 - g_variant_new_uint32 - g_variant_new_int64 - g_variant_new_uint64 - g_variant_new_handle - g_variant_new_double - g_variant_new_string - g_variant_new_take_string - g_variant_new_printf - g_variant_new_signature - g_variant_new_object_path - g_variant_new_variant - g_variant_new_objv - g_variant_new_strv - g_variant_new_bytestring - g_variant_new_bytestring_array - g_variant_new_maybe - g_variant_new_array - g_variant_new_tuple - g_variant_new_dict_entry - g_variant_new_fixed_array - g_variant_new_from_data - g_variant_new_from_bytes - g_variant_builder_end - g_variant_new_parsed_va - g_variant_new_parsed - g_variant_byteswap - g_variant_get_child_value - g_variant_get_normal_form - g_variant_parse + g_variant_new + g_variant_new_va + g_variant_new_boolean + g_variant_new_byte + g_variant_new_int16 + g_variant_new_uint16 + g_variant_new_int32 + g_variant_new_uint32 + g_variant_new_int64 + g_variant_new_uint64 + g_variant_new_handle + g_variant_new_double + g_variant_new_string + g_variant_new_take_string + g_variant_new_printf + g_variant_new_signature + g_variant_new_object_path + g_variant_new_variant + g_variant_new_objv + g_variant_new_strv + g_variant_new_bytestring + g_variant_new_bytestring_array + g_variant_new_maybe + g_variant_new_array + g_variant_new_tuple + g_variant_new_dict_entry + g_variant_new_fixed_array + g_variant_new_from_data + g_variant_new_from_bytes + g_variant_builder_end + g_variant_new_parsed_va + g_variant_new_parsed + g_variant_byteswap + g_variant_get_child_value + g_variant_get_normal_form + g_variant_parse g_variant_ref g_variant_take_ref + g_variant_builder_add + g_variant_builder_add_value + g_variant_builder_add_parsed g_variant_ref_sink g_variant_unref - g_variant_iter_new + g_variant_iter_new g_variant_iter_free - g_variant_type_new - g_variant_type_copy - g_variant_type_new_array - g_variant_type_new_dict_entry - g_variant_type_new_maybe - g_variant_type_new_tuple + g_variant_type_new + g_variant_type_copy + g_variant_type_new_array + g_variant_type_new_dict_entry + g_variant_type_new_maybe + g_variant_type_new_tuple g_variant_type_free - g_allocator_new + g_allocator_new g_allocator_free - g_bookmark_file_new + g_bookmark_file_new g_bookmark_file_free - g_srv_target_new + g_srv_target_new g_srv_target_free - g_string_chunk_new + g_string_chunk_new g_string_chunk_free - g_test_log_buffer_new + g_test_log_buffer_new g_test_log_buffer_free - g_value_array_new + g_value_array_new g_value_array_free - g_cache_new + g_cache_new g_cache_destroy - g_cclosure_new - g_cclosure_new_swap - g_cclosure_new_object - g_cclosure_new_object_swap - g_closure_new_object - g_closure_new_simple + g_cclosure_new + g_cclosure_new_swap + g_cclosure_new_object + g_cclosure_new_object_swap + g_closure_new_object + g_closure_new_simple g_closure_ref g_closure_unref - g_array_new - g_array_sized_new + g_array_new + g_array_sized_new g_array_ref g_array_free g_array_unref - g_async_queue_new - g_async_queue_new_full + g_async_queue_new + g_async_queue_new_full g_async_queue_ref g_async_queue_unref - g_byte_array_new - g_byte_array_sized_new - g_byte_array_new_take - g_byte_array_sized_new - g_bytes_unref_to_array + g_byte_array_new + g_byte_array_sized_new + g_byte_array_new_take + g_byte_array_sized_new + g_bytes_unref_to_array g_byte_array_ref g_byte_array_free g_byte_array_unref - g_checksum_new - g_checksum_copy + g_checksum_new + g_checksum_copy g_checksum_free - g_main_loop_new - g_main_new + g_main_loop_new + g_main_new g_main_loop_ref g_main_loop_unref g_main_destroy - g_main_context_new + g_main_context_new g_main_context_ref g_main_context_unref g_main_destroy - g_thread_pool_new + g_thread_pool_new g_thread_pool_free - g_error_copy - g_error_new_valist - g_error_new_literal - g_error_new + g_error_copy + g_error_new_valist + g_error_new_literal + g_error_new g_error_free - g_string_new - g_string_new_len - g_string_sized_new - g_variant_print_string + g_string_new + g_string_new_len + g_string_sized_new + g_variant_print_string g_string_free - g_ptr_array_new - g_ptr_array_new_full - g_ptr_array_new_with_free_func + g_ptr_array_new + g_ptr_array_new_full + g_ptr_array_new_with_free_func g_ptr_array_ref g_ptr_array_free g_ptr_array_unref - g_pattern_spec_new + g_pattern_spec_new g_pattern_spec_free - g_key_file_new + g_key_file_new g_key_file_ref g_key_file_free g_key_file_unref - g_io_module_scope_new + g_io_module_scope_new g_io_module_scope_free - g_ascii_strdown - g_ascii_strup - g_base64_decode - g_base64_encode - g_bookmark_file_get_description - g_bookmark_file_get_mime_type - g_bookmark_file_get_title - g_bookmark_file_to_data - g_build_filename - g_build_filenamev - g_build_path - g_build_pathv - g_bytes_unref_to_data - g_compute_checksum_for_bytes - g_compute_checksum_for_data - g_compute_checksum_for_string - g_compute_hmac_for_data - g_compute_hmac_for_string - g_convert - g_convert_with_fallback - g_convert_with_iconv - g_credentials_to_string - g_date_time_format - g_filename_display_basename - g_filename_display_name - g_filename_from_uri - g_filename_to_uri - g_get_codeset - g_get_current_dir - g_get_locale_variants - g_key_file_get_start_group - g_key_file_to_data - g_malloc - g_realloc - g_malloc0 - g_malloc0_n - g_malloc_n - g_realloc_n - g_memdup - g_path_get_basename - g_path_get_dirname - g_slice_alloc - g_slice_alloc0 - g_slice_copy - g_strcompress - g_strconcat - g_strdup - g_strdup_printf - g_strdup_vprintf - g_strescape - g_strjoin - g_strjoinv - g_strndup - g_strnfill - g_time_val_to_iso8601 - g_try_malloc - g_try_realloc - g_try_malloc0 - g_try_malloc0_n - g_try_malloc_n - g_try_realloc_n - g_ucs4_to_utf16 - g_ucs4_to_utf8 - g_unicode_canonical_decomposition - g_utf16_to_ucs4 - g_utf16_to_utf8 - g_utf8_casefold - g_utf8_collate_key - g_utf8_collate_key_for_filename - g_utf8_normalize - g_utf8_strdown - g_utf8_strreverse - g_utf8_strup - g_utf8_substring - g_utf8_to_ucs4 - g_utf8_to_ucs4_fast - g_utf8_to_ucs4_fast - g_utf8_to_utf16 - g_key_file_get_locale_string - g_key_file_get_value - g_key_file_get_string - g_key_file_get_boolean_list - g_key_file_get_integer_list - g_key_file_get_double_list - g_key_file_get_comment - g_dbus_proxy_get_name_owner - g_file_info_get_attribute_as_string - g_file_attribute_matcher_to_string - g_app_launch_context_get_environment - g_app_launch_context_get_startup_notify_id - g_filename_completer_get_completion_suffix - g_inet_address_mask_to_string - g_variant_dup_string - g_variant_dup_bytestring - g_variant_get_objv - g_variant_get_strv - g_variant_print - g_datalist_id_dup_data - g_dir_make_tmp - g_filename_from_utf8 - g_filename_to_utf8 - g_file_read_link - g_find_program_in_path - g_format_size - g_format_size_for_display - g_format_size_full - g_hostname_to_ascii - g_hostname_to_unicode - g_locale_from_utf8 - g_locale_to_utf8 - g_markup_escape_text - g_markup_printf_escaped - g_markup_vprintf_escaped - g_match_info_expand_references - g_match_info_fetch - g_match_info_fetch_named - g_option_context_get_help - g_regex_escape_nul - g_regex_escape_string - g_regex_replace - g_regex_replace_eval - g_regex_replace_literal - g_shell_quote - g_shell_unquote - g_uri_escape_string - g_uri_parse_scheme - g_uri_unescape_segment - g_uri_unescape_string - g_variant_type_dup_string - g_value_dup_string + g_ascii_strdown + g_ascii_strup + g_base64_decode + g_base64_encode + g_bookmark_file_get_description + g_bookmark_file_get_mime_type + g_bookmark_file_get_title + g_bookmark_file_to_data + g_build_filename + g_build_filenamev + g_build_path + g_build_pathv + g_bytes_unref_to_data + g_compute_checksum_for_bytes + g_compute_checksum_for_data + g_compute_checksum_for_string + g_compute_hmac_for_data + g_compute_hmac_for_string + g_convert + g_convert_with_fallback + g_convert_with_iconv + g_credentials_to_string + g_date_time_format + g_filename_display_basename + g_filename_display_name + g_filename_from_uri + g_filename_to_uri + g_get_codeset + g_get_current_dir + g_get_locale_variants + g_key_file_get_start_group + g_key_file_to_data + g_malloc + g_realloc + g_malloc0 + g_malloc0_n + g_malloc_n + g_realloc_n + g_memdup + g_path_get_basename + g_path_get_dirname + g_slice_alloc + g_slice_alloc0 + g_slice_copy + g_strcompress + g_strconcat + g_strdup + g_strdup_printf + g_strdup_vprintf + g_strescape + g_strjoin + g_strjoinv + g_strndup + g_strnfill + g_time_val_to_iso8601 + g_try_malloc + g_try_realloc + g_try_malloc0 + g_try_malloc0_n + g_try_malloc_n + g_try_realloc_n + g_ucs4_to_utf16 + g_ucs4_to_utf8 + g_unicode_canonical_decomposition + g_utf16_to_ucs4 + g_utf16_to_utf8 + g_utf8_casefold + g_utf8_collate_key + g_utf8_collate_key_for_filename + g_utf8_normalize + g_utf8_strdown + g_utf8_strreverse + g_utf8_strup + g_utf8_substring + g_utf8_to_ucs4 + g_utf8_to_ucs4_fast + g_utf8_to_ucs4_fast + g_utf8_to_utf16 + g_key_file_get_locale_string + g_key_file_get_value + g_key_file_get_string + g_key_file_get_boolean_list + g_key_file_get_integer_list + g_key_file_get_double_list + g_key_file_get_comment + g_dbus_proxy_get_name_owner + g_file_info_get_attribute_as_string + g_file_attribute_matcher_to_string + g_app_launch_context_get_environment + g_app_launch_context_get_startup_notify_id + g_filename_completer_get_completion_suffix + g_inet_address_mask_to_string + g_variant_dup_string + g_variant_dup_bytestring + g_variant_get_objv + g_variant_get_strv + g_variant_print + g_datalist_id_dup_data + g_dir_make_tmp + g_filename_from_utf8 + g_filename_to_utf8 + g_file_read_link + g_find_program_in_path + g_format_size + g_format_size_for_display + g_format_size_full + g_hostname_to_ascii + g_hostname_to_unicode + g_locale_from_utf8 + g_locale_to_utf8 + g_markup_escape_text + g_markup_printf_escaped + g_markup_vprintf_escaped + g_match_info_expand_references + g_match_info_fetch + g_match_info_fetch_named + g_option_context_get_help + g_regex_escape_nul + g_regex_escape_string + g_regex_replace + g_regex_replace_eval + g_regex_replace_literal + g_shell_quote + g_shell_unquote + g_uri_escape_string + g_uri_parse_scheme + g_uri_unescape_segment + g_uri_unescape_string + g_variant_type_dup_string + g_value_dup_string g_register_data g_free - g_hash_table_new_full - g_hash_table_new + g_hash_table_new_full + g_hash_table_new g_hash_table_ref g_hash_table_destroy g_hash_table_unref - g_io_channel_unix_new - g_io_channel_win32_new_fd - g_io_channel_win32_new_socket - g_io_channel_win32_new_messages - g_io_channel_new_file + g_io_channel_unix_new + g_io_channel_win32_new_fd + g_io_channel_win32_new_socket + g_io_channel_win32_new_messages + g_io_channel_new_file g_io_channel_ref g_io_channel_close g_io_channel_shutdown g_io_channel_unref - g_emblemed_icon_get_emblems - g_list_alloc - g_list_copy - g_list_copy_deep - g_app_info_get_all - g_app_info_get_all_for_type - g_app_info_get_fallback_for_type - g_app_info_get_recommended_for_type - g_io_modules_load_all_in_directory - g_io_modules_load_all_in_directory_with_scope - g_hash_table_get_keys - g_hash_table_get_values + g_emblemed_icon_get_emblems + g_list_alloc + g_list_copy + g_list_copy_deep + g_app_info_get_all + g_app_info_get_all_for_type + g_app_info_get_fallback_for_type + g_app_info_get_recommended_for_type + g_io_modules_load_all_in_directory + g_io_modules_load_all_in_directory_with_scope + g_hash_table_get_keys + g_hash_table_get_values g_list_free g_list_free_1 g_list_free_full - g_regex_new + g_regex_new g_regex_ref g_regex_unref - g_node_new - g_node_copy - g_node_copy_deep + g_node_new + g_node_copy + g_node_copy_deep g_node_destroy - g_time_zone_new - g_time_zone_new_local - g_time_zone_new_utc + g_time_zone_new + g_time_zone_new_local + g_time_zone_new_utc g_time_zone_ref g_time_zone_unref - g_markup_parse_context_new + g_markup_parse_context_new g_markup_parse_context_free - g_mapped_file_new - g_mapped_file_new_from_fd + g_mapped_file_new + g_mapped_file_new_from_fd g_mapped_file_ref g_mapped_file_free g_mapped_file_unref - g_mutex_new + g_mutex_new g_mutex_free - g_mem_chunk_new + g_mem_chunk_new g_mem_chunk_free - g_option_group_new + g_option_group_new g_option_group_free - g_option_context_new + g_option_context_new g_option_context_free - g_rand_new - g_rand_copy - g_rand_new_with_seed - g_rand_new_with_seed_array + g_rand_new + g_rand_copy + g_rand_new_with_seed + g_rand_new_with_seed_array g_rand_free - g_queue_new - g_queue_copy + g_queue_new + g_queue_copy g_queue_free + g_queue_free_full - g_slice_new + g_slice_new g_slice_free g_slice_free1 - g_sequence_new + g_sequence_new g_sequence_free - g_completion_new + g_completion_new g_completion_free - g_chunk_new + g_chunk_new g_chunk_free - g_bytes_new - g_bytes_new_take - g_bytes_new_static - g_bytes_new_with_free_func - g_bytes_new_from_bytes - g_byte_array_free_to_bytes - g_memory_output_stream_steal_as_bytes - g_variant_get_data_as_bytes - g_mapped_file_get_bytes + g_bytes_new + g_bytes_new_take + g_bytes_new_static + g_bytes_new_with_free_func + g_bytes_new_from_bytes + g_byte_array_free_to_bytes + g_memory_output_stream_steal_as_bytes + g_variant_get_data_as_bytes + g_mapped_file_get_bytes g_bytes_ref g_bytes_unref - g_bookmark_file_get_uris - g_bookmark_file_get_groups - g_bookmark_file_get_applications - g_key_file_get_groups - g_key_file_get_keys - g_strdupv - g_strsplit - g_strsplit_set - g_uri_list_extract_uris - g_key_file_get_string_list - g_key_file_get_locale_string_list - g_file_info_list_attributes - g_file_info_get_attribute_stringv - g_app_launch_context_get_environment - g_filename_completer_get_completions - g_io_module_query - g_variant_dup_objv - g_variant_dup_bytestring_array - g_environ_setenv - g_environ_unsetenv - g_get_environ - g_listenv - g_match_info_fetch_all - g_regex_split - g_regex_split_full - g_regex_split_simple - g_regex_split_simple - g_variant_dup_strv + g_bookmark_file_get_uris + g_bookmark_file_get_groups + g_bookmark_file_get_applications + g_key_file_get_groups + g_key_file_get_keys + g_strdupv + g_strsplit + g_strsplit_set + g_uri_list_extract_uris + g_key_file_get_string_list + g_key_file_get_locale_string_list + g_file_info_list_attributes + g_file_info_get_attribute_stringv + g_app_launch_context_get_environment + g_filename_completer_get_completions + g_io_module_query + g_variant_dup_objv + g_variant_dup_bytestring_array + g_environ_setenv + g_environ_unsetenv + g_get_environ + g_listenv + g_match_info_fetch_all + g_regex_split + g_regex_split_full + g_regex_split_simple + g_regex_split_simple + g_variant_dup_strv g_strfreev - g_hmac_new - g_hmac_copy + g_hmac_new + g_hmac_copy g_hmac_ref g_hmac_unref - g_hook_alloc + g_hook_alloc g_hook_ref g_hook_unref g_hook_destroy g_hook_free - g_date_new - g_date_new_dmy - g_date_new_julian + g_date_new + g_date_new_dmy + g_date_new_julian g_date_free - g_variant_builder_new + g_variant_builder_new g_variant_builder_ref g_variant_builder_unref - g_cond_new + g_cond_new g_cond_free - g_app_launch_context_new - g_app_info_create_from_commandline - g_app_info_dup - g_app_info_get_default_for_type - g_app_info_get_default_for_uri_scheme - g_application_new - g_application_get_dbus_connection - g_application_get_default - g_buffered_input_stream_new - g_buffered_output_stream_new - g_cancellable_new - g_charset_converter_new - g_converter_input_stream_new - g_converter_output_stream_new - g_credentials_new - g_data_input_stream_new - g_data_output_stream_new - g_dbus_auth_observer_new - g_dbus_connection_new_finish - g_dbus_connection_new_sync - g_dbus_connection_new_for_address_finish - g_dbus_connection_new_for_address_sync - g_dbus_message_new - g_dbus_message_new_signal - g_dbus_message_new_method_call - g_dbus_message_new_method_reply - g_dbus_message_new_method_error - g_dbus_message_new_method_error_valist - g_dbus_message_new_method_error_literal - g_dbus_object_manager_client_new_finish - g_dbus_object_manager_client_new_sync - g_dbus_object_manager_client_new_for_bus_finish - g_dbus_object_manager_client_new_for_bus_sync - g_dbus_object_manager_server_new - g_dbus_object_manager_server_get_connection - g_dbus_object_proxy_new - g_dbus_object_skeleton_new - g_dbus_proxy_new_finish - g_dbus_proxy_new_sync - g_dbus_proxy_new_for_bus_finish - g_dbus_proxy_new_for_bus_sync - g_emblemed_icon_new - g_emblem_new - g_emblem_new_with_origin - g_file_icon_new - g_file_icon_get_file - g_file_info_new - g_file_info_dup - g_file_info_get_icon - g_file_info_get_symbolic_icon - g_file_info_get_attribute_object - g_file_info_get_deletion_date - g_filename_completer_new - g_inet_address_mask_new - g_inet_address_mask_new_from_string - g_inet_address_mask_get_address - g_inet_socket_address_new - g_inet_socket_address_get_address - g_initable_new - g_initable_new_valist - g_initable_newv - g_io_module_new - g_io_module_scope_new - g_keyfile_settings_backend_new - g_memory_input_stream_new - g_memory_input_stream_new_from_data - g_memory_input_stream_new_from_bytes - g_memory_output_stream_new - g_memory_output_stream_new_resizable - g_memory_settings_backend_new - g_null_settings_backend_new - g_menu_item_new - g_menu_item_new_section - g_menu_item_new_submenu - g_menu_item_new_from_model - g_menu_new - g_mount_operation_new - g_network_address_new - g_network_service_new - g_object_new - g_param_spec_pool_new - g_pollable_source_new - g_private_new - g_proxy_address_new - g_ptr_array_sized_new - g_relation_new - g_scanner_new - g_settings_new - g_signal_type_cclosure_new - g_simple_action_group_new - g_simple_action_new - g_simple_async_result_new - g_simple_permission_new - g_socket_client_new - g_socket_listener_new - g_socket_new - g_socket_service_new - g_tcp_wrapper_connection_new - g_test_dbus_new - g_themed_icon_new - g_threaded_socket_service_new - g_tls_client_connection_new - g_tls_file_database_new - g_tls_password_new - g_tls_server_connection_new - g_unix_signal_source_new - g_zlib_compressor_new - g_zlib_decompressor_new + g_app_launch_context_new + g_app_info_create_from_commandline + g_app_info_dup + g_app_info_get_default_for_type + g_app_info_get_default_for_uri_scheme + g_application_new + g_application_get_dbus_connection + g_application_get_default + g_buffered_input_stream_new + g_buffered_output_stream_new + g_cancellable_new + g_charset_converter_new + g_converter_input_stream_new + g_converter_output_stream_new + g_credentials_new + g_data_input_stream_new + g_data_output_stream_new + g_dbus_auth_observer_new + g_dbus_connection_new_finish + g_dbus_connection_new_sync + g_dbus_connection_new_for_address_finish + g_dbus_connection_new_for_address_sync + g_dbus_message_new + g_dbus_message_new_signal + g_dbus_message_new_method_call + g_dbus_message_new_method_reply + g_dbus_message_new_method_error + g_dbus_message_new_method_error_valist + g_dbus_message_new_method_error_literal + g_dbus_object_manager_client_new_finish + g_dbus_object_manager_client_new_sync + g_dbus_object_manager_client_new_for_bus_finish + g_dbus_object_manager_client_new_for_bus_sync + g_dbus_object_manager_server_new + g_dbus_object_manager_server_get_connection + g_dbus_object_proxy_new + g_dbus_object_skeleton_new + g_dbus_proxy_new_finish + g_dbus_proxy_new_sync + g_dbus_proxy_new_for_bus_finish + g_dbus_proxy_new_for_bus_sync + g_emblemed_icon_new + g_emblem_new + g_emblem_new_with_origin + g_file_icon_new + g_file_icon_get_file + g_file_info_new + g_file_info_dup + g_file_info_get_icon + g_file_info_get_symbolic_icon + g_file_info_get_attribute_object + g_file_info_get_deletion_date + g_filename_completer_new + g_inet_address_mask_new + g_inet_address_mask_new_from_string + g_inet_address_mask_get_address + g_inet_socket_address_new + g_inet_socket_address_get_address + g_initable_new + g_initable_new_valist + g_initable_newv + g_io_module_new + g_io_module_scope_new + g_keyfile_settings_backend_new + g_memory_input_stream_new + g_memory_input_stream_new_from_data + g_memory_input_stream_new_from_bytes + g_memory_output_stream_new + g_memory_output_stream_new_resizable + g_memory_settings_backend_new + g_null_settings_backend_new + g_menu_item_new + g_menu_item_new_section + g_menu_item_new_submenu + g_menu_item_new_from_model + g_menu_new + g_mount_operation_new + g_network_address_new + g_network_service_new + g_object_new + g_param_spec_pool_new + g_pollable_source_new + g_private_new + g_proxy_address_new + g_ptr_array_sized_new + g_relation_new + g_scanner_new + g_settings_new + g_signal_type_cclosure_new + g_simple_action_group_new + g_simple_action_new + g_simple_async_result_new + g_simple_permission_new + g_socket_client_new + g_socket_listener_new + g_socket_new + g_socket_service_new + g_tcp_wrapper_connection_new + g_test_dbus_new + g_themed_icon_new + g_threaded_socket_service_new + g_tls_client_connection_new + g_tls_file_database_new + g_tls_password_new + g_tls_server_connection_new + g_unix_signal_source_new + g_zlib_compressor_new + g_zlib_decompressor_new g_object_ref g_object_unref gtk_widget_destroy - g_tree_new - g_tree_new_full - g_tree_new_with_data + g_tree_new + g_tree_new_full + g_tree_new_with_data g_tree_ref g_tree_unref + g_tree_destroy - g_file_attribute_matcher_new - g_file_attribute_matcher_subtract + g_file_attribute_matcher_new + g_file_attribute_matcher_subtract g_file_attribute_matcher_ref g_file_attribute_matcher_unref @@ -896,31 +936,39 @@ false + + - false + + - + + + false + + + false @@ -930,18 +978,17 @@ - + - + false - @@ -950,7 +997,6 @@ - @@ -959,7 +1005,6 @@ - @@ -970,23 +1015,80 @@ - + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + false + + + + + + + + false @@ -1000,26 +1102,77 @@ false + false + + + + + + + + - + + + false + + + + + + + + + - + + + false + + + + + + + + + false + + + + + + + + + + + + + + false - - - false - - - false + + + + + + + + + + + + false @@ -1036,20 +1189,31 @@ false + false + + + false + + + + + + + false + - @@ -1057,35 +1221,87 @@ false - + false - - + + + + + + false - + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + @@ -1095,7 +1311,9 @@ - + + + false + + + + false - + @@ -1204,197 +1424,623 @@ + false + + + + + + + + + + + + 0: + + false + + + + + + + false + + + + + + + + + 0: + + + + + + + + 0: + + false + + + + + + + + + + + + 0: + - - - false - - - - false - - + + + false + + + + + + + + + 0: + + + + + + false + + + + + + + + + 0: + + + + + 0: + + false + + + + + + + + + false + + + + + + + + 0: + + false + + + + + + + + + false + + + + + + + + + + - - - false - + false + + + + + + + + + + + + + 0: + + false + + + + + + + + + + + + + 0: + - - - false - - + + + false + + + + + + + + + 0: + + false + + + + + + + + + 0: + + + + + 0: + + false + + + + + + + + 0: + + false + + + + + + + + + false + + + + + + + + + + + false + + + + + + + false + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + 0: + + + + + + + + + + + + false + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + 0: + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + + false + + + + + + + + + false + + + + + + - false + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + + - - - false - - + + + false + + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + - + + + false + + + + + + + + - + + + false + + + + + + false - - - - false - - - - false + + + + + + @@ -1444,21 +2090,40 @@ false + false + + + + + + - - - false - - + + + + + + + false + + false + + + + + + + + @@ -1467,99 +2132,202 @@ - + false + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + - - - false - + false + + + + + + + + + + - - - false - - + + false + + + + + + + + + false - - + + + false + + + + + + + + + 0: + + false + + + + + + + + + 0: + - - - false - + false + + + + + + + + - - - false - - + + + false + + + + + + + + + false + + + + + + + + false + + + + + false + + + + + + + + false + + + + + + + + + + - - - false - - - - false - - + + + + false + + @@ -1569,73 +2337,215 @@ false + false + + + + + + + + + + + - - - false - - - - false - - + + + false + + + + + + + + - + + + false + + + + + + + + + 0: + + false + + + + + + + + + 0: + + + + + 0: + + false + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + - - - false - + false + + + + + + + + + + + + + + + + + + false + + + + + + + + + false + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + @@ -1645,8 +2555,12 @@ - - + + + + + + @@ -1673,6 +2587,7 @@ + false @@ -1681,41 +2596,110 @@ + false + + + + + + + + + 0: + + false + + + + + + + + + 0: + - - - false - - + + false + + + + + + + + - + + + false + + + + + + + + + false + + + + + + + + false + + + + + false + + + + + + + + false + + + + + + + + + + @@ -1761,33 +2745,20 @@ false - - - false - - - - false - - - - false - - - - false - - - - false - + false + + + + + false + @@ -2126,31 +3097,52 @@ - - - false - - - - false - - + + + + false + + + + + + + + false + + + + + + + - - - false - + false + + + + + + + + + + + + + + - + false @@ -2163,14 +3155,6 @@ false - - - false - - - - false - false @@ -2188,9 +3172,31 @@ false + false + + + + + + + + + + + + + + + + + + + + + @@ -2345,11 +3351,13 @@ + + @@ -2359,6 +3367,7 @@ + @@ -2374,9 +3383,11 @@ + + @@ -2507,21 +3518,47 @@ false + false + + + + + + + + + + false + + + + + + + + + false + false + + + + + @@ -2530,10 +3567,21 @@ false + + + + + + false + + + + + @@ -2628,10 +3676,6 @@ false - - - false - false @@ -2640,151 +3684,130 @@ false - - - false - + false + + + + + + + + + + + + false - - - - false - - + + + + + + + + + + + + + + - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - + + false + + + + - + + false + + + + + + + + + - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false @@ -2806,13 +3829,28 @@ + false + + + + + + + + + false + + + + + @@ -2872,21 +3910,85 @@ false + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + false + + + + false + + + + false @@ -2929,29 +4031,29 @@ false - - - false - false - - - false - - + + + false + + false - + + + false + + @@ -3010,50 +4112,6 @@ - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - false @@ -3066,17 +4124,45 @@ false + false + + + + + + + + false + + + + + + + + + + + + + + + false + + + + @@ -3102,13 +4188,54 @@ false + false + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + @@ -3118,10 +4245,6 @@ false - - - false - false @@ -3677,29 +4800,9 @@ - - - - - - - false - - - - false - - - - false - - - - false - - - - false + + + @@ -3733,9 +4836,19 @@ false + false + + + + + + + + + @@ -3767,18 +4880,6 @@ 0: - - - false - - - - false - - - - false - false @@ -3791,30 +4892,6 @@ false - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - false @@ -3919,7 +4996,7 @@ false - + false @@ -4021,6 +5098,7 @@ + false @@ -4034,13 +5112,23 @@ - - - false - - + + + false + + + + + + + + + + + + @@ -4094,6 +5182,7 @@ + false @@ -4217,17 +5306,53 @@ 0: + false + + + + + + + false + + + + + + + + + + + - + + + false + + + + + + + + + + + + + + + @@ -4251,10 +5376,6 @@ - - - false - false @@ -4267,9 +5388,17 @@ false + false + + + + + + + @@ -4407,65 +5536,47 @@ false - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - + + + false + + + + + + + + + + + + - + + false + + + + + + + + + + + + + + + + + + + @@ -4667,224 +5778,243 @@ false - - - false - - - - false - - - - false - - - - false - - - - false - - - - - false - - - - - - - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - + false - + false - + false - + false - + false - + + false + + + + + + - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + false - + + + false + + + + + + - + + + false + + + + + - + + + + + false + + + + + + - - + + + false + + + + + + + + + - - + + + false + + + + + + + + + + + + + + + - - + + + false + + + + + - + + + false + + + + + + + + + + + - + false + g_async_queue_timed_pop_unlocked is deprecated and should not be used in newly-written code.use g_async_queue_timeout_pop_unlocked(). - + + + false + + + + + + + + 0: + false + g_async_queue_unref_and_unlock has been deprecated since version 2.8 and should not be used in newly-written code. Reference counting is done atomically. so g_async_queue_unref() can be used regardless of the queues lock. @@ -5018,25 +6148,70 @@ + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + false + + + + + + + false + + + + + + @@ -5210,65 +6385,57 @@ false + false + + + + + + + + + + - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - + + + + + + + + + + + + + false + + + + + + false + false - - - - false - - - - false - - - - false + + + + + + @@ -5282,9 +6449,16 @@ false + false + + + + + + @@ -6098,129 +7272,344 @@ false - + + + + false + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + - + + false + + + + + + + + + + + - - + + false + + - - + + false + + + + + + - - + + false + + + + + + - false + + + + + + + + + false + + + + + + + false + + + + + + + + + + false + + + + + - - - false - - + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - - - false - - + + + + + false + + + + + + - + + + + + false + + + + + - + + + false + + + + + + + + + + 0: + - + + + false + + + + + + + + + 0: + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + false + + + + + + + + + + + + false + + + + + + + + + @@ -6954,53 +8343,158 @@ false + + + false + + + + + + + + - false + + + + + false + + + + + + + + + + + - + + + + + false + + + - + + + + + + false + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + - - - false - - - - false - - + + + false + + + + + + + + + false + + + + + + + + + + + - + + + false + + + + + + + + + false + g_tree_traverse has been deprecated since version 2.2 and should not be used in newly-written code. The order of a balanced tree is somewhat arbitrary. If you just want to visit all nodes in sorted order, use g_tree_foreach() instead. If you really need to visit nodes in a different order, consider using an n-ary tree. @@ -7210,29 +8704,91 @@ false + - false + + + + + + + + + + + + - - + + false + + + + + + + + - - + + false + + + + + + + + + + + + - - + + + false + + + + + - false + + + + + + + + + - false + + + + + + + + + + + + false + + + + + @@ -7330,6 +8886,174 @@ false + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + + @@ -20442,7 +22166,7 @@ - + @@ -20454,6 +22178,17 @@ + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cfg/icu.cfg b/cfg/icu.cfg index 9932716f2d1..5e1f9163fd0 100644 --- a/cfg/icu.cfg +++ b/cfg/icu.cfg @@ -1,6 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cfg/kde.cfg b/cfg/kde.cfg index 5973916fd60..1131d5e0c50 100644 --- a/cfg/kde.cfg +++ b/cfg/kde.cfg @@ -20,6 +20,11 @@ + + + + + @@ -48,4 +53,40 @@ + + + + false + + + + + + + + false + + + + + + + + + false + + + + + + + + + false + + + + + + diff --git a/cfg/libcerror.cfg b/cfg/libcerror.cfg index 0bdd0874eb8..ce621e99d44 100644 --- a/cfg/libcerror.cfg +++ b/cfg/libcerror.cfg @@ -125,4 +125,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cfg/microsoft_sal.cfg b/cfg/microsoft_sal.cfg index 3cdb8299cd4..36371a3610b 100644 --- a/cfg/microsoft_sal.cfg +++ b/cfg/microsoft_sal.cfg @@ -338,7 +338,6 @@ - diff --git a/cfg/opencv2.cfg b/cfg/opencv2.cfg index 797035c1e57..80b51ad7a08 100644 --- a/cfg/opencv2.cfg +++ b/cfg/opencv2.cfg @@ -69,7 +69,7 @@ false - + diff --git a/cfg/opengl.cfg b/cfg/opengl.cfg index 72dcaddb961..ec37abf5516 100644 --- a/cfg/opengl.cfg +++ b/cfg/opengl.cfg @@ -211,6 +211,7 @@ + false diff --git a/cfg/posix.cfg b/cfg/posix.cfg index f07f8fe8b44..751142bacc1 100644 --- a/cfg/posix.cfg +++ b/cfg/posix.cfg @@ -511,6 +511,13 @@ + + + + false + + + @@ -1942,6 +1949,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s + -20:19 @@ -2197,7 +2205,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + @@ -2209,7 +2217,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + @@ -2221,7 +2229,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + @@ -3362,7 +3370,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s false - + @@ -4054,6 +4062,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s false + @@ -4086,7 +4095,6 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - Non reentrant function 'readdir' called. For threadsafe applications it is recommended to use the reentrant replacement function 'readdir_r'. @@ -4178,6 +4186,30 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s 0: + + + + + false + + + + + + + + + + + + + + 0: + + + + + @@ -5212,7 +5244,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s - + @@ -5234,7 +5266,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s 0:255 - + @@ -5606,7 +5638,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s false - + @@ -6267,6 +6299,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s openat socket close + fdopen opendir diff --git a/cfg/protobuf.cfg b/cfg/protobuf.cfg new file mode 100644 index 00000000000..8ff5570c952 --- /dev/null +++ b/cfg/protobuf.cfg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/cfg/qt.cfg b/cfg/qt.cfg index 13d96ecb611..00cb66c1909 100644 --- a/cfg/qt.cfg +++ b/cfg/qt.cfg @@ -59,10 +59,11 @@ invokeMethod - - + + + false @@ -72,6 +73,7 @@ + false @@ -100,6 +102,7 @@ + false @@ -131,6 +134,7 @@ + false @@ -146,6 +150,7 @@ + false @@ -176,6 +181,7 @@ + false @@ -188,6 +194,7 @@ + false @@ -200,6 +207,7 @@ + false @@ -266,6 +274,7 @@ + false @@ -277,6 +286,7 @@ + false @@ -381,9 +391,9 @@ - + false - + @@ -444,11 +454,12 @@ + false - + @@ -747,6 +758,19 @@ + + + + + + + + false + + + + + false @@ -765,7 +789,7 @@ false - + @@ -954,6 +978,25 @@ + + + + + false + + + + + + + + + + false + + + + @@ -1371,13 +1414,6 @@ - - - false - - - - @@ -1418,6 +1454,30 @@ + + + false + + + + + + + + + + false + + + + + + + false + + + + false @@ -1553,7 +1613,7 @@ false - + @@ -1577,7 +1637,7 @@ false - + @@ -1595,7 +1655,7 @@ false - + @@ -1658,7 +1718,7 @@ false - + @@ -2279,7 +2339,7 @@ - + false @@ -2297,7 +2357,7 @@ - + false @@ -2548,7 +2608,7 @@ false - + @@ -2677,6 +2737,7 @@ + @@ -2733,6 +2794,14 @@ + + + + false + + + + false @@ -2764,6 +2833,156 @@ + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + @@ -3075,7 +3294,7 @@ - + @@ -3086,7 +3305,7 @@ - + @@ -3102,7 +3321,7 @@ false - + @@ -3110,10 +3329,10 @@ false - + - + @@ -3150,10 +3369,10 @@ false - + - + @@ -3163,13 +3382,13 @@ false - + - + false @@ -3193,7 +3412,7 @@ - + false @@ -3246,7 +3465,7 @@ - + false @@ -3801,7 +4020,7 @@ - + false @@ -3976,7 +4195,7 @@ false - + @@ -3998,7 +4217,7 @@ - + @@ -4020,14 +4239,14 @@ - + false - + @@ -4042,7 +4261,7 @@ - + @@ -4055,13 +4274,13 @@ false - + - + @@ -4072,7 +4291,7 @@ - + @@ -4086,7 +4305,7 @@ false - + @@ -4108,7 +4327,7 @@ false - + @@ -4128,7 +4347,7 @@ 0: - + @@ -4167,7 +4386,7 @@ - + @@ -4228,7 +4447,7 @@ false - + @@ -4239,7 +4458,7 @@ - + @@ -4250,7 +4469,7 @@ - + @@ -4279,7 +4498,7 @@ - + @@ -4990,6 +5209,23 @@ + + + + + + + + + + + + + + + + + @@ -5024,24 +5260,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + QApplication - QMutexLocker + QMutexLocker + QRect + QRectF + QSize + QSizeF + QPoint + QPointF + QRegion + QTransform - QMutex - QRecursiveMutex - QSemaphore - QReadWriteLock + QMutex + QRecursiveMutex + QSemaphore + QReadWriteLock - @@ -5052,6 +5327,8 @@ + + @@ -5061,13 +5338,18 @@ - + + + + + - + + @@ -5080,22 +5362,36 @@ - + - + + + + + + + + + + + + + + + @@ -5129,12 +5425,40 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cfg/selinux.cfg b/cfg/selinux.cfg new file mode 100644 index 00000000000..e2d7ac34dc3 --- /dev/null +++ b/cfg/selinux.cfg @@ -0,0 +1,3621 @@ + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + get_default_type + free + + + + + + + + false + + + + + + 0:5 + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + selabel_open + selabel_close + + + + + + false + + + + + + + + + + + + + + + + + + + + + selabel_lookup + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + selabel_lookup_raw + freecon + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + selabel_get_digests_all_partial_matches + free + + + selabel_get_digests_all_partial_matches + free + + + + + false + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + selabel_lookup_best_match + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + selabel_lookup_best_match_raw + freecon + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + context_new + context_free + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + get_ordered_context_list + freeconary + + + + + false + + + + + + + + + + + + + + + + + + + + + get_ordered_context_list_with_level + freeconary + + + + + false + + + + + + + + + + + + + + + + + get_default_context + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + get_default_context_with_level + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + get_default_context_with_role + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + get_default_context_with_rolelevel + freecon + + + + + false + + + + + + + + + + + + query_user_context + freecon + + + + + false + + + + + + + + + + + + + manual_user_enter_context + freecon + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + avc_sid_to_context + freecon + + + + + false + + + + + + + + + + + + avc_sid_to_context + freecon + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + false + + + + + + + false + + + + + 0,1 + + + + + + false + + + + + + false + + + + + + false + + + + + + + false + + + + + + false + + + + + + + + false + + + + + 0,1 + + + + + false + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + getcon + freecon + + + + + false + + + + + + + + getcon_raw + freecon + + + + + false + + + + + + + + getprevcon + freecon + + + + + false + + + + + + + + getprevcon_raw + freecon + + + + + false + + + + + + + + getexeccon + freecon + + + + + false + + + + + + + + getexeccon_raw + freecon + + + + + false + + + + + + + + + + + + getpidcon + freecon + + + + + false + + + + + + + + + + + + getpidcon_raw + freecon + + + + + false + + + + + + + + + + + + getpidprevcon + freecon + + + + + false + + + + + + + + + + + + getpidprevcon_raw + freecon + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + getfscreatecon + freecon + + + + + false + + + + + + + + getfscreatecon_raw + freecon + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + getkeycreatecon + freecon + + + + + false + + + + + + + + getkeycreatecon_raw + freecon + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + getsockcreatecon + freecon + + + + + false + + + + + + + + getsockcreatecon_raw + freecon + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + 0: + + + + + + + getpeercon + freecon + + + + + false + + + + + + 0: + + + + + + + getpeercon_raw + freecon + + + + + + false + + + + + + + + + + + + + getfilecon + freecon + + + + + false + + + + + + + + + + + + + getfilecon_raw + freecon + + + + + false + + + + + + + + + + + + + lgetfilecon + freecon + + + + + false + + + + + + + + + + + + + lgetfilecon_raw + freecon + + + + + false + + + + + + 0: + + + + + + + fgetfilecon + freecon + + + + + false + + + + + + 0: + + + + + + + fgetfilecon_raw + freecon + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + 0: + + + + + + + + + + + false + + + + + 0: + + + + + + + + + + + false + + + + + + 0:4 + + + + + + false + + + + + 0:4 + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + security_compute_create + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + security_compute_create_raw + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + security_compute_create_name + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + security_compute_create_name_raw + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + security_compute_relabel + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + security_compute_relabel + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + security_compute_member + freecon + + + + + false + + + + + + + + + + + + + + + + + + + + + + security_compute_member_raw + freecon + + + + + false + + + + + + + + + + + + + + + + + + security_compute_user + freeconary + + + + + false + + + + + + + + + + + + + + + + + + security_compute_user_raw + freeconary + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + security_get_initial_context + freecon + + + + + false + + + + + + + + + + + + + security_get_initial_context_raw + freecon + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + 0,1 + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + 0 + + + + + + false + + + + + + + + + + + security_get_boolean_names + free + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + 0,1 + + + + + + false + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + security_canonicalize_context + freecon + + + + + false + + + + + + + + + + + + + security_canonicalize_context + freecon + + + + + + false + + + + + + + false + + + + + 0,1 + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + Disabling SELinux at runtime is deprecated and may not be supported on modern Linux kernels. + + + + + + false + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + security_av_string + free + + + + + false + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + 0:7 + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + matchpathcon + freecon + + + + + false + + + + + + + + + + + + + + + + + matchpathcon_index + freecon + + + + + + false + + + + + + + + + + + + + + + + + + + + false + + + + + + false + + + + + + false + + + + + + + + + + false + + + + + + + + + + + + + matchmediacon + freecon + + + + + + false + + + + + + + + + + + false + + + + + + + + + + selinux_boolean_sub + free + + + + + + false + + + + + + + + selinux_getpolicytype + free + + + + + + false + + + + + + + false + + + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + false + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + + + selinux_raw_context_to_color + free + + + + + false + + + + + + + + + + + + + selinux_trans_to_raw_context + free + + + + + false + + + + + + + + + + + + + selinux_raw_to_trans_context + free + + + + + + false + + + + + + + + + + + + + + + + getseuserbyname + free + + + getseuserbyname + free + + + + + false + + + + + + + + + + + + + + + + + + + + getseuser + free + + + getseuser + free + + + + + + false + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + false + + This function is not thread safe. Be very sure that no other threads are calling into libselinux when this is called. + + diff --git a/cfg/sqlite3.cfg b/cfg/sqlite3.cfg index 0b0a439b18c..6c5811f1f75 100644 --- a/cfg/sqlite3.cfg +++ b/cfg/sqlite3.cfg @@ -966,6 +966,7 @@ + false @@ -988,6 +989,7 @@ + false @@ -1025,6 +1027,48 @@ + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + - + - - - + + + - + @@ -36,6 +37,7 @@ + @@ -52,12 +54,27 @@ + + + + + + - + + + true + + + + + true + + @@ -729,6 +746,7 @@ + @@ -738,8 +756,11 @@ + + !0.0: + @@ -749,8 +770,11 @@ + + !0.0: + @@ -760,6 +784,8 @@ + + !0.0: @@ -948,7 +974,7 @@ - + false @@ -1254,6 +1280,8 @@ + + @@ -1584,7 +1612,7 @@ false - + @@ -1595,7 +1623,7 @@ false - + @@ -2290,7 +2318,7 @@ false - + @@ -3027,6 +3055,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + @@ -3036,8 +3065,11 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + !0.0: + @@ -3047,8 +3079,11 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + !0.0: + @@ -3058,6 +3093,8 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + !0.0: @@ -3146,7 +3183,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false @@ -3281,11 +3318,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - - - - - + @@ -3296,8 +3329,23 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + + + + + false + + + + + + - + arg1>arg2?1:0 @@ -3310,8 +3358,22 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + arg1>arg2?1:0 + false + + + + + + + + - + arg1 >= arg2?1:0 @@ -3324,12 +3386,22 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + arg1 >= arg2?1:0 + false + + + + + + + + - - - - - + @@ -3340,6 +3412,21 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + + + + + false + + + + + + @@ -3815,7 +3902,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -3838,7 +3925,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -3921,12 +4008,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0: - + false - + @@ -4066,8 +4153,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - - + false @@ -4279,57 +4365,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun !0.0 - - - - - - false - - - - - - - - - - - - - - - - - false - - - - - - - - - - - - - - - - - false - - - - - - - - - - - @@ -4445,7 +4480,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0: - + @@ -4546,23 +4581,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0: - - - - - false - - - - - - 0: - - - - 0: - - @@ -4802,6 +4820,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + @@ -4837,6 +4856,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + false @@ -4851,7 +4871,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0:255 - + @@ -4936,8 +4956,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - - + false @@ -5011,6 +5030,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + @@ -5096,6 +5116,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + @@ -5107,7 +5128,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -5148,11 +5169,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + false - + @@ -5170,7 +5192,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -5211,6 +5233,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + @@ -5353,7 +5376,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -5405,6 +5428,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + false @@ -5426,7 +5450,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -5646,8 +5670,16 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false + + + + + + false + + arg1 < 'A' || arg1 > 'Z' ? arg1 : arg1 + 32 false @@ -6310,8 +6342,59 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + false + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + false + + + arg1<arg2?arg2:arg1>arg3?arg3:arg1 + + + + + + + + + + + + + - + false @@ -6325,7 +6408,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false @@ -6362,6 +6445,38 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + + @@ -6410,45 +6525,29 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun std::istream& std::istream::get (char* s, streamsize n, char delim); stream buffer (3) std::istream& std::istream::get (streambuf& sb); std::istream& std::istream::get (streambuf& sb, char delim);--> - - - + false - - - - - - false - - - - - - false - - + + + + + + + + 0: + + - - - - + + false - - - - @@ -6486,39 +6585,107 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + - + false + + + + + + false + - + false - + false - + false - + + + + + false + + + @@ -6554,6 +6721,31 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0: + + + + + + false + + + + + + + + @@ -6593,7 +6785,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + @@ -6613,10 +6805,10 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false - + @@ -6642,22 +6834,21 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + - + false - + - false @@ -6678,14 +6869,21 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + - + + false + + + + + + false @@ -6764,7 +6962,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + arg1 @@ -6783,10 +6981,10 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false - + false @@ -6859,7 +7057,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + false @@ -6881,6 +7079,18 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + + + + + false + + + + + + + @@ -6955,6 +7165,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + false @@ -6968,6 +7179,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + false @@ -6981,6 +7193,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun + false @@ -6992,8 +7205,14 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun 0: + + + + + false + - + false @@ -7073,24 +7292,6 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - - - - false - - - - - - - - - 0: - - - - - @@ -7319,7 +7520,8 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + + false @@ -7461,15 +7663,15 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false - + - + - + @@ -7510,6 +7712,23 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + + false + + + + + + + + + + + + @@ -8010,6 +8229,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + false @@ -8018,7 +8238,6 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - false @@ -8052,6 +8271,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + false @@ -8076,6 +8296,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false + @@ -8090,6 +8311,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false + @@ -8098,6 +8320,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + false @@ -8158,17 +8381,14 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - - - - - + + + false - + - 0: @@ -8260,7 +8480,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false - + @@ -8271,13 +8491,13 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false - + - + false @@ -8475,7 +8695,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + @@ -8530,37 +8750,69 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init false - false - + - false - + + + false + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + - malloc - calloc - aligned_alloc - realloc - reallocarray - free + malloc,std::malloc + calloc,std::calloc + aligned_alloc,std::aligned_alloc + realloc,std::realloc + free,std::free - strdup - free + strdup,std::strdup + free,std::free - fopen - tmpfile - freopen - fclose + fopen,std::fopen + tmpfile,std::tmpfile + freopen,std::freopen + fclose,std::fclose @@ -8632,7 +8884,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + @@ -8641,7 +8893,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + @@ -8667,7 +8919,6 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - @@ -8690,6 +8941,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + @@ -8724,7 +8976,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - + @@ -8736,12 +8988,12 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init - - - - - - + + + + + + @@ -8757,6 +9009,16 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + + + + + + + + + + @@ -8789,6 +9051,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init std::unique_lock std::shared_lock std::pair + std::complex std::exception std::logic_error std::domain_error @@ -8802,8 +9065,10 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init std::underflow_error std::regex_error std::system_error + std::format_error std::bad_typeid std::bad_cast + std::monostate std::bad_optional_access std::bad_expected_access std::bad_weak_ptr @@ -8815,6 +9080,12 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init std::filesystem::filesystem_error std::bad_variant_access std::span + std::stringstream + std::wstringstream + std::istringstream + std::wistringstream + std::ostringstream + std::wostringstream std::mutex @@ -8923,7 +9194,7 @@ initializer list (7) string& replace (const_iterator i1, const_iterator i2, init + Values are in alignment with posix.cfg --> diff --git a/cfg/tinyxml2.cfg b/cfg/tinyxml2.cfg index 2fdee227bc6..e652fa9c11d 100644 --- a/cfg/tinyxml2.cfg +++ b/cfg/tinyxml2.cfg @@ -1,24 +1,5 @@ - - - - - - - - - - - - - - - - - - - diff --git a/cfg/windows.cfg b/cfg/windows.cfg index 8b4b19d6a71..343e12b3906 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -1411,6 +1411,53 @@ + + + false + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + @@ -1749,7 +1796,7 @@ false - + @@ -1877,6 +1924,26 @@ + + + + + + + + false + + + + + + + + + + + + false @@ -2176,7 +2243,7 @@ false - + @@ -2225,10 +2292,11 @@ - - - - + + + + + false @@ -2243,20 +2311,53 @@ - + + + + + false + + + + + + + + + + + + - - - - - + + + false + + + + + + + + + + + + + + + + + + false + It is recommend you use _stricmp instead. @@ -2328,7 +2429,7 @@ implemented in Cppcheck. It can not (yet) be configured in the configuration file. See #8381 --> - false @@ -2378,7 +2479,7 @@ - false @@ -2480,7 +2581,7 @@ HFONT CreateFont( - @@ -2506,7 +2607,7 @@ HFONT CreateFont( - false @@ -2533,7 +2634,7 @@ HFONT CreateFont( - false @@ -2550,18 +2651,6 @@ HFONT CreateFont( - - - false - - - These POSIX functions are deprecated. Use the ISO C++ conformant _strdup, _wcsdup, _mbsdup instead. - - - - - - false @@ -2585,7 +2674,7 @@ HFONT CreateFont( - false @@ -2642,7 +2731,7 @@ HFONT CreateFont( - false @@ -2762,8 +2851,8 @@ HFONT CreateFont( 0:2 - false @@ -2960,7 +3049,7 @@ HFONT CreateFont( - + @@ -2985,7 +3074,7 @@ HFONT CreateFont( - + @@ -3023,7 +3112,7 @@ HFONT CreateFont( _In_ LPARAM lParam); --> false - + @@ -3044,7 +3133,7 @@ HFONT CreateFont( _In_ LPARAM lParam); --> false - + @@ -3306,7 +3395,7 @@ HFONT CreateFont( false - + @@ -3315,10 +3404,10 @@ HFONT CreateFont( false - + - + @@ -3327,7 +3416,7 @@ HFONT CreateFont( false - + @@ -3339,32 +3428,12 @@ HFONT CreateFont( false - - - - - - - - - - - - - - - - false - - + - - - @@ -3432,7 +3501,7 @@ HFONT CreateFont( - + @@ -3487,7 +3556,7 @@ HFONT CreateFont( - + @@ -3501,7 +3570,7 @@ HFONT CreateFont( false - + @@ -3609,7 +3678,7 @@ HFONT CreateFont( - false @@ -3699,7 +3768,7 @@ HFONT CreateFont( false - + @@ -3715,7 +3784,7 @@ HFONT CreateFont( - false @@ -3746,7 +3815,7 @@ HFONT CreateFont( false - + @@ -3901,7 +3970,7 @@ HFONT CreateFont( - + @@ -4331,8 +4400,8 @@ HFONT CreateFont( - @@ -4365,8 +4434,8 @@ HFONT CreateFont( - @@ -4613,6 +4682,108 @@ HFONT CreateFont( + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + @@ -4726,7 +4897,7 @@ HFONT CreateFont( - + @@ -4772,7 +4943,7 @@ HFONT CreateFont( false - + @@ -4791,7 +4962,7 @@ HFONT CreateFont( - true + false @@ -4800,13 +4971,33 @@ HFONT CreateFont( + + + + + false + + + + + + + + + + + true - + @@ -4821,11 +5012,11 @@ HFONT CreateFont( false - + - + @@ -4884,7 +5075,7 @@ HFONT CreateFont( - + @@ -4941,6 +5132,8 @@ HFONT CreateFont( + + false @@ -5646,7 +5850,7 @@ HFONT CreateFont( - + @@ -6324,7 +6528,7 @@ HFONT CreateFont( false - + @@ -6627,12 +6831,27 @@ HFONT CreateFont( - + + + false + + + This function is obsolete. The ControlTrace function supersedes this function. + + + + + + + + + @@ -6791,7 +7010,7 @@ HFONT CreateFont( - + @@ -6887,25 +7106,6 @@ HFONT CreateFont( - - - - - - - - - - - - - - - - false - - - false @@ -6990,16 +7190,8 @@ HFONT CreateFont( - - - - - - - - - - + + @@ -7010,6 +7202,10 @@ HFONT CreateFont( + + + + @@ -7685,11 +7881,6 @@ HFONT CreateFont( - - - - - @@ -7788,15 +7979,6 @@ HFONT CreateFont( - - - - - - - - - @@ -8634,9 +8816,6 @@ HFONT CreateFont( - - - @@ -12458,7 +12637,6 @@ HFONT CreateFont( - @@ -13051,6 +13229,7 @@ HFONT CreateFont( + @@ -13852,10 +14031,6 @@ HFONT CreateFont( - - - - @@ -14078,6 +14253,10 @@ HFONT CreateFont( + + + + @@ -14463,57 +14642,6 @@ HFONT CreateFont( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -14521,132 +14649,10 @@ HFONT CreateFont( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -14706,147 +14712,6 @@ HFONT CreateFont( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -16985,743 +16850,7 @@ HFONT CreateFont( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -17938,6 +17067,160 @@ HFONT CreateFont( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cfg/wxwidgets.cfg b/cfg/wxwidgets.cfg index 6d4051933aa..c1370373b54 100644 --- a/cfg/wxwidgets.cfg +++ b/cfg/wxwidgets.cfg @@ -1,5 +1,116 @@ + + + wxAcceleratorEntry + wxAny + wxArchiveIterator + wxArrayDouble + wxArrayInt + wxArrayPtrVoid + wxArrayShort + wxArrayString + wxBitmap + wxBitmapBundle + wxBitmapHandler + wxBoxSizer + wxBrush + wxChar + wxUniChar + wxUniCharRef + wxColour + wxColourDatabase + wxCursor + wxDateSpan + wxDelegateRendererNative + wxHeaderButtonParams + wxRendererNative + wxRendererVersion + wxTextWrapper + wxDCClipper + wxDCBrushChanger + wxDCFontChanger + wxDCPenChanger + wxDCTextColourChanger + wxDCTextBgColourChanger + wxDCTextBgModeChanger + wxFileType + wxFont + wxFlexGridSizer + wxFontEnumerator + wxFontInfo + wxFontList + wxFontMetrics + wxGBPosition + wxGBSizerItem + wxGBSpan + wxGDIObject + wxGraphicsBrush + wxGraphicsFont + wxGraphicsGradientStop + wxGraphicsGradientStops + wxGraphicsMatrix + wxGraphicsPath + wxGridBagSizer + wxGridSizer + wxIcon + wxIconBundle + wxIconLocation + wxIFFHandler + wxImage + wxImageHandler + wxGIFHandler + wxJPEGHandler + wxPCXHandler + wxPNGHandler + wxPNMHandler + wxTGAHandler + wxTIFFHandler + wxXPMHandler + wxMask + wxMetafile + wxNativeFontInfo + wxPalette + wxPen + wxPenList + wxPoint + wxPoint2DDouble + wxPoint2DInt + wxPosition + wxRealPoint + wxRegion + wxRegionContain + wxRegionIterator + wxRegEx + wxRect + wxSize + wxSizer + wxSizerItem + wxSplitterRenderParams + wxStaticBoxSizer + wxStdDialogButtonSizer + wxSystemOptions + wxSystemSettings + wxTarEntry + wxTarInputStream + wxTimeSpan + wxUString + wxVariant + wxVariantData + wxVariantDataCurrency + wxVariantDataErrorCode + wxVariantDataSafeArray + wxVector + wxVersionInfo + wxWrapSizer + wxZipEntry + wxZipInputStream + + + + + + @@ -25,6 +136,7 @@ + @@ -85,12 +197,13 @@ + - - + + @@ -136,7 +249,6 @@ - @@ -205,7 +317,6 @@ - @@ -256,7 +367,6 @@ - @@ -284,7 +394,6 @@ - @@ -348,13 +457,11 @@ - - @@ -398,7 +505,6 @@ - @@ -407,7 +513,11 @@ + + + + @@ -579,10 +689,7 @@ - - - @@ -613,7 +720,6 @@ - @@ -676,32 +782,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -780,13 +860,6 @@ - - - - - - - @@ -813,10 +886,6 @@ - - - - @@ -1062,11 +1131,6 @@ - - - - - @@ -3282,9 +3346,6 @@ - - - @@ -3502,13 +3563,6 @@ - - - - - - - @@ -3562,6 +3616,10 @@ + + + + @@ -3723,47 +3781,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3872,23 +3892,7 @@ - - - - - - - - - - - - - - - - @@ -4075,14 +4079,6 @@ - - - - - - - - @@ -5131,15 +5127,6 @@ - - - - - - - - - @@ -5159,10 +5146,6 @@ - - - - @@ -5189,9 +5172,6 @@ - - - @@ -5233,6 +5213,10 @@ + + + + @@ -5430,20 +5414,22 @@ - + false + - + false + This is the same as 'wxString::IsEmpty' and is kept for wxWidgets 1.xx compatibility. You should not use it in new code. @@ -5494,7 +5480,8 @@ - + + false @@ -5697,7 +5684,7 @@ - + @@ -5709,7 +5696,18 @@ - + + + + + + false + + + + + + false @@ -5722,6 +5720,14 @@ + + + false + + + + + @@ -5737,6 +5743,14 @@ + + + false + + + + + false @@ -5910,16 +5924,16 @@ - - - - - - - - - - + + + + + + + + + + false @@ -5927,9 +5941,9 @@ - - - + + + false @@ -5937,15 +5951,15 @@ - + false - - + + false @@ -5953,7 +5967,7 @@ - + @@ -5963,13 +5977,13 @@ - + false - + false @@ -5983,7 +5997,7 @@ - + false @@ -5997,7 +6011,7 @@ - + false @@ -6008,7 +6022,7 @@ - + false @@ -6229,6 +6243,29 @@ + + + false + + + + + + + + false + + + + + + + false + + + + + @@ -6248,6 +6285,22 @@ + + + false + + + + + + + + false + + + + + false @@ -6820,7 +6873,7 @@ false - + @@ -7200,6 +7253,25 @@ This function is deprecated, use 'wxPGProperty::GetValueAsString()' instead. + + + + false + + + + + + + + + false + + + + + + @@ -7238,7 +7310,7 @@ This function is deprecated, please use 'wxFileName::SplitPath()' instead. - + false @@ -7309,7 +7381,7 @@ false - + @@ -7337,7 +7409,7 @@ This function is deprecated. Construct a wxFileName with wxPATH_UNIX and then use wxFileName::GetFullPath(wxPATH_DOS) instead. - + false @@ -7420,6 +7492,26 @@ Use 'wxStyledTextEvent::GetString()' instead. + + + + false + + + + + + + + + + + false + + + + + @@ -7429,6 +7521,27 @@ This function is deprecated. + + + + + + + + + + + + + + + + false + + + + + false @@ -7443,9 +7556,18 @@ false + This function is deprecated and kept mostly for backwards compatibility. Please override 'GetMargins()' method instead in any new code. + + + false + + + + + @@ -7475,7 +7597,7 @@ This function is deprecated and kept mostly for backwards compatibility. Please override 'SetMargins()' method instead in any new code. - + false @@ -7583,6 +7705,15 @@ This function is deprecated. Please use 'wxFileName::SplitPath()' instead. + + + false + + + + + + @@ -7906,7 +8037,7 @@ This function is deprecated since version 3.1.2, dimensions and depth can only be set at construction time. - + false @@ -7916,7 +8047,7 @@ - + false @@ -8409,7 +8540,7 @@ - + false @@ -8450,7 +8581,7 @@ - + false @@ -8660,7 +8791,7 @@ This function is deprecated. Please use 'SetDefaultCellTextColour(colour)' instead. --> - + false @@ -9488,9 +9619,9 @@ - - - + + + false @@ -9886,8 +10017,8 @@ - - + + false @@ -10017,7 +10148,7 @@ - false @@ -10110,14 +10241,6 @@ - - - false - - - - - false @@ -10238,6 +10361,14 @@ + + + false + + + + + false @@ -10264,6 +10395,17 @@ + + + + + + false + + + + + false @@ -10639,7 +10781,7 @@ - + false @@ -10683,6 +10825,20 @@ + + + false + + + + + + false + + + + + false @@ -10872,7 +11028,7 @@ - + false @@ -10885,7 +11041,7 @@ - + false @@ -10929,14 +11085,16 @@ - - + + + false + - + false @@ -10983,7 +11141,7 @@ - + false @@ -11091,7 +11249,7 @@ 0: - + false @@ -11103,7 +11261,7 @@ 0: - + false @@ -11243,6 +11401,12 @@ + + + false + + + @@ -11509,6 +11673,44 @@ + + + + false + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + false + + + + + @@ -11517,6 +11719,30 @@ + + + false + + + + + + + + false + + + + + + + + false + + + + + @@ -11588,6 +11814,105 @@ + + + false + + + + + + + + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + false + + + + + + + false + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + @@ -11738,6 +12063,24 @@ + + + + false + + + + + + + + + false + + + + + @@ -12184,7 +12527,8 @@ - + + false @@ -13751,7 +14095,7 @@ wxItemKind kind = wxITEM_NORMAL) --> false - + false @@ -14095,10 +14439,76 @@ wxItemKind kind = wxITEM_NORMAL) --> + + + + + + false + + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + + false + + + + + + + + + false + + + + + + + - + + + false @@ -14106,6 +14516,12 @@ wxItemKind kind = wxITEM_NORMAL) --> + + + false + + + @@ -14516,6 +14932,14 @@ wxItemKind kind = wxITEM_NORMAL) --> + + + false + + + + + false @@ -15147,6 +15571,45 @@ wxItemKind kind = wxITEM_NORMAL) --> + + + false + + + + + + + + false + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + false @@ -15316,6 +15779,13 @@ wxItemKind kind = wxITEM_NORMAL) --> + + + + false + + + false @@ -15327,13 +15797,66 @@ wxItemKind kind = wxITEM_NORMAL) --> - + + false + + + false + + + + + + + false + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + false + + + + + false @@ -15540,7 +16063,7 @@ wxItemKind kind = wxITEM_NORMAL) --> - + false @@ -15551,7 +16074,7 @@ wxItemKind kind = wxITEM_NORMAL) --> - + false @@ -15593,13 +16116,37 @@ wxItemKind kind = wxITEM_NORMAL) --> - + false + + + + false + + + + + + + + false + + + + + + + + false + + + + false @@ -15608,6 +16155,25 @@ wxItemKind kind = wxITEM_NORMAL) --> + + + + false + + + + + + + + + + false + + + + + @@ -15913,12 +16479,12 @@ wxItemKind kind = wxITEM_NORMAL) --> - false @@ -16168,7 +16734,8 @@ wxItemKind kind = wxITEM_NORMAL) --> - + + false @@ -16351,13 +16918,13 @@ wxItemKind kind = wxITEM_NORMAL) --> - false @@ -16376,7 +16943,7 @@ wxItemKind kind = wxITEM_NORMAL) --> false @@ -16452,4 +17019,291 @@ wxItemKind kind = wxITEM_NORMAL) --> 0: + + + + false + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + false + + + + + + false + + + + + + + + + false + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + + + + false + + + + + diff --git a/clang-tidy.md b/clang-tidy.md index 8e6625081a6..72df0375ca1 100644 --- a/clang-tidy.md +++ b/clang-tidy.md @@ -8,158 +8,194 @@ We do not perform static analysis of the source of the external libraries. `simp ## Disabled Checks -`abseil-*`
-`altera-*`
-`android-*`
-`boost-*`
-`darwin-*`
-`fuchsia-*`
-`linuxkernel-*`
-`llvm-*`
-`llvmlibc-*`
-`mpi-*`
-`objc-*`
-`openmp-*`
-`zircon-*`
+`abseil-*`
+`altera-*`
+`android-*`
+`boost-*`
+`darwin-*`
+`fuchsia-*`
+`linuxkernel-*`
+`llvm-*`
+`llvmlibc-*`
+`mpi-*`
+`objc-*`
+`openmp-*`
+`zircon-*`
These are disabled since the platforms/libraries in question are not targeted by us. -`cert-*`
-`cppcoreguidelines-*`
-`google-*`
-`hicpp-*`
+`cert-*`
+`cppcoreguidelines-*`
+`google-*`
+`hicpp-*`
These are coding guidelines we do not follow. Some of the checks might be explicitly enabled though. -`readability-braces-around-statements`
-`readability-isolate-declaration`
-`modernize-use-trailing-return-type`
-`modernize-use-auto`
-`readability-uppercase-literal-suffix`
-`readability-else-after-return`
-`modernize-use-default-member-init`
-`readability-identifier-length`
+`readability-braces-around-statements`
+`readability-isolate-declaration`
+`readability-uppercase-literal-suffix`
+`readability-identifier-length`
-These do not relect the style we are (currently) enforcing. +These do not reflect the style we are (currently) enforcing. -`readability-function-size`
-`readability-function-cognitive-complexity`
+`readability-function-size`
+`readability-function-cognitive-complexity`
-We are not interesting in the size/complexity of a function. +We are not interested in the size/complexity of a function. -`readability-magic-numbers`
-`readability-redundant-member-init`
+`readability-magic-numbers`
These do not (always) increase readability. -`bugprone-macro-parentheses`
+`bugprone-macro-parentheses`
To be documented. -`readability-implicit-bool-conversion`
+`readability-implicit-bool-conversion`
-This does not appear not to be useful as it is reported on very common code. +This does not appear to be useful as it is reported on very common code. -`bugprone-narrowing-conversions`
-`performance-no-automatic-move`
+`bugprone-narrowing-conversions`
+`performance-no-automatic-move`
It was decided not to apply these. -`modernize-use-equals-default`
-`modernize-loop-convert`
+`modernize-loop-convert`
These might change the behavior of code which might not be intended (need to file an upstream issue) -`modernize-raw-string-literal`
+`modernize-raw-string-literal`
This leads to a mismatch of raw string literals and regular ones and does reduce the readability. -`readability-convert-member-functions-to-static`
+`-clang-analyzer-*`
-Disabled because of false positives with Qt `slot` methods (see https://github.com/llvm/llvm-project/issues/57520). - -`-clang-analyzer-*`
+Disabled because of false positives (need to file upstream bug reports). The checks are also quite time consuming. -Disabled because of false positives (needs to file an upstream bug report). - -`misc-non-private-member-variables-in-classes`
+`misc-non-private-member-variables-in-classes`
We intentionally use this. -`misc-no-recursion`
+`misc-no-recursion`
Leads to lots of "false positives". This seem to enforce a coding guidelines of certain codebases. -`readability-use-anyofallof`
- -We currently don't even apply our own `useStlAlgorithm` findings. - -`bugprone-easily-swappable-parameters`
+`bugprone-easily-swappable-parameters`
This produces a lot of noise and they are not fixable that easily. -`readability-container-data-pointer`
+`readability-container-data-pointer`
Disable because of false positives and inconsistent warnings (need to file an upstream bug report). -`misc-const-correctness`
+`misc-const-correctness`
Work in progress. -`bugprone-assignment-in-if-condition`
+`bugprone-assignment-in-if-condition`
Is reported for valid patterns we are using. -`readability-suspicious-call-argument`
+`readability-suspicious-call-argument`
Produces a lot of false positives since it is too vague in its analysis. -`performance-inefficient-string-concatenation`
+`performance-inefficient-string-concatenation`
Produces warnings which might be considered false positives starting with C++11 - see https://github.com/llvm/llvm-project/issues/54526. -`readability-redundant-access-specifiers`
- -Reports warning with the Qt ` slots:` syntax in class declarations - see https://github.com/llvm/llvm-project/issues/60055. - -`modernize-avoid-c-arrays`
+`modernize-avoid-c-arrays`
Produces warnings when `const char[]` is being used which is quite common in our code. Does not make sense to enable before C++17 when `std::string_view` becomes available. Also reports a false positive about templates which deduce the array length: https://github.com/llvm/llvm-project/issues/60053. -`readability-container-size-empty`
-`bugprone-branch-clone`
-`readability-const-return-type`
-`modernize-return-braced-init-list`
-`misc-throw-by-value-catch-by-reference`
-`readability-avoid-const-params-in-decls`
-`bugprone-signed-char-misuse`
-`readability-redundant-access-specifiers`
-`concurrency-mt-unsafe`
-`misc-use-anonymous-namespace`
+`misc-include-cleaner`
+ +We run this separately via `clang-include-cleaner` in the `iwyu.yml` workflow as the findings of the include checkers still need to be reviewed manually before applying them. + +`readability-use-concise-preprocessor-directives`
+ +Does not improve the readability. + +`bugprone-branch-clone`
+`modernize-return-braced-init-list`
+`misc-throw-by-value-catch-by-reference`
+`bugprone-signed-char-misuse`
+`concurrency-mt-unsafe`
+`misc-use-anonymous-namespace`
+`performance-avoid-endl`
+`bugprone-switch-missing-default-case`
+`bugprone-empty-catch`
+`readability-avoid-nested-conditional-operator`
+`modernize-use-designated-initializers`
+`readability-enum-initial-value`
+`modernize-use-trailing-return-type`
+ +To be evaluated (need to remove exclusion). + +`cppcoreguidelines-missing-std-forward`
+`cppcoreguidelines-avoid-const-or-ref-data-members`
+`cppcoreguidelines-macro-usage`
+`cppcoreguidelines-pro-type-member-init`
+`cppcoreguidelines-prefer-member-initializer`
+`cppcoreguidelines-misleading-capture-default-by-value`
+`bugprone-argument-comment.CommentBoolLiterals`
+`cert-err33-c`
+`google-readability-namespace-comments`
+`cppcoreguidelines-special-member-functions`
+ +To be evaluated (need to enable explicitly). -To be evaluated. +`modernize-type-traits`
+`modernize-use-nodiscard`
+`modernize-use-scoped-lock`
-`portability-std-allocator-const`
+These apply to codebases which use later standards then C++11 (C++17 is used when building with Qt6) so we cannot simply apply them. + +`portability-avoid-pragma-once`
+ +We are not interested in this. + +### Disabled for performance reasons + +`portability-std-allocator-const`
Only necessary for code which is exclusively compiled with `libc++`. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132. -`modernize-deprecated-ios-base-aliases`
+`modernize-deprecated-ios-base-aliases`
Warns about aliases which are removed in C++20. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132. -`bugprone-unchecked-optional-access`
+`bugprone-unchecked-optional-access`
We are not using any `optional` implementation. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132. -`modernize-replace-auto-ptr`
+`modernize-replace-auto-ptr`
Still available until C++17. It is unlikely such code will ever be introduced. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132. -`readability-identifier-naming`
+`readability-identifier-naming`
We are currently using our own `naming.json` to enforce naming schemes. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132. -`portability-simd-intrinsics`
+`portability-simd-intrinsics`
We are not using SIMD instructions and it suggests to use `std::experiemental::` features which might not be commonly available. Also disabled for performance reasons - see https://github.com/llvm/llvm-project/issues/57527#issuecomment-1237935132. + +`modernize-macro-to-enum`
+ +It does not seem to produce any warnings for us (needs to be investigated) and it is one of the more expensive checks. + +`misc-unused-using-decls`
+ +This is the most expensive check for several files and it is providing much in terms of code quality. Reported upstream as https://github.com/llvm/llvm-project/issues/72300. + +### Disabled for GUI only + +`readability-convert-member-functions-to-static`
+ +Disabled because of false positives with Qt `slot` methods (see https://github.com/llvm/llvm-project/issues/57520). + +`readability-redundant-access-specifiers`
+ +Reports warning with the Qt ` slots:` syntax in class declarations - see https://github.com/llvm/llvm-project/issues/60055. diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 0221817d929..2664a29a65d 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -1,86 +1,67 @@ + file(GLOB hdrs "*.h") file(GLOB srcs "*.cpp") file(GLOB mainfile "main.cpp") list(REMOVE_ITEM srcs ${mainfile}) -add_library(cli_objs OBJECT ${hdrs} ${srcs}) -target_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/lib/) -if(USE_BUNDLED_TINYXML2) - target_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/tinyxml2/) -else() - target_include_directories(cli_objs SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS}) -endif() -target_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/) +add_library(cli ${hdrs} ${srcs}) +target_include_directories(cli PUBLIC .) +target_link_libraries(cli PRIVATE cppcheck-core frontend tinyxml2 simplecpp picojson) if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS) - target_precompile_headers(cli_objs PRIVATE precompiled.h) -endif() -if (BUILD_CORE_DLL) - target_compile_definitions(cli_objs PRIVATE CPPCHECKLIB_IMPORT TINYXML2_IMPORT) + target_precompile_headers(cli PRIVATE precompiled.h) endif() -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14) - # false positive warning in up to Clang 13 - caused by FD_ZERO macro +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 13) + # false positive warning in Clang 13 - caused by FD_ZERO macro set_source_files_properties(processexecutor.cpp PROPERTIES COMPILE_FLAGS -Wno-reserved-identifier) endif() -list(APPEND cppcheck_SOURCES ${hdrs} ${mainfile} $) -if (NOT BUILD_CORE_DLL) - list(APPEND cppcheck_SOURCES $) - list(APPEND cppcheck_SOURCES $) - if(USE_BUNDLED_TINYXML2) - list(APPEND cppcheck_SOURCES $) +if (BUILD_CLI) + list(APPEND cppcheck_SOURCES ${hdrs} ${mainfile}) + if (WIN32) + list(APPEND cppcheck_SOURCES version.rc) endif() -endif() -if (WIN32) - list(APPEND cppcheck_SOURCES version.rc) -endif() -add_executable(cppcheck ${cppcheck_SOURCES}) -target_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/lib/) -if(USE_BUNDLED_TINYXML2) - target_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/tinyxml2/) -else() - target_include_directories(cppcheck SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS}) -endif() -target_include_directories(cppcheck PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/) -if (HAVE_RULES) - target_link_libraries(cppcheck ${PCRE_LIBRARY}) -endif() -if (WIN32 AND NOT BORLAND) - if(NOT MINGW) - target_link_libraries(cppcheck Shlwapi.lib) - else() - target_link_libraries(cppcheck shlwapi) + add_executable(cppcheck ${cppcheck_SOURCES}) + target_link_libraries(cppcheck cppcheck-core cli tinyxml2 simplecpp) + if (WIN32 AND NOT BORLAND) + if(NOT MINGW) + target_link_libraries(cppcheck Shlwapi.lib) + else() + target_link_libraries(cppcheck shlwapi) + endif() endif() -endif() -if(tinyxml2_FOUND AND NOT USE_BUNDLED_TINYXML2) - target_link_libraries(cppcheck ${tinyxml2_LIBRARIES}) -endif() -target_link_libraries(cppcheck ${CMAKE_THREAD_LIBS_INIT}) -if (BUILD_CORE_DLL) - target_link_libraries(cppcheck cppcheck-core) -endif() + target_link_libraries(cppcheck ${CMAKE_THREAD_LIBS_INIT}) -add_dependencies(cppcheck copy_cfg) -add_dependencies(cppcheck copy_addons) -add_dependencies(cppcheck copy_platforms) -if (NOT DISABLE_DMAKE) - add_dependencies(cppcheck run-dmake) -endif() + add_dependencies(cppcheck copy_cfg) + add_dependencies(cppcheck copy_addons) + add_dependencies(cppcheck copy_platforms) + if (NOT DISABLE_DMAKE) + add_dependencies(cppcheck run-dmake) + endif() -install(TARGETS cppcheck - RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} - COMPONENT applications) + install(TARGETS cppcheck + RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} + COMPONENT applications) -install(FILES ${addons} - DESTINATION ${FILESDIR}/addons - COMPONENT headers) + install(PROGRAMS ${CMAKE_SOURCE_DIR}/htmlreport/cppcheck-htmlreport + DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} + COMPONENT applications) -install(FILES ${cfgs} - DESTINATION ${FILESDIR}/cfg - COMPONENT headers) + install(FILES ${addons_py} + DESTINATION ${FILESDIR_DEF}/addons + COMPONENT headers) -install(FILES ${platforms} - DESTINATION ${FILESDIR}/platforms - COMPONENT headers) + install(FILES ${addons_json} + DESTINATION ${FILESDIR_DEF}/addons + COMPONENT headers) + install(FILES ${cfgs} + DESTINATION ${FILESDIR_DEF}/cfg + COMPONENT headers) + + install(FILES ${platforms} + DESTINATION ${FILESDIR_DEF}/platforms + COMPONENT headers) + +endif() diff --git a/cli/cli.vcxproj b/cli/cli.vcxproj index 6e642479a7d..05d1cf2916d 100644 --- a/cli/cli.vcxproj +++ b/cli/cli.vcxproj @@ -1,34 +1,18 @@  - - Debug-PCRE - Win32 - Debug-PCRE x64 - - Debug - Win32 - Debug x64 - - Release-PCRE - Win32 - Release-PCRE x64 - - Release - Win32 - Release x64 @@ -40,18 +24,6 @@ 10.0 - - Application - Unicode - false - v142 - - - Application - Unicode - false - v142 - Application Unicode @@ -64,18 +36,6 @@ false v142 - - Application - Unicode - false - v142 - - - Application - Unicode - false - v142 - Application Unicode @@ -90,24 +50,12 @@ - - - - - - - - - - - - @@ -116,114 +64,35 @@ - $(SolutionDir)bin\debug\ - $(SolutionDir)bin\debug\ $(SolutionDir)bin\debug\ $(SolutionDir)bin\debug\ - temp\$(Configuration)_$(PlatformName)\ - temp\$(Configuration)_$(PlatformName)\ temp\$(Configuration)_$(PlatformName)\ temp\$(Configuration)_$(PlatformName)\ - cppcheck - cppcheck cppcheck cppcheck - true - true true true - $(SolutionDir)bin\ - $(SolutionDir)bin\ $(SolutionDir)bin\ $(SolutionDir)bin\ - temp\$(Configuration)_$(PlatformName)\ - temp\$(Configuration)_$(PlatformName)\ temp\$(Configuration)_$(PlatformName)\ temp\$(Configuration)_$(PlatformName)\ - cppcheck - cppcheck cppcheck cppcheck - true - true true true - true - true true true - - - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) - false - true - ProgramDatabase - Disabled - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;WIN32;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level4 - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 - true - Use - precompiled.h - precompiled.h - true - stdcpp14 - /Zc:throwingNew /Zc:__cplusplus %(AdditionalOptions) - - - shlwapi.lib;%(AdditionalDependencies) - ../externals;%(AdditionalLibraryDirectories) - true - Console - true - $(OutDir)$(TargetName).pdb - true - 8000000 - 8000000 - - - - - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) - false - true - ProgramDatabase - Disabled - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;WIN32;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;TIXML_USE_STL;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Level4 - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 - true - Use - precompiled.h - precompiled.h - true - stdcpp14 - /Zc:throwingNew /Zc:__cplusplus %(AdditionalOptions) - - - shlwapi.lib;%(AdditionalDependencies) - ../externals;%(AdditionalLibraryDirectories) - true - Console - true - true - 8000000 - 8000000 - - - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) + ..\lib;..\frontend;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) true ProgramDatabase Disabled - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;WIN32;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions) + CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level4 - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 + 4018;4127;4146;4244;4251;4267;4389;4701;4706;4800;4805 true Use precompiled.h @@ -245,14 +114,14 @@ - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) + ..\lib;..\frontend;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) true ProgramDatabase Disabled - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;WIN32;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions) + CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level4 - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 + 4018;4127;4146;4244;4251;4267;4389;4701;4706;4800;4805 true Use precompiled.h @@ -272,88 +141,12 @@ true - - - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) - false - MaxSpeed - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - MultiThreadedDLL - Level4 - AnySuitable - true - Speed - true - true - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 - ProgramDatabase - true - Use - precompiled.h - precompiled.h - /Zc:throwingNew /Zc:__cplusplus %(AdditionalOptions) - true - stdcpp14 - true - - - shlwapi.lib;%(AdditionalDependencies) - ../externals;%(AdditionalLibraryDirectories) - true - Console - true - true - true - true - true - 8000000 - 8000000 - - - - - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) - false - MaxSpeed - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;WIN32;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;TIXML_USE_STL;%(PreprocessorDefinitions) - MultiThreadedDLL - Level4 - AnySuitable - true - Speed - true - true - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 - ProgramDatabase - true - Use - precompiled.h - precompiled.h - /Zc:throwingNew /Zc:__cplusplus %(AdditionalOptions) - true - stdcpp14 - true - - - shlwapi.lib;%(AdditionalDependencies) - ../externals;%(AdditionalLibraryDirectories) - true - Console - true - true - true - true - true - 8000000 - 8000000 - - - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) + ..\lib;..\frontend;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) false MaxSpeed - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions) + CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) MultiThreadedDLL Level4 AnySuitable @@ -362,7 +155,7 @@ true true true - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 + 4018;4127;4146;4244;4251;4267;4389;4701;4706;4800;4805 ProgramDatabase true Use @@ -388,10 +181,10 @@ - ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) + ..\lib;..\frontend;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories) false MaxSpeed - CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;WIN32;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions) + CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) MultiThreadedDLL Level4 AnySuitable @@ -400,7 +193,7 @@ true true true - 4018;4127;4146;4244;4251;4267;4389;4482;4512;4701;4706;4800;4805 + 4018;4127;4146;4244;4251;4267;4389;4701;4706;4800;4805 ProgramDatabase true Use @@ -430,14 +223,15 @@ - - + + + @@ -447,14 +241,8 @@ - - Create - Create - Create - Create - Create Create Create Create @@ -462,9 +250,12 @@ + + + diff --git a/cli/cli.vcxproj.filters b/cli/cli.vcxproj.filters index e8385a6c84d..5d3bd1c86cc 100644 --- a/cli/cli.vcxproj.filters +++ b/cli/cli.vcxproj.filters @@ -14,9 +14,6 @@ - - Header Files - Header Files @@ -26,10 +23,7 @@ Header Files - - Header Files - - + Header Files @@ -44,6 +38,15 @@ Header Files + + Header Files + + + Header Files + + + Header Files + @@ -55,10 +58,7 @@ Source Files - - Source Files - - + Source Files @@ -76,6 +76,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + diff --git a/cli/cmdlinelogger.h b/cli/cmdlinelogger.h new file mode 100644 index 00000000000..75981c028cd --- /dev/null +++ b/cli/cmdlinelogger.h @@ -0,0 +1,37 @@ +/* -*- C++ -*- + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2024 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CMD_LINE_LOGGER_H +#define CMD_LINE_LOGGER_H + +#include + +class CmdLineLogger +{ +public: + virtual ~CmdLineLogger() = default; + + /** print a regular message */ + virtual void printMessage(const std::string &message) = 0; + /** print an error message */ + virtual void printError(const std::string &message) = 0; + /** print to the output */ + virtual void printRaw(const std::string &message) = 0; +}; + +#endif // CMD_LINE_LOGGER_H diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index d76edbf9114..48ac7e429d9 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -1,6 +1,6 @@ /* * Cppcheck - A tool for static C/C++ code analysis - * Copyright (C) 2007-2023 Cppcheck team. + * Copyright (C) 2007-2025 Cppcheck team. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,14 +18,20 @@ #include "cmdlineparser.h" +#include "addoninfo.h" #include "check.h" +#include "checkers.h" +#include "color.h" #include "config.h" -#include "cppcheckexecutor.h" +#include "cppcheck.h" #include "errorlogger.h" #include "errortypes.h" #include "filelister.h" +#include "filesettings.h" #include "importproject.h" +#include "library.h" #include "path.h" +#include "pathmatch.h" #include "platform.h" #include "settings.h" #include "standards.h" @@ -33,28 +39,28 @@ #include "timer.h" #include "utils.h" +#include "frontend.h" + #include -#include +#include #include #include // EXIT_FAILURE #include -#include // IWYU pragma: keep +#include #include #include #include +#include #include -#include // IWYU pragma: keep -#include +#include #include #include #ifdef HAVE_RULES -// xml is used for rules -#include -#endif +#include "regex.h" -#ifdef __linux__ -#include +// xml is used for rules +#include "xml.h" #endif static bool addFilesToList(const std::string& fileList, std::vector& pathNames) @@ -69,16 +75,15 @@ static bool addFilesToList(const std::string& fileList, std::vector return false; files = &infile; } - if (files && *files) { - std::string fileName; + std::string fileName; + // cppcheck-suppress accessMoved - FP + while (std::getline(*files, fileName)) { // next line // cppcheck-suppress accessMoved - FP - while (std::getline(*files, fileName)) { // next line - // cppcheck-suppress accessMoved - FP - if (!fileName.empty()) { - pathNames.emplace_back(std::move(fileName)); - } + if (!fileName.empty()) { + pathNames.emplace_back(std::move(fileName)); } } + return true; } @@ -90,8 +95,8 @@ static bool addIncludePathsToList(const std::string& fileList, std::list& se return true; } -CmdLineParser::CmdLineParser(Settings &settings, Suppressions &suppressions, Suppressions &suppressionsNoFail) - : mSettings(settings) +namespace { + class XMLErrorMessagesLogger : public ErrorLogger + { + void reportOut(const std::string & outmsg, Color /*c*/ = Color::Reset) override + { + std::cout << outmsg << std::endl; + } + + void reportErr(const ErrorMessage &msg) override + { + reportOut(msg.toXML()); + } + + void reportMetric(const std::string &metric) override + { + /* Not used here */ + (void) metric; + } + + void reportProgress(const std::string & /*filename*/, const char /*stage*/[], const std::size_t /*value*/) override + {} + }; +} + +CmdLineParser::CmdLineParser(CmdLineLogger &logger, Settings &settings, Suppressions &suppressions) + : mLogger(logger) + , mSettings(settings) , mSuppressions(suppressions) - , mSuppressionsNoFail(suppressionsNoFail) - , mShowHelp(false) - , mShowVersion(false) - , mShowErrorMessages(false) - , mExitAfterPrint(false) {} -void CmdLineParser::printMessage(const std::string &message) +bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[]) { - std::cout << "cppcheck: " << message << std::endl; -} + const Result result = parseFromArgs(argc, argv); -void CmdLineParser::printError(const std::string &message) -{ - printMessage("error: " + message); -} + switch (result) { + case Result::Success: + break; + case Result::Exit: + Settings::terminate(); + return true; + case Result::Fail: + return false; + } -#if defined(_WIN64) || defined(_WIN32) -bool CmdLineParser::SHOW_DEF_PLATFORM_MSG = true; -#endif + // Libraries must be loaded before FileLister is executed to ensure markup files will be + // listed properly. + if (!loadLibraries(mSettings)) + return false; + + if (!loadAddons(mSettings)) + return false; + + // Check that all include paths exist + { + for (auto iter = mSettings.includePaths.cbegin(); + iter != mSettings.includePaths.cend(); + ) { + const std::string path(Path::toNativeSeparators(*iter)); + if (Path::isDirectory(path)) + ++iter; + else { + // TODO: this bypasses the template format and other settings + // If the include path is not found, warn user and remove the non-existing path from the list. + if (mSettings.severity.isEnabled(Severity::information)) + std::cout << "(information) Couldn't find path given by -I '" << path << '\'' << std::endl; + iter = mSettings.includePaths.erase(iter); + } + } + } + + // Output a warning for the user if he tries to exclude headers + const std::vector& ignored = mIgnoredPaths; + const bool warn = std::any_of(ignored.cbegin(), ignored.cend(), [](const std::string& i) { + return Path::isHeader(i); + }); + if (warn) { + mLogger.printMessage("filename exclusion does not apply to header (.h and .hpp) files."); + mLogger.printMessage("Please use --suppress for ignoring results from the header files."); + } + + const std::vector& pathnamesRef = mPathNames; + const std::list& fileSettingsRef = mFileSettings; + + // the inputs can only be used exclusively - CmdLineParser should already handle this + assert(!(!pathnamesRef.empty() && !fileSettingsRef.empty())); + + if (!fileSettingsRef.empty()) { + // TODO: de-duplicate + + std::list fileSettings; + if (!mSettings.fileFilters.empty()) { + // filter only for the selected filenames from all project files + PathMatch filtermatcher(mSettings.fileFilters, Path::getCurrentPath()); + std::copy_if(fileSettingsRef.cbegin(), fileSettingsRef.cend(), std::back_inserter(fileSettings), [&](const FileSettings &fs) { + return filtermatcher.match(fs.filename()); + }); + if (fileSettings.empty()) { + for (const std::string& f: mSettings.fileFilters) + mLogger.printError("could not find any files matching the filter:" + f); + return false; + } + } + else { + fileSettings = fileSettingsRef; + } + + mFileSettings.clear(); + + frontend::applyLang(fileSettings, mSettings, mEnforcedLang); + + // sort the markup last + std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) { + return !mSettings.library.markupFile(fs.filename()) || !mSettings.library.processMarkupAfterCode(fs.filename()); + }); + + std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) { + return mSettings.library.markupFile(fs.filename()) && mSettings.library.processMarkupAfterCode(fs.filename()); + }); + + if (mFileSettings.empty()) { + mLogger.printError("could not find or open any of the paths given."); + return false; + } + } + + if (!pathnamesRef.empty()) { + std::list filesResolved; + // Execute recursiveAddFiles() to each given file parameter + // TODO: verbose log which files were ignored? + const PathMatch matcher(ignored, Path::getCurrentPath()); + for (const std::string &pathname : pathnamesRef) { + const std::string err = FileLister::recursiveAddFiles(filesResolved, Path::toNativeSeparators(pathname), mSettings.library.markupExtensions(), matcher, mSettings.debugignore); + if (!err.empty()) { + // TODO: bail out? + mLogger.printMessage(err); + } + } + + if (filesResolved.empty()) { + mLogger.printError("could not find or open any of the paths given."); + // TODO: PathMatch should provide the information if files were ignored + if (!ignored.empty()) + mLogger.printMessage("Maybe all paths were ignored?"); + return false; + } + + // de-duplicate files + { + auto it = filesResolved.begin(); + while (it != filesResolved.end()) { + const std::string& name = it->path(); + // TODO: log if duplicated files were dropped + filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](const FileWithDetails& entry) { + return entry.path() == name; + }), filesResolved.end()); + ++it; + } + } + + std::list files; + if (!mSettings.fileFilters.empty()) { + files = filterFiles(mSettings.fileFilters, filesResolved); + if (files.empty()) { + for (const std::string& f: mSettings.fileFilters) + mLogger.printError("could not find any files matching the filter:" + f); + return false; + } + } + else { + files = std::move(filesResolved); + } + + frontend::applyLang(files, mSettings, mEnforcedLang); + + // sort the markup last + std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const FileWithDetails& entry) { + return !mSettings.library.markupFile(entry.path()) || !mSettings.library.processMarkupAfterCode(entry.path()); + }); + + std::copy_if(files.cbegin(), files.cend(), std::inserter(mFiles, mFiles.end()), [&](const FileWithDetails& entry) { + return mSettings.library.markupFile(entry.path()) && mSettings.library.processMarkupAfterCode(entry.path()); + }); + + if (mFiles.empty()) { + mLogger.printError("could not find or open any of the paths given."); + return false; + } + } + + return true; +} // TODO: normalize/simplify/native all path parameters // TODO: error out on all missing given files/paths -bool CmdLineParser::parseFromArgs(int argc, const char* const argv[]) +CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const argv[]) { -#if defined(_WIN64) || defined(_WIN32) - bool default_platform = true; -#endif + mSettings.exename = Path::getCurrentExecutablePath(argv[0]); - bool def = false; - bool maxconfigs = false; + bool xmlOptionProvided = false; + bool outputFormatOptionProvided = false; - mSettings.exename = Path::getCurrentExecutablePath(argv[0]); + // default to --check-level=normal from CLI for now + mSettings.setCheckLevel(Settings::CheckLevel::normal); + // read --debug-lookup early so the option is available for the cppcheck.cfg loading for (int i = 1; i < argc; i++) { - if (argv[i][0] == '-') { - // User define - if (std::strncmp(argv[i], "-D", 2) == 0) { - std::string define; - - // "-D define" - if (std::strcmp(argv[i], "-D") == 0) { - ++i; - if (i >= argc || argv[i][0] == '-') { - printError("argument to '-D' is missing."); - return false; - } - - define = argv[i]; - } - // "-Ddefine" - else { - define = 2 + argv[i]; - } + // Show debug warnings for lookup for configuration files + if (std::strcmp(argv[i], "--debug-lookup") == 0) + mSettings.debuglookup = true; + + else if (std::strncmp(argv[i], "--debug-lookup=", 15) == 0) { + const std::string lookup = argv[i] + 15; + if (lookup == "all") + mSettings.debuglookup = true; + else if (lookup == "addon") + mSettings.debuglookupAddon = true; + else if (lookup == "config") + mSettings.debuglookupConfig = true; + else if (lookup == "library") + mSettings.debuglookupLibrary = true; + else if (lookup == "platform") + mSettings.debuglookupPlatform = true; + else + { + mLogger.printError("unknown lookup '" + lookup + "'"); + return Result::Fail; + } + } + } - // No "=", append a "=1" - if (define.find('=') == std::string::npos) - define += "=1"; + if (!loadCppcheckCfg()) + return Result::Fail; - if (!mSettings.userDefines.empty()) - mSettings.userDefines += ";"; - mSettings.userDefines += define; + if (argc <= 1) { + printHelp(); + return Result::Exit; + } - def = true; + // check for exclusive options + for (int i = 1; i < argc; i++) { + // documentation.. + if (std::strcmp(argv[i], "--doc") == 0) { + std::ostringstream doc; + // Get documentation.. + for (const Check * it : Check::instances()) { + const std::string& name(it->name()); + const std::string info(it->classInfo()); + if (!name.empty() && !info.empty()) + doc << "## " << name << " ##\n" + << info << "\n"; } - // -E - else if (std::strcmp(argv[i], "-E") == 0) { - mSettings.preprocessOnly = true; - mSettings.quiet = true; + mLogger.printRaw(doc.str()); + return Result::Exit; + } + + // print all possible error messages.. + if (std::strcmp(argv[i], "--errorlist") == 0) { + { + XMLErrorMessagesLogger xmlLogger; + std::cout << ErrorMessage::getXMLHeader(mSettings.cppcheckCfgProductName, 2); + CppCheck::getErrorMessages(xmlLogger); + std::cout << ErrorMessage::getXMLFooter(2) << std::endl; } + return Result::Exit; + } - // Include paths - else if (std::strncmp(argv[i], "-I", 2) == 0) { - std::string path; + // Print help + if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) { + printHelp(); + return Result::Exit; + } - // "-I path/" - if (std::strcmp(argv[i], "-I") == 0) { - ++i; - if (i >= argc || argv[i][0] == '-') { - printError("argument to '-I' is missing."); - return false; - } - path = argv[i]; - } + if (std::strcmp(argv[i], "--filesdir") == 0) { +#ifdef FILESDIR + mLogger.printRaw(FILESDIR); // TODO: should not include newline +#endif + return Result::Exit; + } - // "-Ipath/" - else { - path = 2 + argv[i]; - } - path = Path::removeQuotationMarks(path); - path = Path::fromNativeSeparators(path); + if (std::strcmp(argv[i], "--version") == 0) { + const std::string version = getVersion(); + mLogger.printRaw(version); // TODO: should not include newline + return Result::Exit; + } + } - // If path doesn't end with / or \, add it - if (!endsWith(path,'/')) - path += '/'; + bool debug = false; + bool inputAsFilter = false; // set by: --file-filter=+ - mSettings.includePaths.emplace_back(std::move(path)); - } + ImportProject::Type projectType = ImportProject::Type::NONE; + ImportProject project; + std::string vsConfig; - // User undef - else if (std::strncmp(argv[i], "-U", 2) == 0) { - std::string undef; + std::string platform; + char defaultSign = '\0'; - // "-U undef" - if (std::strcmp(argv[i], "-U") == 0) { - ++i; - if (i >= argc || argv[i][0] == '-') { - printError("argument to '-U' is missing."); - return false; - } + std::vector lookupPaths{ + Path::getCurrentPath(), // TODO: do we want to look in CWD? + Path::getPathFromFilename(mSettings.exename), + }; - undef = argv[i]; - } - // "-Uundef" - else { - undef = 2 + argv[i]; + bool executorAuto = true; + + for (int i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + mPathNames.emplace_back(Path::fromNativeSeparators(Path::removeQuotationMarks(argv[i]))); + } + + // User define + else if (std::strncmp(argv[i], "-D", 2) == 0) { + std::string define; + + // "-D define" + if (std::strcmp(argv[i], "-D") == 0) { + ++i; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("argument to '-D' is missing."); + return Result::Fail; } - mSettings.userUndefs.insert(std::move(undef)); + define = argv[i]; + } + // "-Ddefine" + else { + define = 2 + argv[i]; } - else if (std::strncmp(argv[i], "--addon=", 8) == 0) - mSettings.addons.emplace(argv[i]+8); - - else if (std::strncmp(argv[i],"--addon-python=", 15) == 0) - mSettings.addonPython.assign(argv[i]+15); + // No "=", append a "=1" + if (define.find('=') == std::string::npos) + define += "=1"; - // Check configuration - else if (std::strcmp(argv[i], "--check-config") == 0) - mSettings.checkConfiguration = true; + if (!mSettings.userDefines.empty()) + mSettings.userDefines += ";"; + mSettings.userDefines += define; + } - // Check code exhaustively - else if (std::strcmp(argv[i], "--check-level=exhaustive") == 0) - mSettings.setCheckLevelExhaustive(); + // -E + else if (std::strcmp(argv[i], "-E") == 0) { + mSettings.preprocessOnly = true; + mSettings.quiet = true; + } - // Check code with normal analysis - else if (std::strcmp(argv[i], "--check-level=normal") == 0) - mSettings.setCheckLevelNormal(); + // Include paths + else if (std::strncmp(argv[i], "-I", 2) == 0) { + std::string path; - // Check library definitions - else if (std::strcmp(argv[i], "--check-library") == 0) { - mSettings.checkLibrary = true; + // "-I path/" + if (std::strcmp(argv[i], "-I") == 0) { + ++i; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("argument to '-I' is missing."); + return Result::Fail; + } + path = argv[i]; } - else if (std::strncmp(argv[i], "--checks-max-time=", 18) == 0) { - if (!parseNumberArg(argv[i], 18, mSettings.checksMaxTime, true)) - return false; + // "-Ipath/" + else { + path = 2 + argv[i]; } + path = Path::removeQuotationMarks(std::move(path)); + path = Path::fromNativeSeparators(std::move(path)); - else if (std::strcmp(argv[i], "--clang") == 0) { - mSettings.clang = true; - } + // If path doesn't end with / or \, add it + if (!endsWith(path,'/')) + path += '/'; - else if (std::strncmp(argv[i], "--clang=", 8) == 0) { - mSettings.clang = true; - mSettings.clangExecutable = argv[i] + 8; - } + mSettings.includePaths.emplace_back(std::move(path)); + } - else if (std::strncmp(argv[i], "--config-exclude=",17) ==0) { - mSettings.configExcludePaths.insert(Path::fromNativeSeparators(argv[i] + 17)); - } + // User undef + else if (std::strncmp(argv[i], "-U", 2) == 0) { + std::string undef; - else if (std::strncmp(argv[i], "--config-excludes-file=", 23) == 0) { - // open this file and read every input file (1 file name per line) - const std::string cfgExcludesFile(23 + argv[i]); - if (!addPathsToSet(cfgExcludesFile, mSettings.configExcludePaths)) { - printError("unable to open config excludes file at '" + cfgExcludesFile + "'"); - return false; + // "-U undef" + if (std::strcmp(argv[i], "-U") == 0) { + ++i; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("argument to '-U' is missing."); + return Result::Fail; } - } - else if (std::strncmp(argv[i], "--cppcheck-build-dir=", 21) == 0) { - // TODO: bail out when the folder does not exist? will silently do nothing - mSettings.buildDir = Path::fromNativeSeparators(argv[i] + 21); - if (endsWith(mSettings.buildDir, '/')) - mSettings.buildDir.pop_back(); + undef = argv[i]; + } + // "-Uundef" + else { + undef = 2 + argv[i]; } - // Show --debug output after the first simplifications - else if (std::strcmp(argv[i], "--debug") == 0 || - std::strcmp(argv[i], "--debug-normal") == 0) - mSettings.debugnormal = true; + mSettings.userUndefs.insert(std::move(undef)); + } - // Flag used for various purposes during debugging - else if (std::strcmp(argv[i], "--debug-simplified") == 0) - mSettings.debugSimplified = true; + else if (std::strncmp(argv[i], "--addon=", 8) == 0) + mSettings.addons.emplace(argv[i]+8); - // Show template information - else if (std::strcmp(argv[i], "--debug-template") == 0) - mSettings.debugtemplate = true; + else if (std::strncmp(argv[i],"--addon-python=", 15) == 0) + mSettings.addonPython.assign(argv[i]+15); - // Show debug warnings - else if (std::strcmp(argv[i], "--debug-warnings") == 0) - mSettings.debugwarnings = true; + else if (std::strcmp(argv[i],"--analyze-all-vs-configs") == 0) { + mSettings.analyzeAllVsConfigs = true; + mAnalyzeAllVsConfigsSetOnCmdLine = true; + } - else if (std::strncmp(argv[i], "--disable=", 10) == 0) { - const std::string errmsg = mSettings.removeEnabled(argv[i] + 10); - if (!errmsg.empty()) { - printError(errmsg); - return false; - } + // Check configuration + else if (std::strcmp(argv[i], "--check-config") == 0) + mSettings.checkConfiguration = true; + + else if (std::strcmp(argv[i], "--check-headers") == 0) + mSettings.checkHeaders = true; + + // Check level + else if (std::strncmp(argv[i], "--check-level=", 14) == 0) { + Settings::CheckLevel level = Settings::CheckLevel::normal; + const std::string level_s(argv[i] + 14); + if (level_s == "reduced") + level = Settings::CheckLevel::reduced; + else if (level_s == "normal") + level = Settings::CheckLevel::normal; + else if (level_s == "exhaustive") + level = Settings::CheckLevel::exhaustive; + else { + mLogger.printError("unknown '--check-level' value '" + level_s + "'."); + return Result::Fail; } - // documentation.. - else if (std::strcmp(argv[i], "--doc") == 0) { - std::ostringstream doc; - // Get documentation.. - for (const Check * it : Check::instances()) { - const std::string& name(it->name()); - const std::string info(it->classInfo()); - if (!name.empty() && !info.empty()) - doc << "## " << name << " ##\n" - << info << "\n"; - } + mSettings.setCheckLevel(level); + } + + // Check library definitions + else if (std::strcmp(argv[i], "--check-library") == 0) { + mSettings.checkLibrary = true; + } - std::cout << doc.str(); - mExitAfterPrint = true; - return true; + else if (std::strcmp(argv[i], "--check-unused-templates") == 0) + mSettings.checkUnusedTemplates = true; + + else if (std::strncmp(argv[i], "--check-version=", 16) == 0) { + if (!loadCppcheckCfg()) + return Result::Fail; + const std::string actualVersion = getVersion(); + const std::string wantedVersion = argv[i] + 16; + if (actualVersion != wantedVersion) { + mLogger.printError("--check-version check failed. Aborting."); + return Result::Fail; } + } - // dump cppcheck data - else if (std::strcmp(argv[i], "--dump") == 0) - mSettings.dump = true; + else if (std::strncmp(argv[i], "--checkers-report=", 18) == 0) + mSettings.checkersReportFilename = argv[i] + 18; - else if (std::strncmp(argv[i], "--enable=", 9) == 0) { - const std::string enable_arg = argv[i] + 9; - const std::string errmsg = mSettings.addEnabled(enable_arg); - if (!errmsg.empty()) { - printError(errmsg); - return false; - } - // when "style" is enabled, also enable "warning", "performance" and "portability" - if (enable_arg.find("style") != std::string::npos) { - mSettings.addEnabled("warning"); - mSettings.addEnabled("performance"); - mSettings.addEnabled("portability"); - } - if (enable_arg.find("information") != std::string::npos) { - mSettings.addEnabled("missingInclude"); - printMessage("'--enable=information' will no longer implicitly enable 'missingInclude' starting with 2.16. Please enable it explicitly if you require it."); - } - } + else if (std::strncmp(argv[i], "--checks-max-time=", 18) == 0) { + if (!parseNumberArg(argv[i], 18, mSettings.checksMaxTime, true)) + return Result::Fail; + } + + else if (std::strcmp(argv[i], "--clang") == 0) { + mSettings.clang = true; + } + + else if (std::strncmp(argv[i], "--clang=", 8) == 0) { + mSettings.clang = true; + mSettings.clangExecutable = argv[i] + 8; + } + + else if (std::strcmp(argv[i], "--clang-tidy") == 0) { + mSettings.clangTidy = true; + } + + else if (std::strncmp(argv[i], "--clang-tidy=", 13) == 0) { + mSettings.clangTidy = true; + mSettings.clangTidyExecutable = argv[i] + 13; + } + + else if (std::strncmp(argv[i], "--config-exclude=",17) ==0) { + mSettings.configExcludePaths.insert(Path::fromNativeSeparators(argv[i] + 17)); + } - // print all possible error messages.. - else if (std::strcmp(argv[i], "--errorlist") == 0) { - mShowErrorMessages = true; - mSettings.xml = true; - mExitAfterPrint = true; + else if (std::strncmp(argv[i], "--config-excludes-file=", 23) == 0) { + // open this file and read every input file (1 file name per line) + const std::string cfgExcludesFile(23 + argv[i]); + if (!addPathsToSet(cfgExcludesFile, mSettings.configExcludePaths)) { + mLogger.printError("unable to open config excludes file at '" + cfgExcludesFile + "'"); + return Result::Fail; } + } - // --error-exitcode=1 - else if (std::strncmp(argv[i], "--error-exitcode=", 17) == 0) { - if (!parseNumberArg(argv[i], 17, mSettings.exitCode)) - return false; + else if (std::strncmp(argv[i], "--cppcheck-build-dir=", 21) == 0) { + std::string path = Path::fromNativeSeparators(argv[i] + 21); + if (path.empty()) { + mLogger.printError("no path has been specified for --cppcheck-build-dir"); + return Result::Fail; } + if (endsWith(path, '/')) + path.pop_back(); + mSettings.buildDir = std::move(path); + } + + else if (std::strcmp(argv[i], "--cpp-header-probe") == 0) { + mSettings.cppHeaderProbe = true; + } + + else if (std::strcmp(argv[i], "--debug-ast") == 0) + mSettings.debugast = true; + + // Show debug warnings for lookup for configuration files + else if (std::strcmp(argv[i], "--debug-clang-output") == 0) + mSettings.debugClangOutput = true; + + // Show debug messages for ignored files + else if (std::strcmp(argv[i], "--debug-ignore") == 0) + mSettings.debugignore = true; + + // Show --debug output after the first simplifications + else if (std::strcmp(argv[i], "--debug") == 0 || + std::strcmp(argv[i], "--debug-normal") == 0) + debug = true; + + else if (std::strcmp(argv[i], "--debug-lookup") == 0) + continue; // already handled above + + else if (std::strncmp(argv[i], "--debug-lookup=", 15) == 0) + continue; // already handled above + + // Flag used for various purposes during debugging + else if (std::strcmp(argv[i], "--debug-simplified") == 0) + mSettings.debugSimplified = true; + + else if (std::strcmp(argv[i], "--debug-symdb") == 0) + mSettings.debugsymdb = true; - // Exception handling inside cppcheck client - else if (std::strcmp(argv[i], "--exception-handling") == 0) { - mSettings.exceptionHandling = true; + // Show template information + else if (std::strcmp(argv[i], "--debug-template") == 0) + mSettings.debugtemplate = true; + + else if (std::strcmp(argv[i], "--debug-valueflow") == 0) + mSettings.debugvalueflow = true; + + // Show debug warnings + else if (std::strcmp(argv[i], "--debug-warnings") == 0) + mSettings.debugwarnings = true; + + else if (std::strncmp(argv[i], "--disable=", 10) == 0) { + const std::string errmsg = mSettings.removeEnabled(argv[i] + 10); + if (!errmsg.empty()) { + mLogger.printError(errmsg); + return Result::Fail; } + } - // Exception handling inside cppcheck client - else if (std::strncmp(argv[i], "--exception-handling=", 21) == 0) { - const std::string exceptionOutfilename = argv[i] + 21; - if (exceptionOutfilename != "stderr" && exceptionOutfilename != "stdout") { - printError("invalid '--exception-handling' argument"); - return false; - } - mSettings.exceptionHandling = true; - CppCheckExecutor::setExceptionOutput((exceptionOutfilename == "stderr") ? stderr : stdout); + // dump cppcheck data + else if (std::strcmp(argv[i], "--dump") == 0) + mSettings.dump = true; + + else if (std::strcmp(argv[i], "--emit-duplicates") == 0) + mSettings.emitDuplicates = true; + + else if (std::strncmp(argv[i], "--enable=", 9) == 0) { + const std::string enable_arg = argv[i] + 9; + const std::string errmsg = mSettings.addEnabled(enable_arg); + if (!errmsg.empty()) { + mLogger.printError(errmsg); + return Result::Fail; } + // when "style" is enabled, also enable "warning", "performance" and "portability" + if (enable_arg.find("style") != std::string::npos) { + mSettings.addEnabled("warning"); + mSettings.addEnabled("performance"); + mSettings.addEnabled("portability"); + } + } - // Filter errors - else if (std::strncmp(argv[i], "--exitcode-suppressions=", 24) == 0) { - // exitcode-suppressions=filename.txt - std::string filename = 24 + argv[i]; + // --error-exitcode=1 + else if (std::strncmp(argv[i], "--error-exitcode=", 17) == 0) { + if (!parseNumberArg(argv[i], 17, mSettings.exitCode)) + return Result::Fail; + } - std::ifstream f(filename); - if (!f.is_open()) { - printError("couldn't open the file: \"" + filename + "\"."); - return false; - } - const std::string errmsg(mSuppressionsNoFail.parseFile(f)); - if (!errmsg.empty()) { - printError(errmsg); - return false; - } + // Exception handling inside cppcheck client + else if (std::strcmp(argv[i], "--exception-handling") == 0) { +#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING) + mSettings.exceptionHandling = true; +#else + mLogger.printError("Option --exception-handling is not supported since Cppcheck has not been built with any exception handling enabled."); + return Result::Fail; +#endif + } + + // Exception handling inside cppcheck client + else if (std::strncmp(argv[i], "--exception-handling=", 21) == 0) { +#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING) + const std::string exceptionOutfilename = argv[i] + 21; + if (exceptionOutfilename != "stderr" && exceptionOutfilename != "stdout") { + mLogger.printError("invalid '--exception-handling' argument"); + return Result::Fail; } + mSettings.exceptionHandling = true; + mSettings.exceptionOutput = (exceptionOutfilename == "stderr") ? stderr : stdout; +#else + mLogger.printError("Option --exception-handling is not supported since Cppcheck has not been built with any exception handling enabled."); + return Result::Fail; +#endif + } - // use a file filter - else if (std::strncmp(argv[i], "--file-filter=", 14) == 0) - mSettings.fileFilters.emplace_back(argv[i] + 14); + else if (std::strncmp(argv[i], "--executor=", 11) == 0) { + const std::string type = 11 + argv[i]; + if (type == "auto") { + executorAuto = true; + mSettings.executor = Settings::defaultExecutor(); + } + else if (type == "thread") { +#if defined(HAS_THREADING_MODEL_THREAD) + executorAuto = false; + mSettings.executor = Settings::ExecutorType::Thread; +#else + mLogger.printError("executor type 'thread' cannot be used as Cppcheck has not been built with a respective threading model."); + return Result::Fail; +#endif + } + else if (type == "process") { +#if defined(HAS_THREADING_MODEL_FORK) + executorAuto = false; + mSettings.executor = Settings::ExecutorType::Process; +#else + mLogger.printError("executor type 'process' cannot be used as Cppcheck has not been built with a respective threading model."); + return Result::Fail; +#endif + } + else { + mLogger.printError("unknown executor: '" + type + "'."); + return Result::Fail; + } + } - // file list specified - else if (std::strncmp(argv[i], "--file-list=", 12) == 0) { - // open this file and read every input file (1 file name per line) - const std::string fileList = argv[i] + 12; - if (!addFilesToList(fileList, mPathNames)) { - printError("couldn't open the file: \"" + fileList + "\"."); - return false; - } + // Filter errors + else if (std::strncmp(argv[i], "--exitcode-suppressions=", 24) == 0) { + // exitcode-suppressions=filename.txt + std::string filename = 24 + argv[i]; + + std::ifstream f(filename); + if (!f.is_open()) { + mLogger.printError("couldn't open the file: \"" + filename + "\"."); + return Result::Fail; + } + const std::string errmsg(mSuppressions.nofail.parseFile(f)); + if (!errmsg.empty()) { + mLogger.printError(errmsg); + return Result::Fail; } + } - // Force checking of files that have "too many" configurations - else if (std::strcmp(argv[i], "-f") == 0 || std::strcmp(argv[i], "--force") == 0) - mSettings.force = true; + // use a file filter + else if (std::strncmp(argv[i], "--file-filter=", 14) == 0) { + const char *filter = argv[i] + 14; + if (std::strcmp(filter, "-") == 0) { + if (!addFilesToList(filter, mSettings.fileFilters)) { + mLogger.printError("Failed: --file-filter=-"); + return Result::Fail; + } + } else if (std::strcmp(filter, "+") == 0) { + inputAsFilter = true; + } else { + mSettings.fileFilters.emplace_back(filter); + } + } - // Print help - else if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) { - mPathNames.clear(); - mShowHelp = true; - mExitAfterPrint = true; - break; + // file list specified + else if (std::strncmp(argv[i], "--file-list=", 12) == 0) { + // open this file and read every input file (1 file name per line) + const std::string fileList = argv[i] + 12; + if (!addFilesToList(fileList, mPathNames)) { + mLogger.printError("couldn't open the file: \"" + fileList + "\"."); + return Result::Fail; } + } - // Ignored paths - else if (std::strncmp(argv[i], "-i", 2) == 0) { - std::string path; + // Force checking of files that have "too many" configurations + else if (std::strcmp(argv[i], "-f") == 0 || std::strcmp(argv[i], "--force") == 0) { + mSettings.force = true; + mSettings.maxConfigsOption = Settings::maxConfigsNotAssigned; + } - // "-i path/" - if (std::strcmp(argv[i], "-i") == 0) { - ++i; - if (i >= argc || argv[i][0] == '-') { - printError("argument to '-i' is missing."); - return false; - } - path = argv[i]; - } + else if (std::strcmp(argv[i], "--fsigned-char") == 0) + defaultSign = 's'; - // "-ipath/" - else { - path = 2 + argv[i]; - } + else if (std::strcmp(argv[i], "--funsigned-char") == 0) + defaultSign = 'u'; - if (!path.empty()) { - path = Path::removeQuotationMarks(path); - path = Path::fromNativeSeparators(path); - path = Path::simplifyPath(path); + // Ignored paths + else if (std::strncmp(argv[i], "-i", 2) == 0) { + std::string path; - if (FileLister::isDirectory(path)) { - // If directory name doesn't end with / or \, add it - if (!endsWith(path, '/')) - path += '/'; - } - mIgnoredPaths.emplace_back(std::move(path)); + // "-i path/" + if (std::strcmp(argv[i], "-i") == 0) { + ++i; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("argument to '-i' is missing."); + return Result::Fail; } + path = argv[i]; } - else if (std::strncmp(argv[i], "--include=", 10) == 0) { - mSettings.userIncludes.emplace_back(Path::fromNativeSeparators(argv[i] + 10)); + // "-ipath/" + else { + path = 2 + argv[i]; } - else if (std::strncmp(argv[i], "--includes-file=", 16) == 0) { - // open this file and read every input file (1 file name per line) - const std::string includesFile(16 + argv[i]); - if (!addIncludePathsToList(includesFile, mSettings.includePaths)) { - printError("unable to open includes file at '" + includesFile + "'"); - return false; - } + if (!path.empty()) { + mIgnoredPaths.emplace_back(std::move(path)); } + } - // Inconclusive checking - else if (std::strcmp(argv[i], "--inconclusive") == 0) - mSettings.certainty.enable(Certainty::inconclusive); - - // Enables inline suppressions. - else if (std::strcmp(argv[i], "--inline-suppr") == 0) - mSettings.inlineSuppressions = true; + else if (std::strncmp(argv[i], "--include=", 10) == 0) { + mSettings.userIncludes.emplace_back(Path::fromNativeSeparators(argv[i] + 10)); + } - // Checking threads - else if (std::strncmp(argv[i], "-j", 2) == 0) { - std::string numberString; + else if (std::strncmp(argv[i], "--includes-file=", 16) == 0) { + // open this file and read every input file (1 file name per line) + const std::string includesFile(16 + argv[i]); + if (!addIncludePathsToList(includesFile, mSettings.includePaths)) { + mLogger.printError("unable to open includes file at '" + includesFile + "'"); + return Result::Fail; + } + } - // "-j 3" - if (std::strcmp(argv[i], "-j") == 0) { - ++i; - if (i >= argc || argv[i][0] == '-') { - printError("argument to '-j' is missing."); - return false; - } + // Inconclusive checking + else if (std::strcmp(argv[i], "--inconclusive") == 0) + mSettings.certainty.enable(Certainty::inconclusive); - numberString = argv[i]; - } + // Enables inline suppressions. + else if (std::strcmp(argv[i], "--inline-suppr") == 0) + mSettings.inlineSuppressions = true; - // "-j3" - else - numberString = argv[i]+2; + // Checking threads + else if (std::strncmp(argv[i], "-j", 2) == 0) { + std::string numberString; - unsigned int tmp; - std::string err; - if (!strToInt(numberString, tmp, &err)) { - printError("argument to '-j' is not valid - " + err + "."); - return false; - } - if (tmp > 10000) { - // This limit is here just to catch typos. If someone has - // need for more jobs, this value should be increased. - printError("argument for '-j' is allowed to be 10000 at max."); - return false; + // "-j 3" + if (std::strcmp(argv[i], "-j") == 0) { + ++i; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("argument to '-j' is missing."); + return Result::Fail; } - mSettings.jobs = tmp; + + numberString = argv[i]; } -#ifdef THREADING_MODEL_FORK - else if (std::strncmp(argv[i], "-l", 2) == 0) { - std::string numberString; + // "-j3" + else + numberString = argv[i]+2; - // "-l 3" - if (std::strcmp(argv[i], "-l") == 0) { - ++i; - if (i >= argc || argv[i][0] == '-') { - printError("argument to '-l' is missing."); - return false; - } + unsigned int tmp; + std::string err; + if (!strToInt(numberString, tmp, &err)) { + mLogger.printError("argument to '-j' is not valid - " + err + "."); + return Result::Fail; + } + if (tmp == 0) { + // TODO: implement get CPU logical core count and use that. + // Usually, -j 0 would mean "use all available cores," but + // if we get a 0, we just stall and don't do any work. + mLogger.printError("argument for '-j' must be greater than 0."); + return Result::Fail; + } + if (tmp > 1024) { + // Almost nobody has 1024 logical cores, but somebody out + // there does. + mLogger.printError("argument for '-j' is allowed to be 1024 at max."); + return Result::Fail; + } + mSettings.jobs = tmp; + } + + else if (std::strncmp(argv[i], "-l", 2) == 0) { +#ifdef HAS_THREADING_MODEL_FORK + std::string numberString; - numberString = argv[i]; + // "-l 3" + if (std::strcmp(argv[i], "-l") == 0) { + ++i; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("argument to '-l' is missing."); + return Result::Fail; } - // "-l3" - else - numberString = argv[i]+2; + numberString = argv[i]; + } - int tmp; - std::string err; - if (!strToInt(numberString, tmp, &err)) { - printError("argument to '-l' is not valid - " + err + "."); - return false; - } - mSettings.loadAverage = tmp; + // "-l3" + else + numberString = argv[i]+2; + + int tmp; + std::string err; + if (!strToInt(numberString, tmp, &err)) { + mLogger.printError("argument to '-l' is not valid - " + err + "."); + return Result::Fail; } + mSettings.loadAverage = tmp; +#else + mLogger.printError("Option -l cannot be used as Cppcheck has not been built with fork threading model."); + return Result::Fail; #endif + } - // Enforce language (--language=, -x) - else if (std::strncmp(argv[i], "--language=", 11) == 0 || std::strcmp(argv[i], "-x") == 0) { - std::string str; - if (argv[i][2]) { - str = argv[i]+11; - } else { - i++; - if (i >= argc || argv[i][0] == '-') { - printError("no language given to '-x' option."); - return false; - } - str = argv[i]; - } - - if (str == "c") - mSettings.enforcedLang = Settings::Language::C; - else if (str == "c++") - mSettings.enforcedLang = Settings::Language::CPP; - else { - printError("unknown language '" + str + "' enforced."); - return false; + // Enforce language (--language=, -x) + else if (std::strncmp(argv[i], "--language=", 11) == 0 || std::strcmp(argv[i], "-x") == 0) { + std::string str; + if (argv[i][2]) { + str = argv[i]+11; + } else { + i++; + if (i >= argc || argv[i][0] == '-') { + mLogger.printError("no language given to '-x' option."); + return Result::Fail; } + str = argv[i]; } - // --library - else if (std::strncmp(argv[i], "--library=", 10) == 0) { - mSettings.libraries.emplace_back(argv[i] + 10); + if (str == "c") + mEnforcedLang = Standards::Language::C; + else if (str == "c++") + mEnforcedLang = Standards::Language::CPP; + else { + mLogger.printError("unknown language '" + str + "' enforced."); + return Result::Fail; } + } - // Set maximum number of #ifdef configurations to check - else if (std::strncmp(argv[i], "--max-configs=", 14) == 0) { - int tmp; - if (!parseNumberArg(argv[i], 14, tmp)) - return false; - if (tmp < 1) { - printError("argument to '--max-configs=' must be greater than 0."); - return false; + // --library + else if (std::strncmp(argv[i], "--library=", 10) == 0) { + std::vector libs = splitString(argv[i] + 10, ','); + for (auto& l : libs) { + if (l.empty()) { + mLogger.printError("empty library specified."); + return Result::Fail; } - - mSettings.maxConfigs = tmp; - mSettings.force = false; - maxconfigs = true; + mSettings.libraries.emplace_back(std::move(l)); } + } - // max ctu depth - else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0) { - if (!parseNumberArg(argv[i], 16, mSettings.maxCtuDepth)) - return false; + // Set maximum number of #ifdef configurations to check + else if (std::strncmp(argv[i], "--max-configs=", 14) == 0) { + int tmp; + if (!parseNumberArg(argv[i], 14, tmp)) + return Result::Fail; + if (tmp < 1) { + mLogger.printError("argument to '--max-configs=' must be greater than 0."); + return Result::Fail; } - // Write results in file - else if (std::strncmp(argv[i], "--output-file=", 14) == 0) - mSettings.outputFile = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 14)); + mSettings.maxConfigsOption = tmp; + mSettings.force = false; + } - // Experimental: limit execution time for extended valueflow analysis. basic valueflow analysis - // is always executed. - else if (std::strncmp(argv[i], "--performance-valueflow-max-time=", 33) == 0) { - if (!parseNumberArg(argv[i], 33, mSettings.performanceValueFlowMaxTime, true)) - return false; + // max ctu depth + else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0) { + int temp = 0; + if (!parseNumberArg(argv[i], 16, temp)) + return Result::Fail; + if (temp > 10) { + mLogger.printMessage("--max-ctu-depth is being capped at 10. This limitation will be removed in a future Cppcheck version."); + temp = 10; } + mSettings.maxCtuDepth = temp; + } + + else if (std::strncmp(argv[i], "--max-template-recursion=", 25) == 0) { + if (!parseNumberArg(argv[i], 25, mSettings.maxTemplateRecursion)) + return Result::Fail; + } + + else if (std::strcmp(argv[i],"--no-analyze-all-vs-configs") == 0) { + mSettings.analyzeAllVsConfigs = false; + mAnalyzeAllVsConfigsSetOnCmdLine = true; + } + + else if (std::strcmp(argv[i], "--no-check-headers") == 0) + mSettings.checkHeaders = false; + + else if (std::strcmp(argv[i], "--no-check-unused-templates") == 0) + mSettings.checkUnusedTemplates = false; + + // undocumented option for usage in Python tests to indicate that no build dir should be injected + else if (std::strcmp(argv[i], "--no-cppcheck-build-dir") == 0) { + mSettings.buildDir.clear(); + } + + else if (std::strcmp(argv[i], "--no-cpp-header-probe") == 0) { + mSettings.cppHeaderProbe = false; + } + + else if (std::strcmp(argv[i], "--no-safety") == 0) + mSettings.safety = false; - else if (std::strncmp(argv[i], "--performance-valueflow-max-if-count=", 37) == 0) { - if (!parseNumberArg(argv[i], 37, mSettings.performanceValueFlowMaxIfCount, true)) - return false; + // Write results in file + else if (std::strncmp(argv[i], "--output-file=", 14) == 0) + mSettings.outputFile = Path::simplifyPath(argv[i] + 14); + + else if (std::strncmp(argv[i], "--output-format=", 16) == 0) { + if (xmlOptionProvided) { + outputFormatOptionMixingError(); + return Result::Fail; + } + const std::string format = argv[i] + 16; + // plist can not be handled here because it requires additional data + if (format == "text") + mSettings.outputFormat = Settings::OutputFormat::text; + else if (format == "sarif") + mSettings.outputFormat = Settings::OutputFormat::sarif; + else if (format == "xml") + mSettings.outputFormat = Settings::OutputFormat::xml; + else if (format == "xmlv2") { + mSettings.outputFormat = Settings::OutputFormat::xml; + mSettings.xml_version = 2; + } else if (format == "xmlv3") { + mSettings.outputFormat = Settings::OutputFormat::xml; + mSettings.xml_version = 3; + } else { + mLogger.printError("argument to '--output-format=' must be 'text', 'sarif', 'xml' (deprecated), 'xmlv2' or 'xmlv3'."); + return Result::Fail; } + mSettings.plistOutput = ""; + outputFormatOptionProvided = true; + } - // Specify platform - else if (std::strncmp(argv[i], "--platform=", 11) == 0) { - const std::string platform(11+argv[i]); - std::string errstr; - const std::vector paths = {argv[0]}; - if (!mSettings.platform.set(platform, errstr, paths)) { - printError(errstr); - return false; - } + // Experimental: limit execution time for extended valueflow analysis. basic valueflow analysis + // is always executed. + else if (std::strncmp(argv[i], "--performance-valueflow-max-time=", 33) == 0) { + if (!parseNumberArg(argv[i], 33, mSettings.vfOptions.maxTime, true)) + return Result::Fail; + } -#if defined(_WIN64) || defined(_WIN32) - default_platform = false; -#endif + else if (std::strncmp(argv[i], "--performance-valueflow-max-if-count=", 37) == 0) { + if (!parseNumberArg(argv[i], 37, mSettings.vfOptions.maxIfCount, true)) + return Result::Fail; + } - // TODO: remove - // these are loaded via external files and thus have Settings::PlatformFile set instead. - // override the type so they behave like the regular platforms. - if (platform == "unix32-unsigned") - mSettings.platform.type = cppcheck::Platform::Type::Unix32; - else if (platform == "unix64-unsigned") - mSettings.platform.type = cppcheck::Platform::Type::Unix64; - } - - // Write results in results.plist - else if (std::strncmp(argv[i], "--plist-output=", 15) == 0) { - mSettings.plistOutput = Path::simplifyPath(Path::fromNativeSeparators(argv[i] + 15)); - if (mSettings.plistOutput.empty()) - mSettings.plistOutput = "./"; - else if (!endsWith(mSettings.plistOutput,'/')) - mSettings.plistOutput += '/'; - - const std::string plistOutput = Path::toNativeSeparators(mSettings.plistOutput); - if (!FileLister::isDirectory(plistOutput)) { - std::string message("plist folder does not exist: \""); - message += plistOutput; - message += "\"."; - printError(message); - return false; - } + else if (std::strncmp(argv[i], "--performance-valueflow-max-iterations=", 39) == 0) { + if (!parseNumberArg(argv[i], 39, mSettings.vfOptions.maxIterations, true)) + return Result::Fail; + } + + // Specify platform + else if (std::strncmp(argv[i], "--platform=", 11) == 0) { + std::string p = 11 + argv[i]; + if (p.empty()) { + mLogger.printError("empty platform specified."); + return Result::Fail; + } + platform = std::move(p); + } + + // Write results in results.plist + else if (std::strncmp(argv[i], "--plist-output=", 15) == 0) { + std::string path = Path::simplifyPath(argv[i] + 15); + if (path.empty()) + path = "."; + + const std::string plistOutput = Path::toNativeSeparators(path); + if (!Path::isDirectory(plistOutput)) { + std::string message("plist folder does not exist: '"); + message += plistOutput; + message += "'."; + mLogger.printError(message); + return Result::Fail; } - // Special Cppcheck Premium options - else if (std::strncmp(argv[i], "--premium=", 10) == 0 && isCppcheckPremium()) { - if (!mSettings.premiumArgs.empty()) - mSettings.premiumArgs += " "; - const std::string p(argv[i] + 10); - mSettings.premiumArgs += "--" + p; - if (p == "misra-c-2012") - mSettings.addons.emplace("misra"); - } - - // --project - else if (std::strncmp(argv[i], "--project=", 10) == 0) { - mSettings.checkAllConfigurations = false; // Can be overridden with --max-configs or --force - std::string projectFile = argv[i]+10; - ImportProject::Type projType = mSettings.project.import(projectFile, &mSettings); - mSettings.project.projectType = projType; - if (projType == ImportProject::Type::CPPCHECK_GUI) { - mPathNames = mSettings.project.guiProject.pathNames; - for (const std::string &lib : mSettings.project.guiProject.libraries) - mSettings.libraries.emplace_back(lib); - - const auto& excludedPaths = mSettings.project.guiProject.excludedPaths; - std::copy(excludedPaths.cbegin(), excludedPaths.cend(), std::back_inserter(mIgnoredPaths)); - - std::string platform(mSettings.project.guiProject.platform); - - // keep existing platform from command-line intact - if (!platform.empty()) { - if (platform == "Unspecified") { - printMessage("'Unspecified' is a deprecated platform type and will be removed in Cppcheck 2.14. Please use 'unspecified' instead."); - platform = "unspecified"; - } + if (!endsWith(path,'/')) + path += '/'; - std::string errstr; - const std::vector paths = {projectFile, argv[0]}; - if (!mSettings.platform.set(platform, errstr, paths)) { - printError(errstr); - return false; - } - } + mSettings.outputFormat = Settings::OutputFormat::plist; + mSettings.plistOutput = std::move(path); + } - if (!mSettings.project.guiProject.projectFile.empty()) { - projectFile = mSettings.project.guiProject.projectFile; - projType = mSettings.project.import(mSettings.project.guiProject.projectFile, &mSettings); - } - } - if (projType == ImportProject::Type::VS_SLN || projType == ImportProject::Type::VS_VCXPROJ) { - if (mSettings.project.guiProject.analyzeAllVsConfigs == "false") - mSettings.project.selectOneVsConfig(mSettings.platform.type); - if (!CppCheckExecutor::tryLoadLibrary(mSettings.library, argv[0], "windows.cfg")) { - // This shouldn't happen normally. - printError("failed to load 'windows.cfg'. Your Cppcheck installation is broken. Please re-install."); - return false; + // Special Cppcheck Premium options + else if ((std::strncmp(argv[i], "--premium=", 10) == 0 || std::strncmp(argv[i], "--premium-", 10) == 0) && mSettings.premium) { + // valid options --premium=.. + const std::set valid{ + "autosar", + "cert-c-2016", + "cert-c++-2016", + "cert-cpp-2016", + "cert-c", + "cert-c++", + "metrics", + "misra-c-2012", + "misra-c-2023", + "misra-c-2025", + "misra-c++-2008", + "misra-cpp-2008", + "misra-c++-2023", + "misra-cpp-2023", + "bughunting", + "safety", // TODO: deprecate in favor of the regular --saftey/--no-safety + "debug-progress"}; + // valid options --premium-..= + const std::set valid2{ + "cert-c-int-precision", + "license-file" + }; + + if (std::strcmp(argv[i], "--premium=safety-off") == 0) { + mSettings.safety = false; + continue; + } + if (std::strcmp(argv[i], "--premium=safety") == 0) + mSettings.safety = true; + if (!mSettings.premiumArgs.empty()) + mSettings.premiumArgs += " "; + const std::string p(argv[i] + 10); + const std::string p2(p.find('=') != std::string::npos ? p.substr(0, p.find('=')) : ""); + const bool isCodingStandard = startsWith(p, "autosar") || startsWith(p,"cert-") || startsWith(p,"misra-"); + const std::string p3(endsWith(p,":all") && isCodingStandard ? p.substr(0,p.rfind(':')) : p); + if (!valid.count(p3) && !valid2.count(p2)) { + mLogger.printError("invalid --premium option '" + (p2.empty() ? p : p2) + "'."); + return Result::Fail; + } + mSettings.premiumArgs += "--" + p; + if (isCodingStandard) { + // All checkers related to the coding standard should be enabled. The coding standards + // do not all undefined behavior or portability issues. + mSettings.addEnabled("warning"); + mSettings.addEnabled("portability"); + } + } + + // --project + else if (std::strncmp(argv[i], "--project=", 10) == 0) { + if (projectType != ImportProject::Type::NONE) + { + mLogger.printError("multiple --project options are not supported."); + return Result::Fail; + } + + std::string projectFile = argv[i]+10; + projectType = project.import(projectFile, &mSettings, &mSuppressions); + if (projectType == ImportProject::Type::CPPCHECK_GUI) { + for (const std::string &lib : project.guiProject.libraries) + mSettings.libraries.emplace_back(lib); + + const auto& excludedPaths = project.guiProject.excludedPaths; + std::copy(excludedPaths.cbegin(), excludedPaths.cend(), std::back_inserter(mIgnoredPaths)); + + if (!project.guiProject.platform.empty()) + platform = project.guiProject.platform; + + // look for external files relative to project first + lookupPaths.insert(lookupPaths.cbegin(), Path::getPathFromFilename(projectFile)); + + const auto& projectFileGui = project.guiProject.projectFile; + if (!projectFileGui.empty()) { + // read underlying project + projectFile = projectFileGui; + projectType = project.import(projectFileGui, &mSettings, &mSuppressions); + if (projectType == ImportProject::Type::CPPCHECK_GUI) { + mLogger.printError("nested Cppcheck GUI projects are not supported."); + return Result::Fail; } } - if (projType == ImportProject::Type::MISSING) { - printError("failed to open project '" + projectFile + "'. The file does not exist."); - return false; - } - if (projType == ImportProject::Type::UNKNOWN) { - printError("failed to load project '" + projectFile + "'. The format is unknown."); - return false; - } - if (projType == ImportProject::Type::FAILURE) { - printError("failed to load project '" + projectFile + "'. An error occurred."); - return false; - } } + if (projectType == ImportProject::Type::COMPILE_DB) + mSettings.maxConfigsProject = 1; + if (projectType == ImportProject::Type::VS_SLN || projectType == ImportProject::Type::VS_VCXPROJ) { + mSettings.libraries.emplace_back("windows"); + } + for (const auto &error : project.errors) + mLogger.printError(error); + if (projectType == ImportProject::Type::MISSING) { + mLogger.printError("failed to open project '" + projectFile + "'. The file does not exist."); + return Result::Fail; + } + if (projectType == ImportProject::Type::UNKNOWN) { + mLogger.printError("failed to load project '" + projectFile + "'. The format is unknown."); + return Result::Fail; + } + if (projectType == ImportProject::Type::FAILURE) { + mLogger.printError("failed to load project '" + projectFile + "'. An error occurred."); + return Result::Fail; + } + } - // --project-configuration - else if (std::strncmp(argv[i], "--project-configuration=", 24) == 0) { - mVSConfig = argv[i] + 24; - if (!mVSConfig.empty() && (mSettings.project.projectType == ImportProject::Type::VS_SLN || mSettings.project.projectType == ImportProject::Type::VS_VCXPROJ)) - mSettings.project.ignoreOtherConfigs(mVSConfig); - } - - // Only print something when there are errors - else if (std::strcmp(argv[i], "-q") == 0 || std::strcmp(argv[i], "--quiet") == 0) - mSettings.quiet = true; - - // Output relative paths - else if (std::strcmp(argv[i], "-rp") == 0 || std::strcmp(argv[i], "--relative-paths") == 0) - mSettings.relativePaths = true; - else if (std::strncmp(argv[i], "-rp=", 4) == 0 || std::strncmp(argv[i], "--relative-paths=", 17) == 0) { - mSettings.relativePaths = true; - if (argv[i][argv[i][3]=='='?4:17] != 0) { - std::string paths = argv[i]+(argv[i][3]=='='?4:17); - for (;;) { - const std::string::size_type pos = paths.find(';'); - if (pos == std::string::npos) { - mSettings.basePaths.emplace_back(Path::fromNativeSeparators(paths)); - break; - } - mSettings.basePaths.emplace_back(Path::fromNativeSeparators(paths.substr(0, pos))); - paths.erase(0, pos + 1); + // --project-configuration + else if (std::strncmp(argv[i], "--project-configuration=", 24) == 0) { + vsConfig = argv[i] + 24; + if (vsConfig.empty()) { + mLogger.printError("--project-configuration parameter is empty."); + return Result::Fail; + } + if (projectType != ImportProject::Type::VS_SLN && projectType != ImportProject::Type::VS_VCXPROJ) { + mLogger.printError("--project-configuration has no effect - no Visual Studio project provided."); + return Result::Fail; + } + } + + // Only print something when there are errors + else if (std::strcmp(argv[i], "-q") == 0 || std::strcmp(argv[i], "--quiet") == 0) + mSettings.quiet = true; + + // Output relative paths + else if (std::strcmp(argv[i], "-rp") == 0 || std::strcmp(argv[i], "--relative-paths") == 0) + mSettings.relativePaths = true; + else if (std::strncmp(argv[i], "-rp=", 4) == 0 || std::strncmp(argv[i], "--relative-paths=", 17) == 0) { + mSettings.relativePaths = true; + if (argv[i][argv[i][3]=='='?4:17] != 0) { + std::string paths = argv[i]+(argv[i][3]=='='?4:17); + for (;;) { + const std::string::size_type pos = paths.find(';'); + if (pos == std::string::npos) { + mSettings.basePaths.emplace_back(Path::fromNativeSeparators(std::move(paths))); + break; } - } else { - printError("no paths specified for the '" + std::string(argv[i]) + "' option."); - return false; + mSettings.basePaths.emplace_back(Path::fromNativeSeparators(paths.substr(0, pos))); + paths.erase(0, pos + 1); } + } else { + mLogger.printError("no paths specified for the '" + std::string(argv[i]) + "' option."); + return Result::Fail; } + } + + // Report progress + else if (std::strcmp(argv[i], "--report-progress") == 0) { + mSettings.reportProgress = 10; + } + + else if (std::strncmp(argv[i], "--report-progress=", 18) == 0) { + if (!parseNumberArg(argv[i], 18, mSettings.reportProgress, true)) + return Result::Fail; + } - // Report progress - else if (std::strcmp(argv[i], "--report-progress") == 0) { - mSettings.reportProgress = true; + else if (std::strncmp(argv[i], "--report-type=", 14) == 0) { + const std::string typeStr = argv[i] + 14; + if (typeStr == "normal") { + mSettings.reportType = ReportType::normal; + } else if (typeStr == "autosar") { + mSettings.reportType = ReportType::autosar; + } else if (typeStr == "cert-c-2016") { + mSettings.reportType = ReportType::certC; + } else if (typeStr == "cert-cpp-2016") { + mSettings.reportType = ReportType::certCpp; + } else if (typeStr == "misra-c-2012") { + mSettings.reportType = ReportType::misraC2012; + } else if (typeStr == "misra-c-2023") { + mSettings.reportType = ReportType::misraC2023; + } else if (typeStr == "misra-c-2025") { + mSettings.reportType = ReportType::misraC2025; + } else if (typeStr == "misra-cpp-2008") { + mSettings.reportType = ReportType::misraCpp2008; + } else if (typeStr == "misra-cpp-2023") { + mSettings.reportType = ReportType::misraCpp2023; + } else { + mLogger.printError("Unknown report type \'" + typeStr + "\'"); + return Result::Fail; } + } + // Rule given at command line + else if (std::strncmp(argv[i], "--rule=", 7) == 0) { #ifdef HAVE_RULES - // Rule given at command line - else if (std::strncmp(argv[i], "--rule=", 7) == 0) { - Settings::Rule rule; - rule.pattern = 7 + argv[i]; - mSettings.rules.emplace_back(std::move(rule)); - } - - // Rule file - else if (std::strncmp(argv[i], "--rule-file=", 12) == 0) { - tinyxml2::XMLDocument doc; - if (doc.LoadFile(12+argv[i]) == tinyxml2::XML_SUCCESS) { - tinyxml2::XMLElement *node = doc.FirstChildElement(); - if (node && strcmp(node->Value(), "rules") == 0) - node = node->FirstChildElement("rule"); - for (; node && strcmp(node->Value(), "rule") == 0; node = node->NextSiblingElement()) { - Settings::Rule rule; - - const tinyxml2::XMLElement *tokenlist = node->FirstChildElement("tokenlist"); - if (tokenlist) - rule.tokenlist = tokenlist->GetText(); - - const tinyxml2::XMLElement *pattern = node->FirstChildElement("pattern"); - if (pattern) { - rule.pattern = pattern->GetText(); - } + Settings::Rule rule; + rule.pattern = 7 + argv[i]; - tinyxml2::XMLElement *message = node->FirstChildElement("message"); - if (message) { - const tinyxml2::XMLElement *severity = message->FirstChildElement("severity"); - if (severity) - rule.severity = Severity::fromString(severity->GetText()); + if (rule.pattern.empty()) { + mLogger.printError("no rule pattern provided."); + return Result::Fail; + } - const tinyxml2::XMLElement *id = message->FirstChildElement("id"); - if (id) - rule.id = id->GetText(); + std::string regex_err; + auto regex = Regex::create(rule.pattern, regex_err); + if (!regex) { + mLogger.printError("failed to compile rule pattern '" + rule.pattern + "' (" + regex_err + ")."); + return Result::Fail; + } + rule.regex = std::move(regex); + mSettings.rules.emplace_back(std::move(rule)); +#else + mLogger.printError("Option --rule cannot be used as Cppcheck has not been built with rules support."); + return Result::Fail; +#endif + } - const tinyxml2::XMLElement *summary = message->FirstChildElement("summary"); - if (summary) - rule.summary = summary->GetText() ? summary->GetText() : ""; + // Rule file + else if (std::strncmp(argv[i], "--rule-file=", 12) == 0) { +#ifdef HAVE_RULES + // TODO: improved error handling - wrong root node, etc. + // TODO: consume unused "version" attribute + const std::string ruleFile = argv[i] + 12; + tinyxml2::XMLDocument doc; + const tinyxml2::XMLError err = doc.LoadFile(ruleFile.c_str()); + if (err == tinyxml2::XML_SUCCESS) { + const tinyxml2::XMLElement *node = doc.FirstChildElement(); + // check if it is a single or multi rule configuration + if (node && strcmp(node->Value(), "rules") == 0) + node = node->FirstChildElement("rule"); + for (; node && strcmp(node->Value(), "rule") == 0; node = node->NextSiblingElement()) { + Settings::Rule rule; + + for (const tinyxml2::XMLElement *subnode = node->FirstChildElement(); subnode; subnode = subnode->NextSiblingElement()) { + const char * const subname = subnode->Name(); + const char * const subtext = subnode->GetText(); + if (std::strcmp(subname, "tokenlist") == 0) { + rule.tokenlist = empty_if_null(subtext); + } + else if (std::strcmp(subname, "pattern") == 0) { + rule.pattern = empty_if_null(subtext); + } + else if (std::strcmp(subname, "message") == 0) { + for (const tinyxml2::XMLElement *msgnode = subnode->FirstChildElement(); msgnode; msgnode = msgnode->NextSiblingElement()) { + const char * const msgname = msgnode->Name(); + const char * const msgtext = msgnode->GetText(); + if (std::strcmp(msgname, "severity") == 0) { + rule.severity = severityFromString(empty_if_null(msgtext)); + } + else if (std::strcmp(msgname, "id") == 0) { + rule.id = empty_if_null(msgtext); + } + else if (std::strcmp(msgname, "summary") == 0) { + rule.summary = empty_if_null(msgtext); + } + else { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - unknown element '" + msgname + "' encountered in 'message'."); + return Result::Fail; + } + } + } + else { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - unknown element '" + subname + "' encountered in 'rule'."); + return Result::Fail; } + } - if (!rule.pattern.empty()) - mSettings.rules.emplace_back(std::move(rule)); + if (rule.pattern.empty()) { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - a rule is lacking a pattern."); + return Result::Fail; } - } else { - printError("unable to load rule-file: " + std::string(12+argv[i])); - return false; - } - } -#endif - // show timing information.. - else if (std::strncmp(argv[i], "--showtime=", 11) == 0) { - const std::string showtimeMode = argv[i] + 11; - if (showtimeMode == "file") - mSettings.showtime = SHOWTIME_MODES::SHOWTIME_FILE; - else if (showtimeMode == "file-total") - mSettings.showtime = SHOWTIME_MODES::SHOWTIME_FILE_TOTAL; - else if (showtimeMode == "summary") - mSettings.showtime = SHOWTIME_MODES::SHOWTIME_SUMMARY; - else if (showtimeMode == "top5") - mSettings.showtime = SHOWTIME_MODES::SHOWTIME_TOP5; - else if (showtimeMode.empty()) - mSettings.showtime = SHOWTIME_MODES::SHOWTIME_NONE; - else { - printError("unrecognized showtime mode: \"" + showtimeMode + "\". Supported modes: file, file-total, summary, top5."); - return false; - } - } + if (rule.id.empty()) { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - a rule is lacking an id."); + return Result::Fail; + } - // --std - else if (std::strncmp(argv[i], "--std=", 6) == 0) { - const std::string std = argv[i] + 6; - // TODO: print error when standard is unknown - if (std::strncmp(std.c_str(), "c++", 3) == 0) { - mSettings.standards.cpp = Standards::getCPP(std); - } - else if (std::strncmp(std.c_str(), "c", 1) == 0) { - mSettings.standards.c = Standards::getC(std); - } - else { - printError("unknown --std value '" + std + "'"); - return false; - } - } + if (rule.tokenlist.empty()) { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - a rule is lacking a tokenlist."); + return Result::Fail; + } - else if (std::strncmp(argv[i], "--suppress=", 11) == 0) { - const std::string suppression = argv[i]+11; - const std::string errmsg(mSuppressions.addSuppressionLine(suppression)); - if (!errmsg.empty()) { - printError(errmsg); - return false; - } - } + if (rule.tokenlist != "normal" && rule.tokenlist != "define" && rule.tokenlist != "raw") { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - a rule is using the unsupported tokenlist '" + rule.tokenlist + "'."); + return Result::Fail; + } - // Filter errors - else if (std::strncmp(argv[i], "--suppressions-list=", 20) == 0) { - std::string filename = argv[i]+20; - std::ifstream f(filename); - if (!f.is_open()) { - std::string message("couldn't open the file: \""); - message += filename; - message += "\"."; - if (std::count(filename.cbegin(), filename.cend(), ',') > 0 || - std::count(filename.cbegin(), filename.cend(), '.') > 1) { - // If user tried to pass multiple files (we can only guess that) - // e.g. like this: --suppressions-list=a.txt,b.txt - // print more detailed error message to tell user how he can solve the problem - message += "\nIf you want to pass two files, you can do it e.g. like this:"; - message += "\n cppcheck --suppressions-list=a.txt --suppressions-list=b.txt file.cpp"; + std::string regex_err; + auto regex = Regex::create(rule.pattern, regex_err); + if (!regex) { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - pattern '" + rule.pattern + "' failed to compile (" + regex_err + ")."); + return Result::Fail; } + rule.regex = std::move(regex); - printError(message); - return false; - } - const std::string errmsg(mSuppressions.parseFile(f)); - if (!errmsg.empty()) { - printError(errmsg); - return false; + if (rule.severity == Severity::none) { + mLogger.printError("unable to load rule-file '" + ruleFile + "' - a rule has an invalid severity."); + return Result::Fail; + } + + mSettings.rules.emplace_back(std::move(rule)); } + } else { + mLogger.printError("unable to load rule-file '" + ruleFile + "' (" + tinyxml2::XMLDocument::ErrorIDToName(err) + ")."); + return Result::Fail; } +#else + mLogger.printError("Option --rule-file cannot be used as Cppcheck has not been built with rules support."); + return Result::Fail; +#endif + } - else if (std::strncmp(argv[i], "--suppress-xml=", 15) == 0) { - const char * filename = argv[i] + 15; - const std::string errmsg(mSuppressions.parseXmlFile(filename)); - if (!errmsg.empty()) { - printError(errmsg); - return false; - } + // Safety certified behavior + else if (std::strcmp(argv[i], "--safety") == 0) + mSettings.safety = true; + + // show timing information.. + else if (std::strncmp(argv[i], "--showtime=", 11) == 0) { + const std::string showtimeMode = argv[i] + 11; + if (showtimeMode == "file") + mSettings.showtime = ShowTime::FILE; + else if (showtimeMode == "file-total") + mSettings.showtime = ShowTime::FILE_TOTAL; + else if (showtimeMode == "summary") + mSettings.showtime = ShowTime::SUMMARY; + else if (showtimeMode == "top5_file") + mSettings.showtime = ShowTime::TOP5_FILE; + else if (showtimeMode == "top5_summary") + mSettings.showtime = ShowTime::TOP5_SUMMARY; + else if (showtimeMode == "none") + mSettings.showtime = ShowTime::NONE; + else if (showtimeMode.empty()) { + mLogger.printError("no mode provided for --showtime"); + return Result::Fail; } + else { + mLogger.printError("unrecognized --showtime mode: '" + showtimeMode + "'. Supported modes: file, file-total, summary, top5_file, top5_summary."); + return Result::Fail; + } + } - // TODO: deprecate "--template