forked from pfqgauxfb/code-analysis
commit
75553ebd31
@ -0,0 +1,79 @@
|
||||
---
|
||||
Checks: >
|
||||
*,
|
||||
-abseil-*,
|
||||
-altera-*,
|
||||
-android-*,
|
||||
-boost-*,
|
||||
-cert-*,
|
||||
-cppcoreguidelines-*,
|
||||
-darwin-*,
|
||||
-fuchsia-*,
|
||||
-google-*,
|
||||
-hicpp-*,
|
||||
-linuxkernel-*,
|
||||
-llvm-*,
|
||||
-llvmlibc-*,
|
||||
-mpi-*,
|
||||
-objc-*,
|
||||
-openmp-*,
|
||||
-zircon-*,
|
||||
cert-err34-c,
|
||||
google-explicit-constructor,
|
||||
cppcoreguidelines-rvalue-reference-param-not-moved,
|
||||
-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-auto,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-use-trailing-return-type,
|
||||
-performance-avoid-endl,
|
||||
-performance-enum-size,
|
||||
-performance-inefficient-string-concatenation,
|
||||
-performance-no-automatic-move,
|
||||
-performance-noexcept-swap,
|
||||
-portability-simd-intrinsics,
|
||||
-portability-std-allocator-const,
|
||||
-readability-avoid-const-params-in-decls,
|
||||
-readability-avoid-nested-conditional-operator,
|
||||
-readability-braces-around-statements,
|
||||
-readability-container-data-pointer,
|
||||
-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
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: '(cli|gui|lib|oss-fuzz|test|triage)\/[a-z]+\.h'
|
||||
CheckOptions:
|
||||
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
|
||||
value: '1'
|
||||
- key: readability-simplify-boolean-expr.SimplifyDeMorgan
|
||||
value: '0'
|
||||
@ -0,0 +1,8 @@
|
||||
exclude_paths:
|
||||
- addons/test/**
|
||||
- addons/y2038/test/*.c
|
||||
- htmlreport/example.cc
|
||||
- samples/**/bad.c
|
||||
- samples/**/bad.cpp
|
||||
- test/cfg/*.c
|
||||
- test/cfg/*.cpp
|
||||
@ -0,0 +1,19 @@
|
||||
## standard default enconding
|
||||
* text=auto
|
||||
|
||||
## UNIX specific files
|
||||
*.sh text eol=lf
|
||||
|
||||
## Windows specific files
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
*.vcxproj text eol=crlf
|
||||
*.vcxproj.filters text eol=crlf
|
||||
*.sln text eol=crlf
|
||||
*.wixproj text eol=crlf
|
||||
*.wxi text eol=crlf
|
||||
*.wxs text eol=crlf
|
||||
|
||||
## Binary resources
|
||||
*.pdf binary
|
||||
@ -0,0 +1,56 @@
|
||||
# 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:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
jobs:
|
||||
build_cygwin:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-2022]
|
||||
arch: [x64]
|
||||
include:
|
||||
- platform: 'x86_64'
|
||||
packages: |
|
||||
gcc-g++
|
||||
python3
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Cygwin
|
||||
uses: cygwin/cygwin-install-action@master
|
||||
with:
|
||||
platform: ${{ matrix.arch }}
|
||||
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
|
||||
|
||||
- name: Extra test for misra
|
||||
run: |
|
||||
cd %GITHUB_WORKSPACE%\addons\test
|
||||
..\..\cppcheck.exe --dump -DDUMMY --suppress=uninitvar --inline-suppr misra\misra-test.c --std=c89 --platform=unix64
|
||||
python3 ..\misra.py -verify misra\misra-test.c.dump
|
||||
..\..\cppcheck.exe --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 misra\misra-ctu-1-test.c misra\misra-ctu-2-test.c
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
# 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:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
jobs:
|
||||
build_mingw:
|
||||
strategy:
|
||||
matrix:
|
||||
# the MinGW installation in windows-2019 is supposed to be 8.1 but it is 12.2
|
||||
# the MinGW installation in windows-2022 is not including all necessary packages by default, so just use the older image instead - package versions are he same
|
||||
os: [windows-2019]
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false # use pre-installed
|
||||
install: >-
|
||||
mingw-w64-x86_64-lld
|
||||
mingw-w64-x86_64-ccache
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
# TODO: bail out on warning
|
||||
- name: Build cppcheck
|
||||
run: |
|
||||
export PATH="/mingw64/lib/ccache/bin:$PATH"
|
||||
# set RDYNAMIC to work around broken MinGW detection
|
||||
make VERBOSE=1 RDYNAMIC=-lshlwapi -j2 cppcheck
|
||||
env:
|
||||
LDFLAGS: -fuse-ld=lld # use lld for faster linking
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
export PATH="/mingw64/lib/ccache/bin:$PATH"
|
||||
# set RDYNAMIC to work around broken MinGW detection
|
||||
make VERBOSE=1 RDYNAMIC=-lshlwapi -j2 testrunner
|
||||
env:
|
||||
LDFLAGS: -fuse-ld=lld # use lld for faster linking
|
||||
|
||||
- name: Run test
|
||||
run: |
|
||||
export PATH="/mingw64/lib/ccache/bin:$PATH"
|
||||
# set RDYNAMIC to work around broken MinGW detection
|
||||
make VERBOSE=1 RDYNAMIC=-lshlwapi -j2 check
|
||||
env:
|
||||
LDFLAGS: -fuse-ld=lld # use lld for faster linking
|
||||
@ -0,0 +1,158 @@
|
||||
# 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-unixish-docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build_cmake:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
image: ["ubuntu:16.04", "ubuntu:18.04", "ubuntu:23.10"]
|
||||
include:
|
||||
- build_gui: false
|
||||
- image: "ubuntu:23.10"
|
||||
build_gui: true
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
# TODO: is this actually applied to the guest?
|
||||
env:
|
||||
# TODO: figure out why there are cache misses with PCH enabled
|
||||
CCACHE_SLOPPINESS: pch_defines,time_macros
|
||||
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.image, 'ubuntu')
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y cmake g++ make libxml2-utils libpcre3-dev
|
||||
|
||||
- name: Install missing software (gui) on latest ubuntu
|
||||
if: matrix.build_gui
|
||||
run: |
|
||||
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
|
||||
#
|
||||
# needs to be to fixated on 1.2.11 so it works with older images - see https://github.com/hendrikmuhs/ccache-action/issues/178
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ matrix.image }}
|
||||
|
||||
# tests require CMake 3.9 - ccache available
|
||||
- name: CMake build (no tests)
|
||||
if: matrix.image == 'ubuntu:16.04'
|
||||
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 --build . -- -j$(nproc)
|
||||
|
||||
- name: CMake build
|
||||
if: ${{ !matrix.build_gui && matrix.image != 'ubuntu:16.04' }}
|
||||
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)
|
||||
|
||||
- name: CMake build (with GUI)
|
||||
if: matrix.build_gui
|
||||
run: |
|
||||
cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DUSE_QT6=On -DWITH_QCHART=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
cmake --build cmake.output -- -j$(nproc)
|
||||
|
||||
- name: Run CMake test
|
||||
if: matrix.image != 'ubuntu:16.04'
|
||||
run: |
|
||||
cmake --build cmake.output --target check -- -j$(nproc)
|
||||
|
||||
build_make:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
image: ["ubuntu:16.04", "ubuntu:18.04", "ubuntu:23.10"]
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.image, 'ubuntu')
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y g++ make python3 libxml2-utils libpcre3-dev
|
||||
|
||||
# needs to be called after the package installation since
|
||||
# - it doesn't call "apt-get update"
|
||||
# - it doesn't support centos
|
||||
#
|
||||
# needs to be to fixated on 1.2.11 so it works with older images - see https://github.com/hendrikmuhs/ccache-action/issues/178
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
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 CXXFLAGS="-w"
|
||||
|
||||
- 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 CXXFLAGS="-w"
|
||||
|
||||
- name: Run test
|
||||
run: |
|
||||
make -j$(nproc) check HAVE_RULES=yes
|
||||
|
||||
# requires python3
|
||||
- name: Run extra tests
|
||||
run: |
|
||||
tools/generate_and_run_more_tests.sh
|
||||
|
||||
# requires which
|
||||
- name: Validate
|
||||
run: |
|
||||
make -j$(nproc) checkCWEEntries validateXML
|
||||
|
||||
- name: Test addons
|
||||
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
|
||||
|
||||
@ -0,0 +1,552 @@
|
||||
# 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-unixish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build_cmake_tinyxml2:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04, macos-12]
|
||||
include:
|
||||
- use_qt6: On
|
||||
- os: ubuntu-20.04
|
||||
use_qt6: Off
|
||||
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
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.os, 'ubuntu') && matrix.use_qt6 == 'Off'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libxml2-utils libtinyxml2-dev qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.os, 'ubuntu') && matrix.use_qt6 == 'On'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# qt6-tools-dev-tools for lprodump
|
||||
# qt6-l10n-tools for lupdate
|
||||
sudo apt-get install libxml2-utils libtinyxml2-dev 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 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 -DUSE_QT6=${{ matrix.use_qt6 }} -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=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 -DUSE_QT6=On -DWITH_QCHART=On -DUSE_BUNDLED_TINYXML2=Off -DCMAKE_DISABLE_PRECOMPILE_HEADERS=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)
|
||||
run: |
|
||||
cmake --build cmake.output.tinyxml2 --target check -- -j$(nproc)
|
||||
|
||||
build_cmake:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04, macos-12]
|
||||
include:
|
||||
- use_qt6: On
|
||||
- os: ubuntu-20.04
|
||||
use_qt6: Off
|
||||
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
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.os, 'ubuntu') && matrix.use_qt6 == 'Off'
|
||||
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'
|
||||
with:
|
||||
version: 13
|
||||
platform: x64
|
||||
|
||||
- name: Select compiler
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
echo "CXX=g++-13" >> $GITHUB_ENV
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.os, 'ubuntu') && matrix.use_qt6 == 'On'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# qt6-tools-dev-tools for lprodump
|
||||
# qt6-l10n-tools for lupdate
|
||||
sudo apt-get install libxml2-utils 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: CMake build 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 -DUSE_QT6=${{ matrix.use_qt6 }} -DWITH_QCHART=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
cmake --build cmake.output -- -j$(nproc)
|
||||
|
||||
- name: CMake build 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 -DUSE_QT6=On -DWITH_QCHART=On -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DQt6_DIR=$(brew --prefix qt@6)/lib/cmake/Qt6
|
||||
cmake --build cmake.output -- -j$(nproc)
|
||||
|
||||
- name: Run CMake test
|
||||
run: |
|
||||
cmake --build cmake.output --target check -- -j$(nproc)
|
||||
|
||||
- name: Run CTest
|
||||
run: |
|
||||
pushd cmake.output
|
||||
ctest --output-on-failure -j$(nproc)
|
||||
|
||||
build_uchar:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04, macos-12]
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
# coreutils contains "nproc"
|
||||
- name: Install missing software on macos
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: |
|
||||
brew install coreutils
|
||||
|
||||
- name: Build with Unsigned char
|
||||
run: |
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
make -j$(nproc) CXXFLAGS=-funsigned-char testrunner
|
||||
|
||||
- name: Test with Unsigned char
|
||||
run: |
|
||||
./testrunner TestSymbolDatabase
|
||||
|
||||
build_mathlib:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04, macos-12]
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
# coreutils contains "nproc"
|
||||
- name: Install missing software on macos
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: |
|
||||
brew install coreutils
|
||||
|
||||
- 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
|
||||
|
||||
- name: Test with TEST_MATHLIB_VALUE
|
||||
run: |
|
||||
make -j$(nproc) CPPFLAGS=-DTEST_MATHLIB_VALUE check
|
||||
|
||||
check_nonneg:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04, macos-12]
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# coreutils contains "g++" (default is "c++") and "nproc"
|
||||
- name: Install missing software on macos
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: |
|
||||
brew install coreutils
|
||||
|
||||
- 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
|
||||
|
||||
build_qmake:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
# no longer build with qmake on MacOS as brew might lack pre-built Qt5 packages causing the step to run for hours
|
||||
os: [ubuntu-20.04, ubuntu-22.04]
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install qtbase5-dev qttools5-dev libqt5charts5-dev qtchooser
|
||||
|
||||
# coreutils contains "nproc"
|
||||
- name: Install missing software on macos
|
||||
if: contains(matrix.os, 'macos')
|
||||
run: |
|
||||
brew install coreutils qt@5
|
||||
# expose qmake
|
||||
brew link qt@5 --force
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- name: Build GUI
|
||||
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)
|
||||
|
||||
# TODO: binaries are in a different location on macos
|
||||
- name: Build and Run GUI tests
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
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)
|
||||
|
||||
build:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04, macos-12]
|
||||
fail-fast: false # Prefer quick result
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
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
|
||||
|
||||
# packages for strict cfg checks
|
||||
- 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
|
||||
|
||||
# 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
|
||||
|
||||
- name: Install missing Python packages
|
||||
run: |
|
||||
python3 -m pip install pip --upgrade
|
||||
python3 -m pip install pytest
|
||||
python3 -m pip install pytest-timeout
|
||||
|
||||
- name: Build cppcheck
|
||||
run: |
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
make -j$(nproc) 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
|
||||
|
||||
- name: Run test
|
||||
run: |
|
||||
make -j$(nproc) check HAVE_RULES=yes
|
||||
|
||||
# requires "gnu-sed" installed on macos
|
||||
- name: Run extra tests
|
||||
run: |
|
||||
tools/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 -Werror --strict-markers -vv
|
||||
cd ../../..
|
||||
ln -s cppcheck 'cpp check'
|
||||
cd 'cpp check/test/cli'
|
||||
python3 -m pytest -Werror --strict-markers -vv
|
||||
|
||||
# do not use pushd in this step since we go below the working directory
|
||||
- name: Run test/cli (-j2)
|
||||
run: |
|
||||
cd test/cli
|
||||
python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_J: 2
|
||||
|
||||
# do not use pushd in this step since we go below the working directory
|
||||
- name: Run test/cli (--clang)
|
||||
if: false
|
||||
run: |
|
||||
cd test/cli
|
||||
python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_CLANG: clang
|
||||
|
||||
- name: Run cfg tests
|
||||
if: matrix.os != 'ubuntu-22.04'
|
||||
run: |
|
||||
make -j$(nproc) checkcfg
|
||||
|
||||
- name: Run cfg tests (strict)
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
make -j$(nproc) checkcfg
|
||||
env:
|
||||
STRICT: 1
|
||||
|
||||
- name: Run --dump test
|
||||
run: |
|
||||
./cppcheck test/testpreprocessor.cpp --dump
|
||||
xmllint --noout test/testpreprocessor.cpp.dump
|
||||
|
||||
- name: Validate
|
||||
run: |
|
||||
make -j$(nproc) checkCWEEntries validateXML
|
||||
|
||||
- name: Test Signalhandler
|
||||
run: |
|
||||
cmake -S . -B cmake.output.signal -G "Unix Makefiles" -DBUILD_TESTS=On
|
||||
cmake --build cmake.output.signal --target test-signalhandler -- -j$(nproc)
|
||||
cp cmake.output.signal/bin/test-s* .
|
||||
python3 -m pytest -Werror --strict-markers -vv test/signal/test-signalhandler.py
|
||||
|
||||
# no unix backtrace support on MacOs
|
||||
- name: Test Stacktrace
|
||||
if: contains(matrix.os, 'ubuntu')
|
||||
run: |
|
||||
cmake -S . -B cmake.output.signal -G "Unix Makefiles" -DBUILD_TESTS=On
|
||||
cmake --build cmake.output.signal --target test-stacktrace -- -j$(nproc)
|
||||
cp cmake.output.signal/bin/test-s* .
|
||||
python3 -m pytest -Werror --strict-markers -vv test/signal/test-stacktrace.py
|
||||
|
||||
# TODO: move to scriptcheck.yml so these are tested with all Python versions?
|
||||
- name: Test addons
|
||||
run: |
|
||||
./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
|
||||
python3 ../misra.py -verify misra/misra-test.cpp.dump
|
||||
python3 ../misra.py --rule-texts=misra/misra2012_rules_dummy_ascii.txt -verify misra/misra-test.cpp.dump
|
||||
python3 ../misra.py --rule-texts=misra/misra2012_rules_dummy_utf8.txt -verify misra/misra-test.cpp.dump
|
||||
python3 ../misra.py --rule-texts=misra/misra2012_rules_dummy_windows1250.txt -verify misra/misra-test.cpp.dump
|
||||
../../cppcheck --addon=misra --enable=style --platform=avr8 --error-exitcode=1 misra/misra-test-avr8.c
|
||||
../../cppcheck --dump misc-test.cpp
|
||||
python3 ../misc.py -verify misc-test.cpp.dump
|
||||
../../cppcheck --dump naming_test.c
|
||||
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
|
||||
|
||||
- name: Build democlient
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
run: |
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- 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: 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 -w -DHAVE_BOOST" MATCHCOMPILER=yes VERIFY=1
|
||||
|
||||
# TODO: update to Qt6
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -S . -B cmake.output -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DWITH_QCHART=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 dependencies
|
||||
run: |
|
||||
# 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_summary -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive"
|
||||
cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2"
|
||||
ec=0
|
||||
|
||||
# TODO: add --check-config
|
||||
|
||||
# early exit
|
||||
if [ $ec -eq 1 ]; then
|
||||
exit $ec
|
||||
fi
|
||||
|
||||
# self check simplecpp
|
||||
./cppcheck $selfcheck_options externals/simplecpp || ec=1
|
||||
# self check lib/cli
|
||||
mkdir b1
|
||||
./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json cli lib || ec=1
|
||||
# check gui with qt settings
|
||||
mkdir b2
|
||||
./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b2 -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 || ec=1
|
||||
# self check test and tools
|
||||
./cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1
|
||||
# triage
|
||||
./cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=67 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1
|
||||
exit $ec
|
||||
@ -0,0 +1,227 @@
|
||||
# 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:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
# TODO: choose/add a step to bail out on compiler warnings (maybe even the release build)
|
||||
|
||||
jobs:
|
||||
|
||||
build_qt:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-2019, windows-2022]
|
||||
qt_ver: [5.15.2, 6.7.0]
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Visual Studio environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: Install Qt ${{ matrix.qt_ver }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ matrix.qt_ver }}
|
||||
modules: 'qtcharts'
|
||||
cache: true
|
||||
|
||||
- name: Build GUI release (qmake)
|
||||
if: startsWith(matrix.qt_ver, '5')
|
||||
run: |
|
||||
cd gui || exit /b !errorlevel!
|
||||
qmake HAVE_QCHART=yes || exit /b !errorlevel!
|
||||
nmake release || exit /b !errorlevel!
|
||||
env:
|
||||
CL: /MP
|
||||
|
||||
- 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!
|
||||
|
||||
- name: Build GUI release (CMake)
|
||||
if: startsWith(matrix.qt_ver, '6')
|
||||
run: |
|
||||
cmake -S . -B build -DBUILD_GUI=On -DUSE_QT6=On -DWITH_QCHART=On || exit /b !errorlevel!
|
||||
cmake --build build --target cppcheck-gui || exit /b !errorlevel!
|
||||
|
||||
# TODO: deploy with CMake/Qt6
|
||||
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-2019, windows-2022]
|
||||
config: [debug, release]
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
env:
|
||||
# see https://www.pcre.org/original/changelog.txt
|
||||
PCRE_VERSION: 8.45
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python 3.12
|
||||
if: matrix.config == 'release'
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
check-latest: true
|
||||
|
||||
- name: Set up Visual Studio environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: x64
|
||||
|
||||
- name: Cache PCRE
|
||||
id: cache-pcre
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
externals\pcre.h
|
||||
externals\pcre.lib
|
||||
externals\pcre64.lib
|
||||
key: pcre-${{ env.PCRE_VERSION }}-x64-bin-win
|
||||
|
||||
- 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: |
|
||||
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!
|
||||
nmake || exit /b !errorlevel!
|
||||
copy pcre.h ..\externals || 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!
|
||||
python -m pip install pytest-timeout || exit /b !errorlevel!
|
||||
|
||||
- name: Run CMake
|
||||
if: false # TODO: enable
|
||||
run: |
|
||||
cmake -S . -B build -DBUILD_TESTS=On || exit /b !errorlevel!
|
||||
|
||||
- name: Build CLI debug configuration using MSBuild
|
||||
if: matrix.config == 'debug'
|
||||
run: |
|
||||
:: cmake --build build --target check --config Debug || exit /b !errorlevel!
|
||||
msbuild -m cppcheck.sln /p:Configuration=Debug-PCRE;Platform=x64 -maxcpucount || exit /b !errorlevel!
|
||||
|
||||
- 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: |
|
||||
:: cmake --build build --target check --config Release || exit /b !errorlevel!
|
||||
msbuild -m cppcheck.sln /p:Configuration=Release-PCRE;Platform=x64 -maxcpucount || exit /b !errorlevel!
|
||||
|
||||
- name: Run Release test
|
||||
if: matrix.config == 'release'
|
||||
run: .\bin\testrunner.exe || exit /b !errorlevel!
|
||||
|
||||
- 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!
|
||||
|
||||
- name: Run test/cli
|
||||
if: matrix.config == 'release'
|
||||
run: |
|
||||
cd test/cli || exit /b !errorlevel!
|
||||
python -m pytest -Werror --strict-markers -vv || exit /b !errorlevel!
|
||||
|
||||
- name: Run test/cli (-j2)
|
||||
if: matrix.config == 'release'
|
||||
run: |
|
||||
cd test/cli || exit /b !errorlevel!
|
||||
python -m pytest -Werror --strict-markers -vv || exit /b !errorlevel!
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_J: 2
|
||||
|
||||
# TODO: install clang
|
||||
- name: Run test/cli (--clang)
|
||||
if: false # matrix.config == 'release'
|
||||
run: |
|
||||
cd test/cli || exit /b !errorlevel!
|
||||
python -m pytest -Werror --strict-markers -vv || exit /b !errorlevel!
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_CLANG: clang
|
||||
|
||||
- name: Test addons
|
||||
if: matrix.config == 'release'
|
||||
run: |
|
||||
.\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!
|
||||
cd addons\test
|
||||
rem We'll force C89 standard to enable an additional verification for
|
||||
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!
|
||||
python3 ..\misra.py -verify misra\misra-test.cpp.dump || exit /b !errorlevel!
|
||||
python3 ..\misra.py --rule-texts=misra\misra2012_rules_dummy_ascii.txt -verify misra\misra-test.cpp.dump || exit /b !errorlevel!
|
||||
python3 ..\misra.py --rule-texts=misra\misra2012_rules_dummy_utf8.txt -verify misra\misra-test.cpp.dump || exit /b !errorlevel!
|
||||
python3 ..\misra.py --rule-texts=misra\misra2012_rules_dummy_windows1250.txt -verify misra\misra-test.cpp.dump || exit /b !errorlevel!
|
||||
..\..\cppcheck --addon=misra --enable=style --platform=avr8 --error-exitcode=1 misra\misra-test-avr8.c || exit /b !errorlevel!
|
||||
..\..\cppcheck --dump misc-test.cpp || exit /b !errorlevel!
|
||||
python3 ..\misc.py -verify misc-test.cpp.dump || exit /b !errorlevel!
|
||||
..\..\cppcheck --dump naming_test.c || exit /b !errorlevel!
|
||||
rem TODO: fix this - does not fail on Linux
|
||||
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!
|
||||
|
||||
- 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!
|
||||
@ -0,0 +1,140 @@
|
||||
# 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: address sanitizer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.15.2
|
||||
ASAN_OPTIONS: detect_stack_use_after_return=1
|
||||
# TODO: figure out why there are cache misses with PCH enabled
|
||||
CCACHE_SLOPPINESS: pch_defines,time_macros
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
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 libxml2-utils
|
||||
|
||||
- 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 18
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
if: false
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
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
|
||||
|
||||
# TODO: disable all warnings
|
||||
- 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
|
||||
env:
|
||||
CC: clang-18
|
||||
CXX: clang++-18
|
||||
|
||||
- name: Build cppcheck
|
||||
run: |
|
||||
cmake --build cmake.output --target cppcheck -- -j $(nproc)
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
cmake --build cmake.output --target testrunner -- -j $(nproc)
|
||||
|
||||
- name: Run tests
|
||||
run: ./cmake.output/bin/testrunner
|
||||
|
||||
- name: Run cfg tests
|
||||
run: |
|
||||
cmake --build cmake.output --target checkcfg -- -j $(nproc)
|
||||
|
||||
# TODO: we should use CTest instead to parallelize tests but the start-up overhead will slow things down
|
||||
- name: Run CTest
|
||||
if: false
|
||||
run: |
|
||||
ctest --test-dir cmake.output --output-on-failure -j$(nproc)
|
||||
|
||||
- name: Run test/cli
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
|
||||
- name: Run test/cli (-j2)
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_J: 2
|
||||
|
||||
- name: Run test/cli (--clang)
|
||||
if: false
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_CLANG: clang
|
||||
|
||||
- name: Generate dependencies
|
||||
if: false
|
||||
run: |
|
||||
# make sure auto-generated GUI files exist
|
||||
make -C cmake.output autogen
|
||||
make -C cmake.output gui-build-deps triage-build-ui-deps
|
||||
|
||||
# TODO: this is currently way too slow (~60 minutes) to enable it
|
||||
# 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
|
||||
if: false
|
||||
run: |
|
||||
selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5_summary -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive"
|
||||
cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2"
|
||||
ec=0
|
||||
./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json cli lib || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1
|
||||
exit $ec
|
||||
@ -0,0 +1,60 @@
|
||||
# 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:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
convert_via_pandoc:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- run: |
|
||||
mkdir output
|
||||
|
||||
- uses: docker://pandoc/latex:2.9
|
||||
with:
|
||||
args: --output=output/manual.html man/manual.md
|
||||
|
||||
- uses: docker://pandoc/latex:2.9
|
||||
with:
|
||||
args: --output=output/manual.pdf man/manual.md
|
||||
|
||||
- uses: docker://pandoc/latex:2.9
|
||||
with:
|
||||
args: --output=output/manual-premium.pdf man/manual-premium.md
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: output
|
||||
path: output
|
||||
|
||||
manpage:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- 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@v3
|
||||
with:
|
||||
name: cppcheck.1
|
||||
path: cppcheck.1
|
||||
@ -0,0 +1,34 @@
|
||||
# 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
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'cppcheck'
|
||||
dry-run: false
|
||||
language: c++
|
||||
- name: Run Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'cppcheck'
|
||||
fuzz-seconds: 300
|
||||
dry-run: false
|
||||
language: c++
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
||||
@ -0,0 +1,73 @@
|
||||
# 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: clang-tidy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.7.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- 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
|
||||
|
||||
- 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 18
|
||||
sudo apt-get install -y clang-tidy-18
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
cache: true
|
||||
|
||||
- name: Verify clang-tidy configuration
|
||||
run: |
|
||||
clang-tidy-18 --verify-config
|
||||
|
||||
- name: Prepare CMake
|
||||
run: |
|
||||
cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=On -DUSE_QT6=On -DWITH_QCHART=On -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On -DCPPCHK_GLIBCXX_DEBUG=Off
|
||||
env:
|
||||
CC: clang-18
|
||||
CXX: clang++-18
|
||||
|
||||
- name: Prepare CMake dependencies
|
||||
run: |
|
||||
# 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
|
||||
run: |
|
||||
cmake --build cmake.output --target run-clang-tidy 2> /dev/null
|
||||
@ -0,0 +1,56 @@
|
||||
# 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:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['cpp', 'python']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- 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
|
||||
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: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@ -0,0 +1,70 @@
|
||||
# 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: Coverage
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
# FIXME: disabled because the tokenless upload suddenly started to permanently fail
|
||||
if: false # ${{ github.repository_owner == 'danmar' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ runner.os }}
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libxml2-utils lcov
|
||||
|
||||
- name: Install missing Python packages on ubuntu
|
||||
run: |
|
||||
python -m pip install pip --upgrade
|
||||
python -m pip install lcov_cobertura
|
||||
|
||||
- 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
|
||||
|
||||
- name: Run instrumented tests
|
||||
run: |
|
||||
./testrunner
|
||||
test/cfg/runtests.sh
|
||||
|
||||
- name: Generate coverage report
|
||||
run: |
|
||||
gcov lib/*.cpp -o lib/
|
||||
lcov --directory ./ --capture --output-file lcov_tmp.info -b ./
|
||||
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
|
||||
with:
|
||||
name: Coverage results
|
||||
path: coverage_report
|
||||
|
||||
- uses: codecov/codecov-action@v3
|
||||
with:
|
||||
# token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
|
||||
# file: ./coverage.xml # optional
|
||||
flags: unittests # optional
|
||||
name: ${{ github.repository }} # optional
|
||||
fail_ci_if_error: true # optional (default = false):
|
||||
@ -0,0 +1,39 @@
|
||||
# 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
|
||||
- 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
|
||||
@ -0,0 +1,44 @@
|
||||
# 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/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-22.04 # run on the latest image only
|
||||
|
||||
env:
|
||||
PREMIUM_VERSION: 24.2.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Download cppcheckpremium
|
||||
run: |
|
||||
wget https://files.cppchecksolutions.com/${{ env.PREMIUM_VERSION }}/ubuntu-22.04/cppcheckpremium-${{ env.PREMIUM_VERSION }}-amd64.tar.gz
|
||||
tar xzf cppcheckpremium-${{ env.PREMIUM_VERSION }}-amd64.tar.gz
|
||||
|
||||
- name: Generate a license file
|
||||
run: |
|
||||
echo cppcheck > cppcheck.lic
|
||||
echo 241231 >> cppcheck.lic
|
||||
echo 80000 >> cppcheck.lic
|
||||
echo 53b72a908d7aeeee >> cppcheck.lic
|
||||
echo path:lib >> cppcheck.lic
|
||||
|
||||
- name: Check
|
||||
run: |
|
||||
cppcheckpremium-${{ env.PREMIUM_VERSION }}/premiumaddon --check-loc-license cppcheck.lic > cppcheck-premium-loc
|
||||
cppcheckpremium-${{ env.PREMIUM_VERSION }}/cppcheck -j$(nproc) -D__GNUC__ -D__CPPCHECK__ --suppressions-list=cppcheckpremium-suppressions --platform=unix64 --enable=style --premium=misra-c++-2008 --premium=cert-c++-2016 --inline-suppr --error-exitcode=1 lib
|
||||
@ -0,0 +1,47 @@
|
||||
# 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: format
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Cache uncrustify
|
||||
uses: actions/cache@v3
|
||||
id: cache-uncrustify
|
||||
with:
|
||||
path: |
|
||||
~/uncrustify
|
||||
key: ${{ runner.os }}-uncrustify
|
||||
|
||||
- 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
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build -- -j$(nproc) -s
|
||||
mkdir ~/uncrustify
|
||||
cd build && cp uncrustify ~/uncrustify/
|
||||
|
||||
- name: Uncrustify check
|
||||
run: |
|
||||
~/uncrustify/uncrustify -c .uncrustify.cfg -l CPP --no-backup --replace */*.cpp */*.h
|
||||
git diff
|
||||
git diff | diff - /dev/null &> /dev/null
|
||||
@ -0,0 +1,187 @@
|
||||
# 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: include-what-you-use
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
iwyu:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
image: ["archlinux:latest"] # "opensuse/tumbleweed:latest" / "fedora:latest" / "debian:unstable" / "archlinux:latest"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ github.repository_owner == 'danmar' }}
|
||||
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.7.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install missing software on debian/ubuntu
|
||||
if: contains(matrix.image, 'debian')
|
||||
run: |
|
||||
apt-get update
|
||||
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 clang pcre --noconfirm
|
||||
pacman -S libglvnd --noconfirm # fixes missing dependency for Qt in CMake
|
||||
pacman-key --init
|
||||
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
|
||||
pacman -Sy
|
||||
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 iwyu
|
||||
ln -s iwyu_tool.py /usr/bin/iwyu_tool
|
||||
|
||||
- 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
|
||||
# fixes error during Qt installation
|
||||
# /__w/cppcheck/Qt/6.7.0/gcc_64/bin/qmake: error while loading shared libraries: libgthread-2.0.so.0: cannot open shared object file: No such file or directory
|
||||
zypper install -y libgthread-2_0-0
|
||||
ln -s iwyu_tool.py /usr/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@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
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 -DUSE_QT6=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 -DEXTERNALS_AS_SYSTEM=On
|
||||
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 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: iwyu_tool
|
||||
run: |
|
||||
PWD=$(pwd)
|
||||
# -isystem/usr/lib/clang/17/include
|
||||
iwyu_tool -p cmake.output -j $(nproc) -- -w -Xiwyu --max_line_length=1024 -Xiwyu --comment_style=long -Xiwyu --quoted_includes_first -Xiwyu --update_comments > iwyu.log
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: Compilation Database
|
||||
path: ./cmake.output/compile_commands.json
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: Logs (include-what-you-use)
|
||||
path: ./*.log
|
||||
|
||||
clang-include-cleaner:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
if: ${{ github.repository_owner == 'danmar' }}
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.7.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install missing software
|
||||
run: |
|
||||
sudo apt-get update
|
||||
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 18
|
||||
sudo apt-get install -y clang-tools-18
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
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 -DUSE_QT6=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 -DEXTERNALS_AS_SYSTEM=On
|
||||
env:
|
||||
CC: clang-18
|
||||
CXX: clang++-18
|
||||
|
||||
- name: Prepare CMake dependencies
|
||||
run: |
|
||||
# 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 $PWD/gui -maxdepth 1 -name "*.cpp" | xargs -t -n 1 clang-include-cleaner-18 --print=changes --extra-arg=-w -p cmake.output > clang-include-cleaner.log 2>&1
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Logs (clang-include-cleaner)
|
||||
path: ./*.log
|
||||
@ -0,0 +1,168 @@
|
||||
# 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:
|
||||
push:
|
||||
tags:
|
||||
- '2.*'
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
|
||||
runs-on: windows-2022
|
||||
if: ${{ github.repository_owner == 'danmar' }}
|
||||
|
||||
env:
|
||||
# see https://www.pcre.org/original/changelog.txt
|
||||
PCRE_VERSION: 8.45
|
||||
QT_VERSION: 5.15.2
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- 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: |
|
||||
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!
|
||||
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!
|
||||
|
||||
# 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
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
tools: 'tools_opensslv3_x64'
|
||||
cache: true
|
||||
|
||||
- name: Create .qm
|
||||
run: |
|
||||
cd gui || exit /b !errorlevel!
|
||||
lupdate gui.pro -no-obsolete || exit /b !errorlevel!
|
||||
lrelease gui.pro -removeidentical || exit /b !errorlevel!
|
||||
|
||||
- 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!
|
||||
env:
|
||||
CL: /MP
|
||||
|
||||
- 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!
|
||||
|
||||
# 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: 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!
|
||||
|
||||
- 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!
|
||||
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!
|
||||
xcopy /s gui\help win_installer\files\help || exit /b !errorlevel!
|
||||
del win_installer\files\translations\*.qm || exit /b !errorlevel!
|
||||
move gui\*.qm win_installer\files\translations || 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!
|
||||
|
||||
- name: Build Installer
|
||||
run: |
|
||||
cd win_installer || exit /b !errorlevel!
|
||||
REM Read ProductVersion
|
||||
for /f "tokens=4 delims= " %%a in ('find "ProductVersion" productInfo.wxi') do set PRODUCTVER=%%a
|
||||
REM Remove double quotes
|
||||
set PRODUCTVER=%PRODUCTVER:"=%
|
||||
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
|
||||
with:
|
||||
name: installer
|
||||
path: win_installer/Build/
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: deploy
|
||||
path: win_installer\files
|
||||
|
||||
- name: Clean up deploy
|
||||
run: |
|
||||
del win_installer\files\addons\*.dll || 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\bearer || 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\printsupport || exit /b !errorlevel!
|
||||
rmdir /s /q win_installer\files\sqldrivers || 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\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\Qt5Svg.dll || exit /b !errorlevel!
|
||||
del win_installer\files\vc_redist.x64.exe || exit /b !errorlevel!
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: portable
|
||||
path: win_installer\files
|
||||
@ -0,0 +1,200 @@
|
||||
# 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: scriptcheck
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
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
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ runner.os }}
|
||||
|
||||
- name: Cache Cppcheck
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cppcheck
|
||||
key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }}
|
||||
|
||||
- name: build cppcheck
|
||||
run: |
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
make -j$(nproc) -s CXXFLAGS="-w"
|
||||
strip -s ./cppcheck
|
||||
|
||||
scriptcheck:
|
||||
|
||||
needs: build
|
||||
# 'ubuntu-22.04' removes Python 2.7, 3.5 and 3.6 so keep the previous LTS version
|
||||
# 'ubutunu-20.04' no longer works on 2.7 - TODO: re-added in a different way or remove support for it?
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12']
|
||||
include:
|
||||
- python-version: '3.12'
|
||||
python-latest: true
|
||||
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Restore Cppcheck
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: cppcheck
|
||||
key: ${{ runner.os }}-scriptcheck-cppcheck-${{ github.sha }}
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
|
||||
- name: Install missing software on ubuntu
|
||||
run: |
|
||||
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)
|
||||
# ERROR: No matching distribution found for shellcheck
|
||||
sudo apt-get install shellcheck
|
||||
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 unittest2
|
||||
python -m pip install pytest
|
||||
python -m pip install pygments
|
||||
python -m pip install requests
|
||||
python -m pip install psutil
|
||||
|
||||
- name: run Shellcheck
|
||||
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-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
|
||||
|
||||
- name: check .json files
|
||||
if: matrix.python-latest
|
||||
run: |
|
||||
find . -name '*.json' | xargs -n 1 python -m json.tool > /dev/null
|
||||
|
||||
- name: Validate
|
||||
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
|
||||
python -m py_compile htmlreport/cppcheck-htmlreport
|
||||
python -m py_compile htmlreport/*.py
|
||||
python -m py_compile tools/*.py
|
||||
|
||||
- name: compile addons
|
||||
run: |
|
||||
python -m compileall ./addons
|
||||
|
||||
- name: test matchcompiler
|
||||
run: |
|
||||
python tools/test_matchcompiler.py
|
||||
|
||||
# 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 addons/test
|
||||
env:
|
||||
PYTHONPATH: ./addons
|
||||
|
||||
- name: test addons
|
||||
if: matrix.python-version != '3.9' && matrix.python-version != '3.10'
|
||||
run: |
|
||||
python -m pytest -Werror --strict-markers -vv addons/test
|
||||
env:
|
||||
PYTHONPATH: ./addons
|
||||
|
||||
- name: test htmlreport
|
||||
run: |
|
||||
htmlreport/test_htmlreport.py
|
||||
cd htmlreport
|
||||
./check.sh
|
||||
|
||||
- name: test reduce
|
||||
run: |
|
||||
python -m pytest -Werror --strict-markers -vv tools/reduce_test.py
|
||||
env:
|
||||
PYTHONPATH: ./tools
|
||||
|
||||
- name: test donate_cpu_lib
|
||||
if: matrix.python-version != '2.7'
|
||||
run: |
|
||||
python -m pytest -Werror --strict-markers -vv tools/donate_cpu_lib_test.py
|
||||
env:
|
||||
PYTHONPATH: ./tools
|
||||
|
||||
- name: test donate_cpu_server
|
||||
if: matrix.python-version != '2.7'
|
||||
run: |
|
||||
python -m pytest -Werror --strict-markers -vv tools/donate_cpu_server_test.py
|
||||
env:
|
||||
PYTHONPATH: ./tools
|
||||
|
||||
dmake:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, macos-12, windows-2022]
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: run dmake
|
||||
run: |
|
||||
make -j2 CXXFLAGS="-w" run-dmake
|
||||
|
||||
- name: check diff
|
||||
run: |
|
||||
git diff --exit-code
|
||||
@ -0,0 +1,135 @@
|
||||
# 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: selfcheck
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 6.7.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install missing software
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libboost-container-dev
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ runner.os }}
|
||||
|
||||
- name: Install missing software
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-14 valgrind
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
cache: true
|
||||
|
||||
# TODO: cache this - perform same build as for the other self check
|
||||
- name: Self check (build)
|
||||
run: |
|
||||
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
|
||||
env:
|
||||
CC: clang-14
|
||||
CXX: clang++-14
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
cmake -S . -B cmake.output -G "Unix Makefiles" -DHAVE_RULES=On -DBUILD_TESTS=On -DBUILD_GUI=ON -DUSE_QT6=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On
|
||||
|
||||
- name: Generate dependencies
|
||||
run: |
|
||||
# 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 -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=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr
|
||||
env:
|
||||
DISABLE_VALUEFLOW: 1
|
||||
UNUSEDFUNCTION_ONLY: 1
|
||||
|
||||
# the following steps are duplicated from above since setting up the build node in a parallel step takes longer than the actual steps
|
||||
- name: CMake (no test)
|
||||
run: |
|
||||
cmake -S . -B cmake.output.notest -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
|
||||
|
||||
- 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 -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=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --enable=unusedFunction --exception-handling -rp=. --project=cmake.output.notest/compile_commands.json --suppressions-list=.selfcheck_unused_suppressions --inline-suppr
|
||||
env:
|
||||
DISABLE_VALUEFLOW: 1
|
||||
UNUSEDFUNCTION_ONLY: 1
|
||||
|
||||
- name: Fetch corpus
|
||||
run: |
|
||||
wget https://github.com/danmar/cppcheck/archive/refs/tags/2.8.tar.gz
|
||||
tar xvf 2.8.tar.gz
|
||||
|
||||
- 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 -DUSE_QT6=On -DWITH_QCHART=ON -DENABLE_CHECK_INTERNAL=On -DCMAKE_GLOBAL_AUTOGEN_TARGET=On
|
||||
|
||||
- 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 -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=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --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)
|
||||
cat callgrind.log
|
||||
callgrind_annotate --auto=no > callgrind.annotated.log
|
||||
head -50 callgrind.annotated.log
|
||||
env:
|
||||
DISABLE_VALUEFLOW: 1
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Callgrind Output
|
||||
path: ./callgrind.*
|
||||
@ -0,0 +1,142 @@
|
||||
# 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: thread sanitizer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.15.2
|
||||
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
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
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 libxml2-utils
|
||||
|
||||
- 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 18
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
if: false
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
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
|
||||
|
||||
- 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 -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
|
||||
env:
|
||||
CC: clang-18
|
||||
CXX: clang++-18
|
||||
|
||||
- name: Build cppcheck
|
||||
run: |
|
||||
cmake --build cmake.output --target cppcheck -- -j $(nproc)
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
cmake --build cmake.output --target testrunner -- -j $(nproc)
|
||||
|
||||
- name: Run tests
|
||||
run: ./cmake.output/bin/testrunner
|
||||
|
||||
- name: Run cfg tests
|
||||
run: |
|
||||
cmake --build cmake.output --target checkcfg -- -j $(nproc)
|
||||
|
||||
# TODO: we should use CTest instead to parallelize tests but the start-up overhead will slow things down
|
||||
- name: Run CTest
|
||||
if: false
|
||||
run: |
|
||||
ctest --test-dir cmake.output --output-on-failure -j$(nproc)
|
||||
|
||||
- name: Run test/cli
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_EXECUTOR: thread
|
||||
|
||||
- name: Run test/cli (-j2)
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_J: 2
|
||||
|
||||
- name: Run test/cli (--clang)
|
||||
if: false
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_CLANG: clang
|
||||
|
||||
- name: Generate dependencies
|
||||
if: false
|
||||
run: |
|
||||
# make sure auto-generated GUI files exist
|
||||
make -C cmake.output autogen
|
||||
make -C cmake.output gui-build-deps triage-build-ui-deps
|
||||
|
||||
# TODO: disabled for now as it takes around 40 minutes to finish
|
||||
# set --error-exitcode=0 so we only fail on sanitizer issues - since it uses threads for execution it will exit the whole process on the first issue
|
||||
- name: Self check
|
||||
if: false
|
||||
run: |
|
||||
selfcheck_options="-q -j$(nproc) --std=c++11 --template=selfcheck --showtime=top5_summary -D__GNUC__ --error-exitcode=0 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --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"
|
||||
ec=0
|
||||
./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json -DCHECK_INTERNAL cli lib || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1
|
||||
exit $ec
|
||||
@ -0,0 +1,136 @@
|
||||
# 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: undefined behaviour sanitizers
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
QT_VERSION: 5.15.2
|
||||
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
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
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 libxml2-utils
|
||||
|
||||
- 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 18
|
||||
|
||||
- name: Install Qt ${{ env.QT_VERSION }}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: ${{ env.QT_VERSION }}
|
||||
modules: 'qtcharts'
|
||||
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
|
||||
|
||||
# TODO: disable warnings
|
||||
- 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
|
||||
env:
|
||||
CC: clang-18
|
||||
CXX: clang++-18
|
||||
|
||||
- name: Build cppcheck
|
||||
run: |
|
||||
cmake --build cmake.output --target cppcheck -- -j $(nproc)
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
cmake --build cmake.output --target testrunner -- -j $(nproc)
|
||||
|
||||
- name: Run tests
|
||||
run: ./cmake.output/bin/testrunner
|
||||
|
||||
- name: Run cfg tests
|
||||
run: |
|
||||
cmake --build cmake.output --target checkcfg -- -j $(nproc)
|
||||
|
||||
# TODO: we should use CTest instead to parallelize tests but the start-up overhead will slow things down
|
||||
- name: Run CTest
|
||||
if: false
|
||||
run: |
|
||||
ctest --test-dir cmake.output --output-on-failure -j$(nproc)
|
||||
|
||||
- name: Run test/cli
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
|
||||
- name: Run test/cli (-j2)
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_J: 2
|
||||
|
||||
- name: Run test/cli (--clang)
|
||||
if: false
|
||||
run: |
|
||||
pwd=$(pwd)
|
||||
cd test/cli
|
||||
TEST_CPPCHECK_EXE_LOOKUP_PATH="$pwd/cmake.output" python3 -m pytest -Werror --strict-markers -vv
|
||||
env:
|
||||
TEST_CPPCHECK_INJECT_CLANG: clang
|
||||
|
||||
- name: Generate dependencies
|
||||
run: |
|
||||
# make sure auto-generated GUI files exist
|
||||
make -C cmake.output autogen
|
||||
make -C cmake.output gui-build-deps triage-build-ui-deps
|
||||
|
||||
# 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_summary -D__GNUC__ --error-exitcode=1 --inline-suppr --suppressions-list=.selfcheck_suppressions --library=gnu --inconclusive --enable=style,performance,portability,warning,missingInclude,internal --exception-handling --debug-warnings --check-level=exhaustive"
|
||||
cppcheck_options="-D__CPPCHECK__ -DCHECK_INTERNAL -DHAVE_RULES --library=cppcheck-lib -Ilib -Iexternals/simplecpp/ -Iexternals/tinyxml2"
|
||||
ec=0
|
||||
./cmake.output/bin/cppcheck $selfcheck_options externals/simplecpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options --addon=naming.json cli lib || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt --addon=naming.json -Icmake.output/gui -Igui gui/*.cpp cmake.output/gui/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -Icli test/*.cpp tools/*.cpp || ec=1
|
||||
./cmake.output/bin/cppcheck $selfcheck_options $cppcheck_options -DQ_MOC_OUTPUT_REVISION=68 -DQT_CHARTS_LIB -DQT_MOC_HAS_STRINGDATA --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage/*.cpp || ec=1
|
||||
exit $ec
|
||||
@ -0,0 +1,62 @@
|
||||
# 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: valgrind
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'releases/**'
|
||||
tags:
|
||||
- '2.*'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.11
|
||||
with:
|
||||
key: ${{ github.workflow }}-${{ runner.os }}
|
||||
|
||||
- name: Install missing software
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libxml2-utils
|
||||
sudo apt-get install valgrind
|
||||
sudo apt-get install libboost-container-dev
|
||||
sudo apt-get install debuginfod
|
||||
|
||||
- name: Build cppcheck
|
||||
run: |
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
CXXFLAGS="-O1 -g -w -DHAVE_BOOST" make -j$(nproc) HAVE_RULES=yes MATCHCOMPILER=yes
|
||||
|
||||
- name: Build test
|
||||
run: |
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
CXXFLAGS="-O1 -g -w -DHAVE_BOOST" make -j$(nproc) testrunner HAVE_RULES=yes MATCHCOMPILER=yes
|
||||
|
||||
- name: Run valgrind
|
||||
run: |
|
||||
ec=0
|
||||
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
|
||||
# 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
|
||||
if: success() || failure()
|
||||
with:
|
||||
name: Logs
|
||||
path: ./*.log
|
||||
@ -0,0 +1,136 @@
|
||||
*.bak
|
||||
*.gcno
|
||||
*.o
|
||||
*.pyc
|
||||
/cppcheck
|
||||
/cppcheck.exe
|
||||
cppcheck-core.dll
|
||||
/dmake
|
||||
/dmake.exe
|
||||
reduce
|
||||
reduce.exe
|
||||
tags
|
||||
/testrunner
|
||||
/testrunner.exe
|
||||
tools/daca2*.html
|
||||
tools/errmsg
|
||||
tools/extracttests
|
||||
|
||||
# dump files generated by Cppcheck
|
||||
*.*.dump
|
||||
|
||||
# CTU info files generated by Cppcheck
|
||||
*.*.ctu-info
|
||||
|
||||
# VS generated files
|
||||
*.aps
|
||||
*.idb
|
||||
*.ncb
|
||||
*.obj
|
||||
*.opensdf
|
||||
*.orig
|
||||
*.pdb
|
||||
*.sdf
|
||||
*.suo
|
||||
*.user
|
||||
/.vs/
|
||||
UpgradeLog*.htm
|
||||
|
||||
# VS build folders
|
||||
bin/
|
||||
Build/
|
||||
BuildTmp/
|
||||
/cli/temp/
|
||||
ipch/
|
||||
/lib/temp/
|
||||
/test/temp/
|
||||
|
||||
# XCode build folders and files
|
||||
*.mode[0-9]v[0-9]
|
||||
*.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
|
||||
*~
|
||||
|
||||
# kdevelop 4.x
|
||||
*.kdev4
|
||||
|
||||
# Common cmake build directories
|
||||
build**/
|
||||
|
||||
# Temporal files
|
||||
*.swp
|
||||
|
||||
# Snapcraft build
|
||||
part
|
||||
prime
|
||||
parts
|
||||
stage
|
||||
*.snap
|
||||
/snap/.snapcraft
|
||||
|
||||
# Manual folder
|
||||
/man/manual.log
|
||||
/man/manual.tex
|
||||
/man/*.pdf
|
||||
/man/*.html
|
||||
|
||||
# CLion
|
||||
/.idea
|
||||
/.metadata/
|
||||
/cmake-build-*
|
||||
/.run
|
||||
|
||||
# clang tooling temporary files
|
||||
.clangd/
|
||||
.cache/
|
||||
compile_commands.json
|
||||
|
||||
# qmake
|
||||
.qmake.stash
|
||||
|
||||
#vs code
|
||||
/.vscode
|
||||
|
||||
# fuzzing output
|
||||
/oss-fuzz/corpus
|
||||
/oss-fuzz/corpus_
|
||||
/oss-fuzz/samples
|
||||
@ -0,0 +1,28 @@
|
||||
missingIncludeSystem
|
||||
|
||||
# temporary suppressions - fix the warnings!
|
||||
simplifyUsing:lib/valueptr.h
|
||||
varid0:gui/projectfile.cpp
|
||||
naming-privateMemberVariable:gui/test/cppchecklibrarydata/testcppchecklibrarydata.h
|
||||
symbolDatabaseWarning:*/moc_*.cpp
|
||||
simplifyUsing:*/moc_*.cpp
|
||||
|
||||
# warnings in Qt generated code we cannot fix
|
||||
funcArgNamesDifferent:*/moc_*.cpp
|
||||
naming-varname:*/ui_*.h
|
||||
functionStatic:*/ui_fileview.h
|
||||
|
||||
# --debug-warnings suppressions
|
||||
valueFlowBailout
|
||||
valueFlowBailoutIncompleteVar
|
||||
autoNoType
|
||||
|
||||
naming-varname:externals/simplecpp/simplecpp.h
|
||||
naming-privateMemberVariable:externals/simplecpp/simplecpp.h
|
||||
|
||||
# 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
|
||||
@ -0,0 +1,15 @@
|
||||
# we are not using all methods of their interfaces
|
||||
unusedFunction:externals/*/*
|
||||
|
||||
# TODO: fix these
|
||||
# false positive - # 10660
|
||||
unusedFunction:gui/mainwindow.cpp
|
||||
unusedFunction:gui/resultstree.cpp
|
||||
unusedFunction:gui/codeeditor.*
|
||||
# usage is disabled
|
||||
unusedFunction:lib/symboldatabase.cpp
|
||||
# false positive - #10661
|
||||
unusedFunction:oss-fuzz/main.cpp
|
||||
|
||||
# Q_OBJECT functions which are not called in our code
|
||||
unusedFunction:cmake.output.notest/gui/cppcheck-gui_autogen/*/moc_aboutdialog.cpp
|
||||
@ -0,0 +1,43 @@
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,408 @@
|
||||
The cppcheck team, in alphabetical order:
|
||||
|
||||
0x41head
|
||||
Abhijit Sawant
|
||||
Abhishek Bharadwaj
|
||||
Abigail Buccaneer
|
||||
Adam J Richter
|
||||
Adrien Chardon
|
||||
Ahti Legonkov
|
||||
Akhilesh Nema
|
||||
Akio Idehara
|
||||
Albert Aribaud
|
||||
Aleksandr Pikalev
|
||||
Aleksey Palazhchenko
|
||||
Alexander Alekseev
|
||||
Alexander Festini
|
||||
Alexander Gushchin
|
||||
Alexander Mai
|
||||
Alexander Tkachev
|
||||
Alexandre Chouvellon
|
||||
Alexey Eryomenko
|
||||
Alexey Zhikhartsev
|
||||
Alfi Maulana
|
||||
Ali Can Demiralp
|
||||
Alon Alexander
|
||||
Alon Liberman
|
||||
Ameen Ali
|
||||
Andreas Bacher
|
||||
Andreas Bießmann
|
||||
Andreas Grob
|
||||
Andreas Pokorny
|
||||
Andreas Rönnquist
|
||||
Andreas Vollenweider
|
||||
Andrei Karas
|
||||
Andrew C Aitchison
|
||||
Andrew C. Martin
|
||||
Andrew D. Bancroft
|
||||
Andy Holmes
|
||||
Andy Maloney
|
||||
Andy Mac Gregor
|
||||
Aneesh Azhakesan S
|
||||
Ankita Gupta
|
||||
Anton Lindqvist
|
||||
Antti Tuppurainen
|
||||
Anurag Garg
|
||||
Armin Müller
|
||||
Arpit Chaudhary
|
||||
August Sodora
|
||||
Ayaz Salikhov
|
||||
Balázs Tóth
|
||||
Baris Demiray
|
||||
Bart vdr. Meulen
|
||||
Bartlomiej Grzeskowiak
|
||||
bbennetts
|
||||
Benjamin Bannier
|
||||
Benjamin Fovet
|
||||
Benjamin Goose
|
||||
Benjamin Kramer
|
||||
Benjamin Woester
|
||||
Benjamin Wolsey
|
||||
Ben T
|
||||
Bernd Buschinski
|
||||
Bill Egert
|
||||
Björge Dijkstra
|
||||
booga
|
||||
Boris Barbulovski
|
||||
Boris Egorov
|
||||
Boussaffa Walid
|
||||
Bo Rydberg
|
||||
bzgec
|
||||
Carl Michael Grüner Monzón
|
||||
Carl Morgan
|
||||
Carlo Marcelo Arenas Belón
|
||||
Carlos Gomes Martinho
|
||||
Carl-Oskar Larsson
|
||||
Cary R
|
||||
Changkyoon Kim
|
||||
Chris Lalancette
|
||||
Christian Ehrlicher
|
||||
Christian Franke
|
||||
Christoph Grüninger
|
||||
Christoph Schmidt
|
||||
Christoph Strehle
|
||||
Chuck Larson
|
||||
Cilyan Olowen
|
||||
Claus Jensby Madsen
|
||||
Colomban Wendling
|
||||
Conrado Gouvea
|
||||
daisuke-chiba
|
||||
Daniel Friedrich
|
||||
David Korczynski
|
||||
Daniel Marjamäki
|
||||
David Hallas
|
||||
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
|
||||
Erik Lax
|
||||
Ettl Martin
|
||||
Even Rouault
|
||||
Evgeny Mandrikov
|
||||
Felipe Pena
|
||||
Felix Geyer
|
||||
Felix Passenberg
|
||||
Felix Wolff
|
||||
Florin Iucha
|
||||
Francesc Elies
|
||||
Frank Zingsheim
|
||||
Frederik Schwarzer
|
||||
fu7mu4
|
||||
Galimov Albert
|
||||
Garrett Bodily
|
||||
Gary Leutheuser
|
||||
gaurav kaushik
|
||||
Gennady Feldman
|
||||
Georgi D. Sotirov
|
||||
Georgy Komarov
|
||||
Gerbo Engels
|
||||
Gerhard Zlabinger
|
||||
Gerik Rhoden
|
||||
Gianfranco Costamagna
|
||||
Gianluca Scacco
|
||||
Gleydson Soares
|
||||
Goran Džaferi
|
||||
Graham Whitted
|
||||
Greg Hewgill
|
||||
Guillaume A.
|
||||
Guillaume Chauvel
|
||||
Guillaume Miossec
|
||||
Gustav Palmqvist
|
||||
Günther Makulik
|
||||
Haowei Hsu
|
||||
Harald Scheidl
|
||||
Heiko Bauke
|
||||
Heiko Eißfeldt
|
||||
Heinrich Schuchardt
|
||||
Henrik Nilsson
|
||||
He Yuqi
|
||||
Hoang Tuan Su
|
||||
Igor Rondarev
|
||||
Igor Zhukov
|
||||
Ilya Shipitsin
|
||||
Ivan Maidanski
|
||||
Iván Matellanes
|
||||
Ivan Ryabov
|
||||
Ivar Bonsaksen
|
||||
Jakub Melka
|
||||
Jan Egil Ruud
|
||||
Jan Hellwig
|
||||
János Maros
|
||||
Jay Sigbrandt
|
||||
Jedrzej Klocek
|
||||
Jens Bäckman
|
||||
Jens Yllman
|
||||
Jérémy Lefaure
|
||||
Jes Ramsing
|
||||
Jesse Boswell
|
||||
Jim Kuhn
|
||||
Jim Zhou
|
||||
jlguardi
|
||||
Johan Bertrand
|
||||
Johan Samuelson
|
||||
John Marshall
|
||||
John-Paul Ore
|
||||
John Smits
|
||||
Jonathan Clohessy
|
||||
Jonathan Haehne
|
||||
Jonathan Neuschäfer
|
||||
Jonathan Thackray
|
||||
José Martins
|
||||
Jose Roquette
|
||||
Joshua Beck
|
||||
Joshua Rogers
|
||||
Julian Santander
|
||||
Julien Marrec
|
||||
Julien Peyregne
|
||||
Jure Menart
|
||||
Jussi Lehtola
|
||||
Jørgen Kvalsvik
|
||||
Kamil Dudka
|
||||
Kartik Bajaj
|
||||
Kefu Chai
|
||||
keinflue
|
||||
Ken-Patrick Lehrmann
|
||||
Ketil Skjerve
|
||||
Kevin Christian
|
||||
Kevin Kendzia
|
||||
Kimmo Varis
|
||||
Kleber Tarcísio
|
||||
Konrad Grochowski
|
||||
Konrad Windszus
|
||||
Kumar Ashwani
|
||||
Kushal Chandar
|
||||
Kyle Chisholm
|
||||
Lars Even Almaas
|
||||
larudwer
|
||||
Lau bakman
|
||||
Lauri Nurmi
|
||||
Leandro Lisboa Penz
|
||||
Leila F. Rahman
|
||||
Lena Herscheid
|
||||
Leon De Andrade
|
||||
Lieven de Cock
|
||||
lioncash
|
||||
Lionel Gimbert
|
||||
Lucas Manuel Rodriguez
|
||||
Luis Díaz Más
|
||||
Lukas Grützmacher
|
||||
Lukasz Czajczyk
|
||||
Łukasz Jankowski
|
||||
Luxon Jean-Pierre
|
||||
Maarten van der Schrieck
|
||||
Maksim Derbasov
|
||||
Malcolm Parsons
|
||||
Marc-Antoine Perennou
|
||||
Marcel Raad
|
||||
Marco Trevisan
|
||||
Marek Zmysłowski
|
||||
Marian Klymov
|
||||
Mark de Wever
|
||||
Mark Hermeling
|
||||
Markus Elfring
|
||||
Martin Delille
|
||||
Martin Ettl
|
||||
Martin Exner
|
||||
Martin Güthle
|
||||
Martin Herren
|
||||
Márton Csordás
|
||||
Masafumi Koba
|
||||
Massimo Paladin
|
||||
Mateusz Michalak
|
||||
Mateusz Pusz
|
||||
Mathias De Maré
|
||||
Mathias Schmid
|
||||
Matthias Krüger
|
||||
Matthias Kuhn
|
||||
Matthias Schmieder
|
||||
Matt Johnson
|
||||
Maurice Gilden
|
||||
Mavik
|
||||
Michael Drake
|
||||
Michael Løiten
|
||||
Miika-Petteri Matikainen
|
||||
Mika Attila
|
||||
Mike Tzou
|
||||
Milhan Kim
|
||||
Mil Tolstoy
|
||||
Mischa Aster Alff
|
||||
Mohit Mate
|
||||
Monika Lukow
|
||||
Moritz Barsnick
|
||||
Moritz Lipp
|
||||
Moshe Kaplan
|
||||
ms
|
||||
Neszt Tibor
|
||||
Nguyen Duong Tuan
|
||||
Ni2c2k
|
||||
Nick Ridgway
|
||||
Nicolás Alvarez
|
||||
Nicolas Le Cam
|
||||
Nilesh Kumar
|
||||
Ogawa KenIchi
|
||||
Oleksandr Redko
|
||||
Oliver Schode
|
||||
Oliver Stöneberg
|
||||
Olivier Croquette
|
||||
Patrick Oppenlander
|
||||
Paul Aitken
|
||||
Paul Bersee
|
||||
Paul Fultz II
|
||||
Pavel Bibergal
|
||||
Pavel Pimenov
|
||||
Pavel Roschin
|
||||
Pavel Skipenes
|
||||
Pavel Šimovec
|
||||
Pavol Misik
|
||||
Pete Johns
|
||||
Peter Pentchev
|
||||
Peter Schops
|
||||
Philip Chimento
|
||||
Philipp Kloke
|
||||
Pierre Schweitzer
|
||||
Pino Toscano
|
||||
Pranav Khanna
|
||||
Radek Jarecki
|
||||
Rainer Wiesenfarth
|
||||
Ramzan Bekbulatov
|
||||
Raphael Geissert
|
||||
Razvan Ioan Alexe
|
||||
Reijo Tomperi
|
||||
Rainer Wiesenfarth
|
||||
Riccardo Ghetta
|
||||
Richard A. Smith
|
||||
Richard Quirk
|
||||
Rick van der Sluijs
|
||||
Rikard Falkeborn
|
||||
rivdsl
|
||||
Robert Habrich
|
||||
Robert Morin
|
||||
Roberto Martelloni
|
||||
Robert Reif
|
||||
rofl0r
|
||||
Roman Zaytsev Borisovich
|
||||
Ronald Hiemstra
|
||||
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 Furry
|
||||
Sebastian Held
|
||||
Sebastian Matuschka
|
||||
Sébastien Debrard
|
||||
Sergei Chernykh
|
||||
Sergei Trofimovich
|
||||
Sergey Burgsdorf
|
||||
Shane Tapp
|
||||
Shohei YOSHIDA
|
||||
Simon Cornell
|
||||
Simon Kagstrom
|
||||
Simon Large
|
||||
Simon Martin
|
||||
Simon Shanks
|
||||
Slava Semushin
|
||||
Stas Cymbalov
|
||||
Stefan Beller
|
||||
Stefan Hagen
|
||||
Stefan Naewe
|
||||
Stefan van Kessel
|
||||
Stefan Weil
|
||||
Stéphane Michel
|
||||
Steve Browne
|
||||
Steve Duan
|
||||
Steve Mokris
|
||||
Steven Cook
|
||||
Steven Myint
|
||||
Susi Lehtola
|
||||
Swasti Shrivastava
|
||||
Sylvain Joubert
|
||||
Tam Do Thanh
|
||||
Teddy Didé
|
||||
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 Weibel
|
||||
Tomasz Kłoczko
|
||||
Tom Pollok
|
||||
Tomo Dote
|
||||
Toralf Förster
|
||||
Troshin V.S.
|
||||
Tyson Nottingham
|
||||
Valentin Batz
|
||||
Valerii Lashmanov
|
||||
Vasily Maslyukov
|
||||
Veli-Matti Visuri
|
||||
Vesa Pikki
|
||||
Ville-Pekka Vahteala
|
||||
Ville Skyttä
|
||||
Vincent Le Garrec
|
||||
Wang Haoyu
|
||||
WenChung Chiu
|
||||
Wolfgang Stöggl
|
||||
x29a
|
||||
XhmikosR
|
||||
Xuecheng Zhang
|
||||
Yichen Yan
|
||||
Yurii Putin
|
||||
Zachary Blair
|
||||
Zhao Qifa
|
||||
Zhiyuan Zhang
|
||||
Zhu Lei
|
||||
Дмитрий Старцев
|
||||
|
||||
GUI graphics courtesy of Tango Desktop Project:
|
||||
http://tango.freedesktop.org
|
||||
@ -0,0 +1,105 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
if (MSVC)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
endif()
|
||||
cmake_policy(SET CMP0048 NEW) # allow VERSION in project()
|
||||
project(Cppcheck VERSION 2.13.99 LANGUAGES CXX)
|
||||
|
||||
include(cmake/cxx11.cmake)
|
||||
use_cxx11()
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
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()
|
||||
|
||||
|
||||
file(GLOB addons "addons/*.py")
|
||||
file(GLOB cfgs "cfg/*.cfg")
|
||||
file(GLOB platforms "platforms/*.xml")
|
||||
|
||||
if(LIBXML2_XMLLINT_EXECUTABLE)
|
||||
add_custom_target(validateCFG DEPENDS validateCFG-cmd)
|
||||
add_custom_command(OUTPUT validateCFG-cmd
|
||||
COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --noout ${CMAKE_SOURCE_DIR}/cfg/cppcheck-cfg.rng)
|
||||
foreach(cfg ${cfgs})
|
||||
add_custom_command(OUTPUT validateCFG-cmd APPEND
|
||||
COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --noout --relaxng ${CMAKE_SOURCE_DIR}/cfg/cppcheck-cfg.rng ${cfg})
|
||||
endforeach()
|
||||
# this is a symbolic name for a build rule and not an output file
|
||||
set_source_files_properties(validateCFG-cmd PROPERTIES SYMBOLIC "true")
|
||||
|
||||
add_custom_target(validatePlatforms ${LIBXML2_XMLLINT_EXECUTABLE} --noout ${CMAKE_SOURCE_DIR}/platforms/cppcheck-platforms.rng)
|
||||
foreach(platform ${platforms})
|
||||
get_filename_component(platformname ${platform} NAME_WE)
|
||||
add_custom_target(validatePlatforms-${platformname} ${LIBXML2_XMLLINT_EXECUTABLE} --noout --relaxng ${CMAKE_SOURCE_DIR}/platforms/cppcheck-platforms.rng ${platform})
|
||||
add_dependencies(validatePlatforms validatePlatforms-${platformname})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(errorlist-xml $<TARGET_FILE:cppcheck> --errorlist > ${CMAKE_BINARY_DIR}/errorlist.xml
|
||||
DEPENDS cppcheck)
|
||||
|
||||
add_custom_target(example-xml $<TARGET_FILE:cppcheck> --xml --enable=all --inconclusive --max-configs=1 ${CMAKE_SOURCE_DIR}/samples 2> ${CMAKE_BINARY_DIR}/example.xml
|
||||
DEPENDS cppcheck)
|
||||
|
||||
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
|
||||
DEPENDS errorlist-xml)
|
||||
endif()
|
||||
|
||||
add_custom_target(validateXML ${LIBXML2_XMLLINT_EXECUTABLE} --noout ${CMAKE_SOURCE_DIR}/cppcheck-errors.rng
|
||||
COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --noout --relaxng ${CMAKE_SOURCE_DIR}/cppcheck-errors.rng ${CMAKE_BINARY_DIR}/errorlist.xml
|
||||
COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --noout --relaxng ${CMAKE_SOURCE_DIR}/cppcheck-errors.rng ${CMAKE_BINARY_DIR}/example.xml
|
||||
DEPENDS createXMLExamples
|
||||
)
|
||||
|
||||
add_custom_target(validateRules ${LIBXML2_XMLLINT_EXECUTABLE} --noout ${CMAKE_SOURCE_DIR}/rules/*.xml)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
add_custom_target(copy_cfg ALL
|
||||
${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/cfg"
|
||||
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/cfg"
|
||||
COMMENT "Copying cfg files to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}")
|
||||
|
||||
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(copy_platforms ALL
|
||||
${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/platforms"
|
||||
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/platforms"
|
||||
COMMENT "Copying platforms files to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}")
|
||||
|
||||
if(USE_BUNDLED_TINYXML2)
|
||||
message(STATUS "Using bundled version of tinyxml2")
|
||||
add_subdirectory(externals/tinyxml2)
|
||||
endif()
|
||||
add_subdirectory(externals/simplecpp)
|
||||
add_subdirectory(lib) # CppCheck Library
|
||||
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)
|
||||
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@ -0,0 +1,902 @@
|
||||
# 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=
|
||||
endif
|
||||
|
||||
ifndef MATCHCOMPILER
|
||||
MATCHCOMPILER=
|
||||
endif
|
||||
# use match compiler
|
||||
ifeq ($(MATCHCOMPILER),yes)
|
||||
# Find available Python interpreter
|
||||
ifeq ($(PYTHON_INTERPRETER),)
|
||||
PYTHON_INTERPRETER := $(shell which python3)
|
||||
endif
|
||||
ifeq ($(PYTHON_INTERPRETER),)
|
||||
PYTHON_INTERPRETER := $(shell which python)
|
||||
endif
|
||||
ifeq ($(PYTHON_INTERPRETER),)
|
||||
$(error Did not find a Python interpreter)
|
||||
endif
|
||||
ifdef VERIFY
|
||||
matchcompiler_S := $(shell $(PYTHON_INTERPRETER) tools/matchcompiler.py --verify)
|
||||
else
|
||||
matchcompiler_S := $(shell $(PYTHON_INTERPRETER) tools/matchcompiler.py)
|
||||
endif
|
||||
libcppdir:=build
|
||||
else ifeq ($(MATCHCOMPILER),)
|
||||
libcppdir:=lib
|
||||
else
|
||||
$(error invalid MATCHCOMPILER value '$(MATCHCOMPILER)')
|
||||
endif
|
||||
|
||||
ifndef CPPFLAGS
|
||||
CPPFLAGS=
|
||||
endif
|
||||
|
||||
ifdef FILESDIR
|
||||
CPPFLAGS+=-DFILESDIR=\"$(FILESDIR)\"
|
||||
endif
|
||||
|
||||
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
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info COMSPEC not found)
|
||||
endif
|
||||
ifdef ComSpec
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info ComSpec found)
|
||||
endif
|
||||
#### ComSpec is defined on some WIN32's.
|
||||
WINNT=1
|
||||
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info PATH=$(PATH))
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring /cygdrive/,$(PATH)))
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info /cygdrive/ found in PATH)
|
||||
endif
|
||||
CYGWIN=1
|
||||
endif # CYGWIN
|
||||
endif # ComSpec
|
||||
endif # COMSPEC
|
||||
|
||||
ifdef WINNT
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info WINNT found)
|
||||
endif
|
||||
#### Maybe Windows
|
||||
ifndef CPPCHK_GLIBCXX_DEBUG
|
||||
CPPCHK_GLIBCXX_DEBUG=
|
||||
endif # !CPPCHK_GLIBCXX_DEBUG
|
||||
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info MSYSTEM=$(MSYSTEM))
|
||||
endif
|
||||
|
||||
ifneq ($(MSYSTEM),MINGW32 MINGW64)
|
||||
RDYNAMIC=
|
||||
endif
|
||||
|
||||
LDFLAGS+=-lshlwapi
|
||||
else # !WINNT
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info WINNT not found)
|
||||
endif
|
||||
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(info uname_S=$(uname_S))
|
||||
endif
|
||||
|
||||
ifeq ($(uname_S),Linux)
|
||||
ifndef CPPCHK_GLIBCXX_DEBUG
|
||||
CPPCHK_GLIBCXX_DEBUG=-D_GLIBCXX_DEBUG
|
||||
endif # !CPPCHK_GLIBCXX_DEBUG
|
||||
endif # Linux
|
||||
|
||||
ifeq ($(uname_S),GNU/kFreeBSD)
|
||||
ifndef CPPCHK_GLIBCXX_DEBUG
|
||||
CPPCHK_GLIBCXX_DEBUG=-D_GLIBCXX_DEBUG
|
||||
endif # !CPPCHK_GLIBCXX_DEBUG
|
||||
endif # GNU/kFreeBSD
|
||||
|
||||
LDFLAGS+=-pthread
|
||||
|
||||
endif # WINNT
|
||||
|
||||
ifdef CYGWIN
|
||||
ifeq ($(VERBOSE),1)
|
||||
$(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
|
||||
|
||||
ifndef CXX
|
||||
CXX=g++
|
||||
endif
|
||||
|
||||
ifeq (clang++, $(findstring clang++,$(CXX)))
|
||||
CPPCHK_GLIBCXX_DEBUG=
|
||||
endif
|
||||
ifndef CXXFLAGS
|
||||
CXXFLAGS=-std=c++0x -O2 -DNDEBUG -Wall -Wno-sign-compare -Wno-multichar
|
||||
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
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RULES),yes)
|
||||
PCRE_CONFIG = $(shell which pcre-config)
|
||||
ifeq ($(PCRE_CONFIG),)
|
||||
$(error Did not find pcre-config)
|
||||
endif
|
||||
override CXXFLAGS += -DHAVE_RULES $(shell $(PCRE_CONFIG) --cflags)
|
||||
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
|
||||
|
||||
ifndef PREFIX
|
||||
PREFIX=/usr
|
||||
endif
|
||||
|
||||
ifndef INCLUDE_FOR_LIB
|
||||
INCLUDE_FOR_LIB=-Ilib -isystem externals -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2
|
||||
endif
|
||||
|
||||
ifndef INCLUDE_FOR_CLI
|
||||
INCLUDE_FOR_CLI=-Ilib -isystem externals/simplecpp -isystem externals/tinyxml2
|
||||
endif
|
||||
|
||||
ifndef INCLUDE_FOR_TEST
|
||||
INCLUDE_FOR_TEST=-Ilib -Icli -isystem externals/simplecpp -isystem externals/tinyxml2
|
||||
endif
|
||||
|
||||
BIN=$(DESTDIR)$(PREFIX)/bin
|
||||
|
||||
# For 'make man': sudo apt-get install xsltproc docbook-xsl docbook-xml on Linux
|
||||
DB2MAN?=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl
|
||||
XP=xsltproc -''-nonet -''-param man.charmap.use.subset "0"
|
||||
MAN_SOURCE=man/cppcheck.1.xml
|
||||
|
||||
|
||||
###### Object Files
|
||||
|
||||
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)/checkersreport.o \
|
||||
$(libcppdir)/checkexceptionsafety.o \
|
||||
$(libcppdir)/checkfunctions.o \
|
||||
$(libcppdir)/checkinternal.o \
|
||||
$(libcppdir)/checkio.o \
|
||||
$(libcppdir)/checkleakautovar.o \
|
||||
$(libcppdir)/checkmemoryleak.o \
|
||||
$(libcppdir)/checknullpointer.o \
|
||||
$(libcppdir)/checkother.o \
|
||||
$(libcppdir)/checkpostfixoperator.o \
|
||||
$(libcppdir)/checksizeof.o \
|
||||
$(libcppdir)/checkstl.o \
|
||||
$(libcppdir)/checkstring.o \
|
||||
$(libcppdir)/checktype.o \
|
||||
$(libcppdir)/checkuninitvar.o \
|
||||
$(libcppdir)/checkunusedfunctions.o \
|
||||
$(libcppdir)/checkunusedvar.o \
|
||||
$(libcppdir)/checkvaarg.o \
|
||||
$(libcppdir)/clangimport.o \
|
||||
$(libcppdir)/color.o \
|
||||
$(libcppdir)/cppcheck.o \
|
||||
$(libcppdir)/ctu.o \
|
||||
$(libcppdir)/errorlogger.o \
|
||||
$(libcppdir)/errortypes.o \
|
||||
$(libcppdir)/forwardanalyzer.o \
|
||||
$(libcppdir)/fwdanalysis.o \
|
||||
$(libcppdir)/importproject.o \
|
||||
$(libcppdir)/infer.o \
|
||||
$(libcppdir)/keywords.o \
|
||||
$(libcppdir)/library.o \
|
||||
$(libcppdir)/mathlib.o \
|
||||
$(libcppdir)/path.o \
|
||||
$(libcppdir)/pathanalysis.o \
|
||||
$(libcppdir)/pathmatch.o \
|
||||
$(libcppdir)/platform.o \
|
||||
$(libcppdir)/preprocessor.o \
|
||||
$(libcppdir)/programmemory.o \
|
||||
$(libcppdir)/reverseanalyzer.o \
|
||||
$(libcppdir)/settings.o \
|
||||
$(libcppdir)/summaries.o \
|
||||
$(libcppdir)/suppressions.o \
|
||||
$(libcppdir)/templatesimplifier.o \
|
||||
$(libcppdir)/timer.o \
|
||||
$(libcppdir)/token.o \
|
||||
$(libcppdir)/tokenlist.o \
|
||||
$(libcppdir)/utils.o \
|
||||
$(libcppdir)/vfvalue.o
|
||||
|
||||
EXTOBJ = externals/simplecpp/simplecpp.o \
|
||||
externals/tinyxml2/tinyxml2.o
|
||||
|
||||
CLIOBJ = cli/cmdlineparser.o \
|
||||
cli/cppcheckexecutor.o \
|
||||
cli/cppcheckexecutorseh.o \
|
||||
cli/executor.o \
|
||||
cli/filelister.o \
|
||||
cli/main.o \
|
||||
cli/processexecutor.o \
|
||||
cli/signalhandler.o \
|
||||
cli/singleexecutor.o \
|
||||
cli/stacktrace.o \
|
||||
cli/threadexecutor.o
|
||||
|
||||
TESTOBJ = test/fixture.o \
|
||||
test/helpers.o \
|
||||
test/main.o \
|
||||
test/options.o \
|
||||
test/test64bit.o \
|
||||
test/testanalyzerinformation.o \
|
||||
test/testassert.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 \
|
||||
test/testcolor.o \
|
||||
test/testcondition.o \
|
||||
test/testconstructors.o \
|
||||
test/testcppcheck.o \
|
||||
test/testerrorlogger.o \
|
||||
test/testexceptionsafety.o \
|
||||
test/testfilelister.o \
|
||||
test/testfunctions.o \
|
||||
test/testgarbage.o \
|
||||
test/testimportproject.o \
|
||||
test/testincompletestatement.o \
|
||||
test/testinternal.o \
|
||||
test/testio.o \
|
||||
test/testleakautovar.o \
|
||||
test/testlibrary.o \
|
||||
test/testmathlib.o \
|
||||
test/testmemleak.o \
|
||||
test/testnullpointer.o \
|
||||
test/testoptions.o \
|
||||
test/testother.o \
|
||||
test/testpath.o \
|
||||
test/testpathmatch.o \
|
||||
test/testplatform.o \
|
||||
test/testpostfixoperator.o \
|
||||
test/testpreprocessor.o \
|
||||
test/testprocessexecutor.o \
|
||||
test/testsettings.o \
|
||||
test/testsimplifytemplate.o \
|
||||
test/testsimplifytokens.o \
|
||||
test/testsimplifytypedef.o \
|
||||
test/testsimplifyusing.o \
|
||||
test/testsingleexecutor.o \
|
||||
test/testsizeof.o \
|
||||
test/teststl.o \
|
||||
test/teststring.o \
|
||||
test/testsummaries.o \
|
||||
test/testsuppressions.o \
|
||||
test/testsymboldatabase.o \
|
||||
test/testthreadexecutor.o \
|
||||
test/testtimer.o \
|
||||
test/testtoken.o \
|
||||
test/testtokenize.o \
|
||||
test/testtokenlist.o \
|
||||
test/testtokenrange.o \
|
||||
test/testtype.o \
|
||||
test/testuninitvar.o \
|
||||
test/testunusedfunctions.o \
|
||||
test/testunusedprivfunc.o \
|
||||
test/testunusedvar.o \
|
||||
test/testutils.o \
|
||||
test/testvaarg.o \
|
||||
test/testvalueflow.o \
|
||||
test/testvarid.o
|
||||
|
||||
.PHONY: run-dmake tags
|
||||
|
||||
|
||||
###### Targets
|
||||
|
||||
cppcheck: $(EXTOBJ) $(LIBOBJ) $(CLIOBJ)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS) $(RDYNAMIC)
|
||||
|
||||
all: cppcheck testrunner
|
||||
|
||||
testrunner: $(EXTOBJ) $(TESTOBJ) $(LIBOBJ) cli/executor.o cli/processexecutor.o cli/singleexecutor.o cli/threadexecutor.o cli/cmdlineparser.o cli/cppcheckexecutor.o cli/cppcheckexecutorseh.o cli/signalhandler.o cli/stacktrace.o cli/filelister.o
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS) $(RDYNAMIC)
|
||||
|
||||
test: all
|
||||
./testrunner
|
||||
|
||||
check: all
|
||||
./testrunner -q
|
||||
|
||||
checkcfg: cppcheck validateCFG
|
||||
./test/cfg/runtests.sh
|
||||
|
||||
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 --release
|
||||
|
||||
clean:
|
||||
rm -f build/*.cpp build/*.o lib/*.o cli/*.o test/*.o tools/*.o externals/*/*.o testrunner dmake cppcheck cppcheck.exe cppcheck.1
|
||||
|
||||
man: man/cppcheck.1
|
||||
|
||||
man/cppcheck.1: $(MAN_SOURCE)
|
||||
|
||||
$(XP) $(DB2MAN) $(MAN_SOURCE)
|
||||
|
||||
tags:
|
||||
ctags -R --exclude=doxyoutput --exclude=test/cfg cli externals gui lib test
|
||||
|
||||
install: cppcheck
|
||||
install -d ${BIN}
|
||||
install cppcheck ${BIN}
|
||||
install htmlreport/cppcheck-htmlreport ${BIN}
|
||||
ifdef FILESDIR
|
||||
install -d ${DESTDIR}${FILESDIR}
|
||||
install -d ${DESTDIR}${FILESDIR}/addons
|
||||
install -m 644 addons/*.py ${DESTDIR}${FILESDIR}/addons
|
||||
install -d ${DESTDIR}${FILESDIR}/cfg
|
||||
install -m 644 cfg/*.cfg ${DESTDIR}${FILESDIR}/cfg
|
||||
install -d ${DESTDIR}${FILESDIR}/platforms
|
||||
install -m 644 platforms/*.xml ${DESTDIR}${FILESDIR}/platforms
|
||||
else
|
||||
$(error FILESDIR must be set!)
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
@if test -d ${BIN}; then \
|
||||
files="cppcheck cppcheck-htmlreport"; \
|
||||
echo '(' cd ${BIN} '&&' rm -f $$files ')'; \
|
||||
( cd ${BIN} && rm -f $$files ); \
|
||||
fi
|
||||
ifdef FILESDIR
|
||||
@if test -d ${DESTDIR}${FILESDIR}; then \
|
||||
echo rm -rf ${DESTDIR}${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))
|
||||
.PHONY: validateCFG
|
||||
%.checked:%.cfg
|
||||
xmllint --noout --relaxng cfg/cppcheck-cfg.rng $<
|
||||
validateCFG: ${ConfigFilesCHECKED}
|
||||
xmllint --noout cfg/cppcheck-cfg.rng
|
||||
|
||||
# Validation of platforms files:
|
||||
PlatformFiles := $(wildcard platforms/*.xml)
|
||||
PlatformFilesCHECKED := $(patsubst %.xml,%.checked,$(PlatformFiles))
|
||||
.PHONY: validatePlatforms
|
||||
%.checked:%.xml
|
||||
xmllint --noout --relaxng platforms/cppcheck-platforms.rng $<
|
||||
validatePlatforms: ${PlatformFilesCHECKED}
|
||||
xmllint --noout platforms/cppcheck-platforms.rng
|
||||
|
||||
# Validate XML output (to detect regressions)
|
||||
/tmp/errorlist.xml: cppcheck
|
||||
./cppcheck --errorlist >$@
|
||||
/tmp/example.xml: cppcheck
|
||||
./cppcheck --xml --enable=all --inconclusive --max-configs=1 samples 2>/tmp/example.xml
|
||||
createXMLExamples:/tmp/errorlist.xml /tmp/example.xml
|
||||
.PHONY: validateXML
|
||||
validateXML: createXMLExamples
|
||||
xmllint --noout cppcheck-errors.rng
|
||||
xmllint --noout --relaxng cppcheck-errors.rng /tmp/errorlist.xml
|
||||
xmllint --noout --relaxng cppcheck-errors.rng /tmp/example.xml
|
||||
|
||||
checkCWEEntries: /tmp/errorlist.xml
|
||||
$(eval PYTHON_INTERPRETER := $(if $(PYTHON_INTERPRETER),$(PYTHON_INTERPRETER),$(shell which python3)))
|
||||
$(eval PYTHON_INTERPRETER := $(if $(PYTHON_INTERPRETER),$(PYTHON_INTERPRETER),$(shell which python)))
|
||||
$(eval PYTHON_INTERPRETER := $(if $(PYTHON_INTERPRETER),$(PYTHON_INTERPRETER),$(error Did not find a Python interpreter)))
|
||||
$(PYTHON_INTERPRETER) tools/listErrorsWithoutCWE.py -F /tmp/errorlist.xml
|
||||
.PHONY: validateRules
|
||||
validateRules:
|
||||
xmllint --noout rules/*.xml
|
||||
|
||||
###### Build
|
||||
|
||||
$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkuninitvar.h lib/color.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/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/valueptr.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/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/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)/symboldatabase.o: lib/symboldatabase.cpp lib/addoninfo.h lib/astutils.h lib/color.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/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)/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/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.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/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.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/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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp
|
||||
|
||||
$(libcppdir)/check.o: lib/check.cpp lib/addoninfo.h lib/check.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/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/addoninfo.h lib/check.h lib/check64bit.h lib/config.h lib/errortypes.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp
|
||||
|
||||
$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/addoninfo.h lib/check.h lib/checkassert.h lib/config.h lib/errortypes.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp
|
||||
|
||||
$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkautovariables.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/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)/checkautovariables.cpp
|
||||
|
||||
$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkbool.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/suppressions.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/addoninfo.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/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 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/addoninfo.h lib/astutils.h lib/check.h lib/checkclass.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/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 lib/xml.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp
|
||||
|
||||
$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkcondition.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/suppressions.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)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkers.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/suppressions.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/check.h lib/checkexceptionsafety.h lib/config.h lib/errortypes.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp
|
||||
|
||||
$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astutils.h lib/check.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/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)/checkfunctions.cpp
|
||||
|
||||
$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.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/suppressions.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/addoninfo.h lib/astutils.h lib/check.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/suppressions.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/addoninfo.h lib/astutils.h lib/check.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/suppressions.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/addoninfo.h lib/astutils.h lib/check.h lib/checkmemoryleak.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/suppressions.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/addoninfo.h 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/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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp
|
||||
|
||||
$(libcppdir)/checkother.o: lib/checkother.cpp lib/addoninfo.h lib/astutils.h lib/check.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/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)/checkother.cpp
|
||||
|
||||
$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp
|
||||
|
||||
$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/addoninfo.h lib/check.h lib/checksizeof.h lib/config.h lib/errortypes.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp
|
||||
|
||||
$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/addoninfo.h lib/astutils.h lib/check.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/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)/checkstl.cpp
|
||||
|
||||
$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/addoninfo.h lib/astutils.h lib/check.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/suppressions.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/addoninfo.h lib/check.h lib/checktype.h lib/config.h lib/errortypes.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp
|
||||
|
||||
$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/addoninfo.h 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/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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp
|
||||
|
||||
$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/checkunusedfunctions.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/suppressions.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 lib/addoninfo.h lib/astutils.h lib/check.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/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)/checkunusedvar.cpp
|
||||
|
||||
$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/addoninfo.h lib/astutils.h lib/check.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/suppressions.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/addoninfo.h lib/clangimport.h lib/config.h lib/errortypes.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
|
||||
$(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/addoninfo.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/filesettings.h lib/json.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 lib/xml.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp
|
||||
|
||||
$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/astutils.h lib/check.h lib/color.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/suppressions.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/addoninfo.h lib/analyzerinfo.h lib/check.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/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 lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errortypes.cpp
|
||||
|
||||
$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.h lib/color.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/suppressions.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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp
|
||||
|
||||
$(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/addoninfo.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/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 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
|
||||
$(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 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
|
||||
$(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/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/standards.h lib/utils.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 lib/standards.h lib/utils.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/addoninfo.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/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp
|
||||
|
||||
$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/addoninfo.h lib/astutils.h lib/calculate.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/suppressions.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)/programmemory.cpp
|
||||
|
||||
$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/addoninfo.h lib/analyzer.h lib/astutils.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/suppressions.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/addoninfo.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/addoninfo.h lib/analyzerinfo.h lib/config.h lib/errortypes.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
|
||||
$(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/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)/templatesimplifier.o: lib/templatesimplifier.cpp lib/addoninfo.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/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 lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp
|
||||
|
||||
$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.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/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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp
|
||||
|
||||
$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/astutils.h lib/color.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/suppressions.h lib/symboldatabase.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)/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
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp
|
||||
|
||||
cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.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/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/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/executor.h cli/processexecutor.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkersreport.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/platform.h lib/settings.h lib/standards.h lib/suppressions.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/config.h lib/filesettings.h lib/platform.h lib/standards.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutorseh.cpp
|
||||
|
||||
cli/executor.o: cli/executor.cpp cli/executor.h lib/addoninfo.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/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/config.h lib/errortypes.h lib/filesettings.h lib/platform.h lib/standards.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/main.cpp
|
||||
|
||||
cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/analyzerinfo.h lib/check.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/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/signalhandler.o: cli/signalhandler.cpp cli/signalhandler.h cli/stacktrace.h lib/config.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/analyzerinfo.h lib/check.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/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/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/executor.h cli/threadexecutor.h lib/addoninfo.h lib/analyzerinfo.h lib/check.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/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/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.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 lib/xml.h test/fixture.h test/options.h test/redirect.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp
|
||||
|
||||
test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/config.h lib/errortypes.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/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp
|
||||
|
||||
test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.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/suppressions.h lib/utils.h test/fixture.h test/options.h
|
||||
$(CXX) ${INCLUDE_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
|
||||
|
||||
test/test64bit.o: test/test64bit.cpp lib/addoninfo.h lib/check.h lib/check64bit.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp
|
||||
|
||||
test/testanalyzerinformation.o: test/testanalyzerinformation.cpp lib/addoninfo.h lib/analyzerinfo.h lib/check.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 test/fixture.h
|
||||
$(CXX) ${INCLUDE_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/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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_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/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/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/testastutils.cpp
|
||||
|
||||
test/testautovariables.o: test/testautovariables.cpp lib/addoninfo.h lib/check.h lib/checkautovariables.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_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/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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp
|
||||
|
||||
test/testboost.o: test/testboost.cpp lib/addoninfo.h lib/check.h lib/checkboost.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testboost.cpp
|
||||
|
||||
test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/addoninfo.h lib/check.h lib/checkbufferoverrun.h lib/color.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/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/testbufferoverrun.cpp
|
||||
|
||||
test/testcharvar.o: test/testcharvar.cpp lib/addoninfo.h lib/check.h lib/checkother.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp
|
||||
|
||||
test/testcheck.o: test/testcheck.cpp lib/addoninfo.h lib/check.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 test/fixture.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp
|
||||
|
||||
test/testclangimport.o: test/testclangimport.cpp lib/addoninfo.h lib/check.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/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/testclass.o: test/testclass.cpp lib/addoninfo.h lib/check.h lib/checkclass.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/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/testclass.cpp
|
||||
|
||||
test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h lib/addoninfo.h lib/check.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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp
|
||||
|
||||
test/testcolor.o: test/testcolor.cpp lib/addoninfo.h lib/check.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 test/fixture.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp
|
||||
|
||||
test/testcondition.o: test/testcondition.cpp lib/addoninfo.h lib/check.h lib/checkcondition.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp
|
||||
|
||||
test/testconstructors.o: test/testconstructors.cpp lib/addoninfo.h lib/check.h lib/checkclass.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/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/testconstructors.cpp
|
||||
|
||||
test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.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/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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp
|
||||
|
||||
test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/color.h lib/config.h lib/cppcheck.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 lib/xml.h test/fixture.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp
|
||||
|
||||
test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/check.h lib/checkexceptionsafety.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp
|
||||
|
||||
test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.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/suppressions.h lib/utils.h test/fixture.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp
|
||||
|
||||
test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkfunctions.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp
|
||||
|
||||
test/testgarbage.o: test/testgarbage.cpp lib/addoninfo.h lib/check.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/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/testgarbage.cpp
|
||||
|
||||
test/testimportproject.o: test/testimportproject.cpp lib/addoninfo.h lib/check.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/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h test/redirect.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp
|
||||
|
||||
test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkother.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp
|
||||
|
||||
test/testinternal.o: test/testinternal.cpp lib/addoninfo.h lib/check.h lib/checkinternal.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp
|
||||
|
||||
test/testio.o: test/testio.cpp lib/addoninfo.h lib/check.h lib/checkio.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp
|
||||
|
||||
test/testleakautovar.o: test/testleakautovar.cpp lib/addoninfo.h lib/check.h lib/checkleakautovar.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp
|
||||
|
||||
test/testlibrary.o: test/testlibrary.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.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/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp
|
||||
|
||||
test/testmathlib.o: test/testmathlib.cpp lib/addoninfo.h lib/check.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 test/fixture.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp
|
||||
|
||||
test/testmemleak.o: test/testmemleak.cpp lib/addoninfo.h lib/check.h lib/checkmemoryleak.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/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/testmemleak.cpp
|
||||
|
||||
test/testnullpointer.o: test/testnullpointer.cpp lib/addoninfo.h lib/check.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/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/testnullpointer.cpp
|
||||
|
||||
test/testoptions.o: test/testoptions.cpp lib/addoninfo.h lib/check.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 test/fixture.h test/options.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp
|
||||
|
||||
test/testother.o: test/testother.cpp lib/addoninfo.h lib/check.h lib/checkother.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp
|
||||
|
||||
test/testpath.o: test/testpath.cpp lib/addoninfo.h lib/check.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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp
|
||||
|
||||
test/testpathmatch.o: test/testpathmatch.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.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/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.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 lib/xml.h test/fixture.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp
|
||||
|
||||
test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/addoninfo.h lib/check.h lib/checkpostfixoperator.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp
|
||||
|
||||
test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp
|
||||
|
||||
test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/addoninfo.h lib/analyzerinfo.h lib/check.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/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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp
|
||||
|
||||
test/testsettings.o: test/testsettings.cpp lib/addoninfo.h lib/check.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp
|
||||
|
||||
test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/addoninfo.h lib/check.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/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/testsimplifytemplate.cpp
|
||||
|
||||
test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/addoninfo.h lib/check.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/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/testsimplifytokens.cpp
|
||||
|
||||
test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/addoninfo.h lib/check.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/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/testsimplifytypedef.cpp
|
||||
|
||||
test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/addoninfo.h lib/check.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/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/testsimplifyusing.cpp
|
||||
|
||||
test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/addoninfo.h lib/analyzerinfo.h lib/check.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/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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp
|
||||
|
||||
test/testsizeof.o: test/testsizeof.cpp lib/addoninfo.h lib/check.h lib/checksizeof.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.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/checkstl.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/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/teststl.cpp
|
||||
|
||||
test/teststring.o: test/teststring.cpp lib/addoninfo.h lib/check.h lib/checkstring.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.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/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/summaries.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.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/analyzerinfo.h lib/check.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/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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp
|
||||
|
||||
test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/addoninfo.h lib/check.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/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/analyzerinfo.h lib/check.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/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} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp
|
||||
|
||||
test/testtimer.o: test/testtimer.cpp lib/addoninfo.h lib/check.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/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/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/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/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/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 lib/addoninfo.h lib/check.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/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/testtokenlist.cpp
|
||||
|
||||
test/testtokenrange.o: test/testtokenrange.cpp lib/addoninfo.h lib/check.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/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 test/helpers.h
|
||||
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp
|
||||
|
||||
test/testtype.o: test/testtype.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checktype.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/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/testtype.cpp
|
||||
|
||||
test/testuninitvar.o: test/testuninitvar.cpp lib/addoninfo.h lib/check.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/platform.h lib/settings.h lib/standards.h lib/suppressions.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/testuninitvar.cpp
|
||||
|
||||
test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/addoninfo.h lib/check.h lib/checkunusedfunctions.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.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/color.h lib/config.h lib/errorlogger.h lib/errortypes.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/testunusedprivfunc.cpp
|
||||
|
||||
test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/checkunusedvar.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/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.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/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 test/fixture.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/checkvaarg.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/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.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/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/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/testvalueflow.cpp
|
||||
|
||||
test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.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/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/testvarid.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
|
||||
|
||||
tools/dmake/dmake.o: tools/dmake/dmake.cpp cli/filelister.h lib/config.h lib/pathmatch.h lib/utils.h
|
||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ tools/dmake/dmake.cpp
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
# Cppcheck addons
|
||||
|
||||
Addons are scripts that analyses Cppcheck dump files to check compatibility with secure coding standards and to locate various issues.
|
||||
|
||||
## Supported addons
|
||||
|
||||
+ [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).
|
||||
+ [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
|
||||
|
||||
### Command line interface
|
||||
|
||||
```bash
|
||||
cppcheck --addon=misc src/test.c
|
||||
```
|
||||
|
||||
It is also possible to call scripts as follows:
|
||||
```bash
|
||||
cppcheck --dump --quiet src/test.c
|
||||
python misc.py src/test.c.dump
|
||||
python misra.py --rule-texts=~/misra_rules.txt src/test.c.dump
|
||||
```
|
||||
|
||||
This allows you to add additional parameters when calling the script (for example, `--rule-texts` for `misra.py`). The full list of available parameters can be found by calling any script with the `--help` flag.
|
||||
|
||||
### GUI
|
||||
|
||||
When using the graphical interface `cppcheck-gui`, the selection and configuration of addons is carried out on the tab `Addons and tools` in the project settings (`Edit Project File`):
|
||||
|
||||

|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
{
|
||||
"RE_FILE": [".*[A-Z]"],
|
||||
"RE_NAMESPACE": {".*[A-Z]": [true, "under_scored"],
|
||||
".*\\_$": [true, "under_scored"]},
|
||||
"RE_FUNCTIONNAME": {".*\\_": [true, "camelCase"],
|
||||
".*^[a-z]": [false, "camelCase"]},
|
||||
"RE_CLASS_NAME": {".*^[A-Z]": [false, "CamelCase"],
|
||||
".*\\_": [true, "CamelCase"]},
|
||||
"RE_GLOBAL_VARNAME": {".*^([g]\\_)": [false, "g_under_scored"],
|
||||
".*[A-Z]": [true, "g_under_scored"],
|
||||
".*\\_$": [true, "g_under_scored"]},
|
||||
"RE_VARNAME": {".*^([g]\\_)": [true, "under_scored"],
|
||||
".*[A-Z]": [true, "under_scored"],
|
||||
".*\\_$": [true, "under_scored"]},
|
||||
"RE_PRIVATE_MEMBER_VARIABLE": {".*\\_$": [false, "under_scored_"],
|
||||
".*[A-Z]": [true, "under_scored_"]},
|
||||
"RE_PUBLIC_MEMBER_VARIABLE": {".*\\_$": [false, "under_scored_"],
|
||||
".*[A-Z]": [true, "under_scored_"]},
|
||||
"var_prefixes": {"uint32_t": "ui32",
|
||||
"int*": "intp"},
|
||||
"function_prefixes": {"uint16_t": "ui16",
|
||||
"uint32_t": "ui32"},
|
||||
"skip_one_char_variables": false
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
|
||||
import cppcheckdata, sys, os
|
||||
|
||||
__checkers__ = []
|
||||
|
||||
def checker(f):
|
||||
__checkers__.append(f)
|
||||
return f
|
||||
|
||||
|
||||
__errorid__ = ''
|
||||
__addon_name__ = ''
|
||||
def reportError(location, severity, message, errorId=None):
|
||||
cppcheckdata.reportError(location, severity, message, __addon_name__, errorId or __errorid__)
|
||||
|
||||
def runcheckers():
|
||||
# If there are no checkers then don't run
|
||||
if len(__checkers__) == 0:
|
||||
return
|
||||
global __addon_name__
|
||||
global __errorid__
|
||||
addon = sys.argv[0]
|
||||
parser = cppcheckdata.ArgumentParser()
|
||||
args = parser.parse_args()
|
||||
|
||||
__addon_name__ = os.path.splitext(os.path.basename(addon))[0]
|
||||
|
||||
for dumpfile in args.dumpfile:
|
||||
if not args.quiet:
|
||||
print('Checking %s...' % dumpfile)
|
||||
|
||||
data = cppcheckdata.CppcheckData(dumpfile)
|
||||
|
||||
for cfg in data.iterconfigurations():
|
||||
if not args.quiet:
|
||||
print('Checking %s, config %s...' % (dumpfile, cfg.name))
|
||||
for c in __checkers__:
|
||||
__errorid__ = c.__name__
|
||||
c(cfg, data)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 23 KiB |
@ -0,0 +1,151 @@
|
||||
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: <symbol> 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.
|
||||
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Locate casts in the code
|
||||
#
|
||||
|
||||
import cppcheck
|
||||
|
||||
@cppcheck.checker
|
||||
def cast(cfg, data):
|
||||
for token in cfg.tokenlist:
|
||||
if token.str != '(' or not token.astOperand1 or token.astOperand2:
|
||||
continue
|
||||
|
||||
# Is it a lambda?
|
||||
if token.astOperand1.str == '{':
|
||||
continue
|
||||
|
||||
# we probably have a cast.. if there is something inside the parentheses
|
||||
# there is a cast. Otherwise this is a function call.
|
||||
typetok = token.next
|
||||
if not typetok.isName:
|
||||
continue
|
||||
|
||||
# cast number => skip output
|
||||
if token.astOperand1.isNumber:
|
||||
continue
|
||||
|
||||
# void cast => often used to suppress compiler warnings
|
||||
if typetok.str == 'void':
|
||||
continue
|
||||
|
||||
cppcheck.reportError(token, 'information', 'found a cast')
|
||||
@ -0,0 +1,163 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Misc: Uncategorized checks that might be moved to some better addon later
|
||||
#
|
||||
# Example usage of this addon (scan a sourcefile main.cpp)
|
||||
# cppcheck --dump main.cpp
|
||||
# python misc.py main.cpp.dump
|
||||
|
||||
import cppcheckdata
|
||||
import sys
|
||||
import re
|
||||
|
||||
DEBUG = ('-debug' in sys.argv)
|
||||
VERIFY = ('-verify' in sys.argv)
|
||||
VERIFY_EXPECTED = []
|
||||
VERIFY_ACTUAL = []
|
||||
|
||||
def reportError(token, severity, msg, id):
|
||||
if id == 'debug' and DEBUG == False:
|
||||
return
|
||||
if VERIFY:
|
||||
VERIFY_ACTUAL.append(str(token.linenr) + ':' + id)
|
||||
else:
|
||||
cppcheckdata.reportError(token, severity, msg, 'misc', id)
|
||||
|
||||
def simpleMatch(token, pattern):
|
||||
return cppcheckdata.simpleMatch(token, pattern)
|
||||
|
||||
# Get function arguments
|
||||
def getArgumentsRecursive(tok, arguments):
|
||||
if tok is None:
|
||||
return
|
||||
if tok.str == ',':
|
||||
getArgumentsRecursive(tok.astOperand1, arguments)
|
||||
getArgumentsRecursive(tok.astOperand2, arguments)
|
||||
else:
|
||||
arguments.append(tok)
|
||||
|
||||
def getArguments(ftok):
|
||||
arguments = []
|
||||
getArgumentsRecursive(ftok.astOperand2, arguments)
|
||||
return arguments
|
||||
|
||||
def isStringLiteral(tokenString):
|
||||
return tokenString.startswith('"')
|
||||
|
||||
# check data
|
||||
def stringConcatInArrayInit(data):
|
||||
# Get all string macros
|
||||
stringMacros = []
|
||||
for cfg in data.iterconfigurations():
|
||||
for directive in cfg.directives:
|
||||
res = re.match(r'#define[ ]+([A-Za-z0-9_]+)[ ]+".*', directive.str)
|
||||
if res:
|
||||
macroName = res.group(1)
|
||||
if macroName not in stringMacros:
|
||||
stringMacros.append(macroName)
|
||||
|
||||
# Check code
|
||||
arrayInit = False
|
||||
for i in range(len(data.rawTokens)):
|
||||
if i < 2:
|
||||
continue
|
||||
tok1 = data.rawTokens[i-2].str
|
||||
tok2 = data.rawTokens[i-1].str
|
||||
tok3 = data.rawTokens[i-0].str
|
||||
if tok3 == '}':
|
||||
arrayInit = False
|
||||
elif tok1 == ']' and tok2 == '=' and tok3 == '{':
|
||||
arrayInit = True
|
||||
elif arrayInit and (tok1 in [',', '{']):
|
||||
isString2 = (isStringLiteral(tok2) or (tok2 in stringMacros))
|
||||
isString3 = (isStringLiteral(tok3) or (tok3 in stringMacros))
|
||||
if isString2 and isString3:
|
||||
reportError(data.rawTokens[i], 'style', 'String concatenation in array initialization, missing comma?', 'stringConcatInArrayInit')
|
||||
|
||||
|
||||
def implicitlyVirtual(data):
|
||||
for cfg in data.iterconfigurations():
|
||||
for function in cfg.functions:
|
||||
if function.isImplicitlyVirtual is None:
|
||||
continue
|
||||
if not function.isImplicitlyVirtual:
|
||||
continue
|
||||
reportError(function.tokenDef, 'style', 'Function \'' + function.name + '\' overrides base class function but is not marked with \'virtual\' keyword.', 'implicitlyVirtual')
|
||||
|
||||
def ellipsisStructArg(data):
|
||||
for cfg in data.iterconfigurations():
|
||||
for tok in cfg.tokenlist:
|
||||
if tok.str != '(':
|
||||
continue
|
||||
if tok.astOperand1 is None or tok.astOperand2 is None:
|
||||
continue
|
||||
if tok.astOperand2.str != ',':
|
||||
continue
|
||||
if tok.scope.type in ['Global', 'Class']:
|
||||
continue
|
||||
if tok.astOperand1.function is None:
|
||||
continue
|
||||
for argnr, argvar in tok.astOperand1.function.argument.items():
|
||||
if argnr < 1:
|
||||
continue
|
||||
if not simpleMatch(argvar.typeStartToken, '...'):
|
||||
continue
|
||||
callArgs = getArguments(tok)
|
||||
for i in range(argnr-1, len(callArgs)):
|
||||
valueType = callArgs[i].valueType
|
||||
if valueType is None:
|
||||
argStart = callArgs[i].previous
|
||||
while argStart.str != ',':
|
||||
if argStart.str == ')':
|
||||
argStart = argStart.link
|
||||
argStart = argStart.previous
|
||||
argEnd = callArgs[i]
|
||||
while argEnd.str != ',' and argEnd.str != ')':
|
||||
if argEnd.str == '(':
|
||||
argEnd = argEnd.link
|
||||
argEnd = argEnd.next
|
||||
expression = ''
|
||||
argStart = argStart.next
|
||||
while argStart != argEnd:
|
||||
expression = expression + argStart.str
|
||||
argStart = argStart.next
|
||||
reportError(tok, 'debug', 'Bailout, unknown argument type for argument \'' + expression + '\'.', 'debug')
|
||||
continue
|
||||
if valueType.pointer > 0:
|
||||
continue
|
||||
if valueType.type != 'record' and valueType.type != 'container':
|
||||
continue
|
||||
reportError(tok, 'style', 'Passing record to ellipsis function \'' + tok.astOperand1.function.name + '\'.', 'ellipsisStructArg')
|
||||
break
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
if arg in ['-debug', '-verify', '--cli']:
|
||||
continue
|
||||
|
||||
print("Checking %s..." % arg)
|
||||
data = cppcheckdata.CppcheckData(arg)
|
||||
|
||||
if VERIFY:
|
||||
VERIFY_ACTUAL = []
|
||||
VERIFY_EXPECTED = []
|
||||
for tok in data.rawTokens:
|
||||
if tok.str.startswith('//'):
|
||||
for word in tok.str[2:].split(' '):
|
||||
if word in ['stringConcatInArrayInit', 'implicitlyVirtual', 'ellipsisStructArg']:
|
||||
VERIFY_EXPECTED.append(str(tok.linenr) + ':' + word)
|
||||
|
||||
stringConcatInArrayInit(data)
|
||||
implicitlyVirtual(data)
|
||||
ellipsisStructArg(data)
|
||||
|
||||
if VERIFY:
|
||||
for expected in VERIFY_EXPECTED:
|
||||
if expected not in VERIFY_ACTUAL:
|
||||
print('Expected but not seen: ' + expected)
|
||||
sys.exit(1)
|
||||
for actual in VERIFY_ACTUAL:
|
||||
if actual not in VERIFY_EXPECTED:
|
||||
print('Not expected: ' + actual)
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(cppcheckdata.EXIT_CODE)
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,563 @@
|
||||
import cppcheckdata
|
||||
|
||||
# Holds information about an array, struct or union's element definition.
|
||||
class ElementDef:
|
||||
def __init__(self, elementType, name, valueType, dimensions = None):
|
||||
self.elementType = elementType # 'array', 'record' or 'value'
|
||||
self.name = str(name)
|
||||
self.valueType = valueType
|
||||
self.children = []
|
||||
self.dimensions = dimensions
|
||||
self.parent = None
|
||||
|
||||
self.isDesignated = False
|
||||
self.isPositional = False
|
||||
self.numInits = 0
|
||||
self.childIndex = -1
|
||||
|
||||
self.flexibleToken = None
|
||||
self.isFlexible = False
|
||||
self.structureViolationToken = None
|
||||
|
||||
def __repr__(self):
|
||||
inits = ""
|
||||
if self.isPositional:
|
||||
inits += 'P'
|
||||
if self.isDesignated:
|
||||
inits += 'D'
|
||||
if not (self.isPositional or self.isDesignated) and self.numInits == 0:
|
||||
inits += '_'
|
||||
if self.numInits > 1:
|
||||
inits += str(self.numInits)
|
||||
|
||||
attrs = ["childIndex", "elementType", "valueType"]
|
||||
return "{}({}, {}, {})".format(
|
||||
"ElementDef",
|
||||
self.getLongName(),
|
||||
inits,
|
||||
", ".join(("{}={}".format(a, repr(getattr(self, a))) for a in attrs))
|
||||
)
|
||||
|
||||
@property
|
||||
def isArray(self):
|
||||
return self.elementType == 'array'
|
||||
|
||||
@property
|
||||
def isRecord(self):
|
||||
return self.elementType == 'record'
|
||||
|
||||
@property
|
||||
def isValue(self):
|
||||
return self.elementType == 'value'
|
||||
|
||||
|
||||
def getLongName(self):
|
||||
return self.parent.getLongName() + "." + self.name if self.parent else self.name
|
||||
|
||||
def getInitDump(self):
|
||||
t = []
|
||||
if self.isPositional:
|
||||
t.append('P')
|
||||
if self.isDesignated:
|
||||
t.append('D')
|
||||
if self.numInits == 0:
|
||||
t.append('_')
|
||||
if self.numInits > 1:
|
||||
t.append(str(self.numInits))
|
||||
|
||||
myDump = "".join(t)
|
||||
|
||||
if len(self.children):
|
||||
childDumps = []
|
||||
for c in self.children:
|
||||
childDumps.append(c.getInitDump())
|
||||
if self.structureViolationToken is not None:
|
||||
myDump += "!"
|
||||
myDump += "{ " + ", ".join(childDumps) + " }"
|
||||
|
||||
return myDump
|
||||
|
||||
def addChild(self, child):
|
||||
self.children.append(child)
|
||||
child.parent = self
|
||||
|
||||
def getNextChild(self):
|
||||
self.childIndex += 1
|
||||
return self.getChildByIndex(self.childIndex)
|
||||
|
||||
def getChildByIndex(self, index):
|
||||
if self.isFlexible:
|
||||
while len(self.children) <= index:
|
||||
createChild(self, self.flexibleToken, len(self.children), None)
|
||||
return self.children[index] if 0 <= index < len(self.children) else None
|
||||
|
||||
def getChildByName(self, name):
|
||||
for c in self.children:
|
||||
if c.name == name:
|
||||
return c
|
||||
return None
|
||||
|
||||
def getNextValueElement(self, root):
|
||||
current = self
|
||||
while current != root:
|
||||
if not current.parent:
|
||||
return None
|
||||
# Get next index of parent
|
||||
i = current.parent.children.index(current) + 1
|
||||
# Next index of parent exists
|
||||
if i < len(current.parent.children):
|
||||
current = current.parent.children[i]
|
||||
return current.getFirstValueElement()
|
||||
|
||||
# Next index of parent doesn't exist. Move up
|
||||
current = current.parent
|
||||
return None
|
||||
|
||||
def getFirstValueElement(self):
|
||||
current = self
|
||||
|
||||
# Move to first child as long as children exists
|
||||
next_child = current.getChildByIndex(0)
|
||||
while next_child:
|
||||
current = next_child
|
||||
next_child = current.getChildByIndex(0)
|
||||
return current
|
||||
|
||||
def getLastValueElement(self):
|
||||
current = self
|
||||
# Move to last child as long as children exists
|
||||
while len(current.children) > 0:
|
||||
current = current.children[-1]
|
||||
return current
|
||||
|
||||
def getChildByValueElement(self, ed):
|
||||
potentialChild = ed
|
||||
while potentialChild and potentialChild not in self.children:
|
||||
potentialChild = potentialChild.parent
|
||||
|
||||
return self.children[self.children.index(potentialChild)] if potentialChild else None
|
||||
|
||||
def getEffectiveLevel(self):
|
||||
if self.parent and self.parent.elementType == "array":
|
||||
return self.parent.getEffectiveLevel() + 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def setInitialized(self, designated=False, positional=False):
|
||||
if designated:
|
||||
self.isDesignated = True
|
||||
if positional or not designated:
|
||||
self.isPositional = True
|
||||
self.numInits += 1
|
||||
|
||||
def initializeChildren(self):
|
||||
for child in self.children:
|
||||
child.setInitialized(positional=True)
|
||||
child.initializeChildren()
|
||||
|
||||
def unset(self):
|
||||
self.isDesignated = False
|
||||
self.isPositional = False
|
||||
|
||||
# Unset is always recursive
|
||||
for child in self.children:
|
||||
child.unset()
|
||||
|
||||
def markStuctureViolation(self, token):
|
||||
if self.name == '->':
|
||||
self.children[0].markStuctureViolation(token)
|
||||
elif not self.structureViolationToken:
|
||||
self.structureViolationToken = token
|
||||
|
||||
def markAsFlexibleArray(self, token):
|
||||
self.flexibleToken = token
|
||||
self.isFlexible = True
|
||||
|
||||
def markAsCurrent(self):
|
||||
if self.parent:
|
||||
if self.name == '<-':
|
||||
self.parent.childIndex = self.parent.children.index(self.children[0])
|
||||
else:
|
||||
self.parent.childIndex = self.parent.children.index(self)
|
||||
|
||||
self.parent.markAsCurrent()
|
||||
|
||||
def isAllChildrenSet(self):
|
||||
myself = len(self.children) == 0 and (self.isDesignated or self.isPositional)
|
||||
mychildren = len(self.children) > 0 and all([child.isAllChildrenSet() for child in self.children])
|
||||
return myself or mychildren
|
||||
|
||||
def isAllSet(self):
|
||||
return all([child.isPositional or child.isDesignated for child in self.children])
|
||||
|
||||
def isOnlyDesignated(self):
|
||||
return all([not child.isPositional for child in self.children])
|
||||
|
||||
def isMisra92Compliant(self):
|
||||
return self.structureViolationToken is None and all([child.isMisra92Compliant() for child in self.children])
|
||||
|
||||
def isMisra93Compliant(self):
|
||||
if self.elementType == 'array':
|
||||
result = self.isAllChildrenSet() or \
|
||||
((self.isAllSet() or
|
||||
self.isOnlyDesignated()) and
|
||||
all([not (child.isDesignated or child.isPositional) or child.isMisra93Compliant() for child in self.children]))
|
||||
return result
|
||||
elif self.elementType == 'record':
|
||||
result = all([child.isMisra93Compliant() for child in self.children])
|
||||
return result
|
||||
else:
|
||||
return True
|
||||
|
||||
def isMisra94Compliant(self):
|
||||
return self.numInits <= 1 and all([child.isMisra94Compliant() for child in self.children])
|
||||
|
||||
def isMisra95Compliant(self):
|
||||
return not self.isFlexible or all([not child.isDesignated for child in self.children])
|
||||
|
||||
# Parses the initializers and update the ElementDefs status accordingly
|
||||
class InitializerParser:
|
||||
def __init__(self):
|
||||
self.token = None
|
||||
self.root = None
|
||||
self.ed = None
|
||||
self.rootStack = []
|
||||
|
||||
def parseInitializer(self, root, token):
|
||||
self.root = root
|
||||
self.token = token
|
||||
dummyRoot = ElementDef('array', '->', self.root.valueType)
|
||||
dummyRoot.children = [self.root]
|
||||
|
||||
self.rootStack = []
|
||||
self.root = dummyRoot
|
||||
self.ed = self.root.getFirstValueElement()
|
||||
isFirstElement = False
|
||||
isDesignated = False
|
||||
|
||||
while self.token:
|
||||
if self.token.str == ',':
|
||||
self.token = self.token.astOperand1
|
||||
isFirstElement = False
|
||||
|
||||
# Designated initializer ( [2]=... or .name=... )
|
||||
elif self.token.isAssignmentOp and not self.token.valueType:
|
||||
self.popFromStackIfExitElement()
|
||||
|
||||
self.ed = getElementByDesignator(self.root, self.token.astOperand1)
|
||||
if self.ed:
|
||||
# Update root
|
||||
self.pushToRootStackAndMarkAsDesignated()
|
||||
# Make sure ed points to valueElement
|
||||
self.ed = self.ed.getFirstValueElement()
|
||||
|
||||
self.token = self.token.astOperand2
|
||||
isFirstElement = False
|
||||
isDesignated = True
|
||||
|
||||
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
|
||||
self.ed.markAsCurrent()
|
||||
self.ed = self.root.getNextChild()
|
||||
else:
|
||||
self.unwindAndContinue()
|
||||
continue
|
||||
|
||||
elif self.token.str == '{':
|
||||
nextChild = self.root.getNextChild() if self.root is not None else None
|
||||
|
||||
if nextChild:
|
||||
if nextChild.isArray or nextChild.isRecord:
|
||||
nextChild.unset()
|
||||
nextChild.setInitialized(isDesignated)
|
||||
self.ed = nextChild.getFirstValueElement()
|
||||
isDesignated = False
|
||||
elif nextChild.valueType is None:
|
||||
# No type information available - unable to check structure - assume correct initialization
|
||||
nextChild.setInitialized(isDesignated)
|
||||
self.unwindAndContinue()
|
||||
continue
|
||||
|
||||
elif self.token.astOperand1:
|
||||
# Create dummy nextChild to represent excess levels in initializer
|
||||
dummyRoot = ElementDef('array', '<-', self.root.valueType)
|
||||
dummyRoot.parent = self.root
|
||||
dummyRoot.childIndex = 0
|
||||
dummyRoot.children = [nextChild]
|
||||
nextChild.parent = dummyRoot
|
||||
|
||||
self.root.markStuctureViolation(self.token)
|
||||
|
||||
# Fake dummy as nextChild (of current root)
|
||||
nextChild = dummyRoot
|
||||
|
||||
if nextChild and self.token.astOperand1:
|
||||
self.root = nextChild
|
||||
self.token = self.token.astOperand1
|
||||
isFirstElement = True
|
||||
else:
|
||||
if self.root:
|
||||
# {}
|
||||
if self.root.name == '<-':
|
||||
self.root.parent.markStuctureViolation(self.token)
|
||||
else:
|
||||
self.root.markStuctureViolation(self.token)
|
||||
self.ed = None
|
||||
self.unwindAndContinue()
|
||||
|
||||
else:
|
||||
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()
|
||||
elif self.token.isString and self.ed.valueType and self.ed.valueType.pointer > 0:
|
||||
if self.ed.valueType.pointer - self.ed.getEffectiveLevel() == 1:
|
||||
if self.ed.parent != self.root:
|
||||
self.root.markStuctureViolation(self.token)
|
||||
self.ed.setInitialized(isDesignated)
|
||||
elif self.ed.valueType.pointer == self.ed.getEffectiveLevel():
|
||||
if(self.root.name != '->' and self.ed.parent.parent != self.root) or (self.root.name == '->' and self.root.children[0] != self.ed.parent):
|
||||
self.root.markStuctureViolation(self.token)
|
||||
else:
|
||||
self.ed.parent.setInitialized(isDesignated)
|
||||
self.ed.parent.initializeChildren()
|
||||
|
||||
else:
|
||||
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:
|
||||
if child.elementType != 'record' or self.token.valueType.type != 'record' or child.valueType.typeScope != self.token.valueType.typeScope:
|
||||
self.root.markStuctureViolation(self.token)
|
||||
|
||||
self.ed.setInitialized(isDesignated)
|
||||
|
||||
# Mark all elements up to root with positional or designated
|
||||
# (for complex designators, or missing structure)
|
||||
parent = self.ed.parent
|
||||
while parent and parent != self.root:
|
||||
parent.isDesignated = isDesignated if isDesignated and not parent.isPositional else parent.isDesignated
|
||||
parent.isPositional = not isDesignated if not isDesignated and not parent.isDesignated else parent.isPositional
|
||||
parent = parent.parent
|
||||
isDesignated = False
|
||||
|
||||
if self.token.isString and self.ed.parent.isArray:
|
||||
self.ed = self.ed.parent
|
||||
self.unwindAndContinue()
|
||||
|
||||
def pushToRootStackAndMarkAsDesignated(self):
|
||||
new = self.ed.parent
|
||||
if new != self.root:
|
||||
# Mark all elements up to self.root root as designated
|
||||
parent = new
|
||||
while parent and parent != self.root:
|
||||
parent.isDesignated = True
|
||||
parent = parent.parent
|
||||
self.rootStack.append((self.root, new))
|
||||
new.markAsCurrent()
|
||||
new.childIndex = new.children.index(self.ed) - 1
|
||||
self.root = new
|
||||
|
||||
def popFromStackIfExitElement(self):
|
||||
if len(self.rootStack) > 0 and self.rootStack[-1][1] == self.root:
|
||||
old = self.rootStack.pop()[0]
|
||||
old.markAsCurrent()
|
||||
self.root = old
|
||||
|
||||
def unwindAndContinue(self):
|
||||
while self.token:
|
||||
if self.token.astParent.astOperand1 == self.token and self.token.astParent.astOperand2:
|
||||
if self.ed:
|
||||
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.root = self.root.parent
|
||||
|
||||
if self.token.astParent is None:
|
||||
self.token = None
|
||||
break
|
||||
|
||||
def misra_9_x(self, data, rule, rawTokens = None):
|
||||
|
||||
parser = InitializerParser()
|
||||
|
||||
for variable in data.variables:
|
||||
if variable.nameToken is None:
|
||||
continue
|
||||
|
||||
nameToken = variable.nameToken
|
||||
|
||||
# Check if declaration and initialization is
|
||||
# split into two separate statements in ast.
|
||||
if nameToken.next and nameToken.next.isSplittedVarDeclEq:
|
||||
nameToken = nameToken.next.next
|
||||
|
||||
# Find declarations with initializer assignment
|
||||
eq = nameToken
|
||||
while not eq.isAssignmentOp and eq.astParent:
|
||||
eq = eq.astParent
|
||||
|
||||
# We are only looking for initializers
|
||||
if not eq.isAssignmentOp or eq.astOperand2.isName:
|
||||
continue
|
||||
|
||||
if variable.isArray or variable.isClass:
|
||||
ed = getElementDef(nameToken, rawTokens)
|
||||
# No need to check non-arrays if valueType is missing,
|
||||
# since we can't say anything useful about the structure
|
||||
# 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():
|
||||
self.reportError(nameToken, 9, 2)
|
||||
if rule == 903 and not ed.isMisra93Compliant():
|
||||
# Do not check when variable is pointer type
|
||||
type_token = variable.nameToken
|
||||
while type_token and type_token.isName:
|
||||
type_token = type_token.previous
|
||||
if type_token and type_token.str == '*':
|
||||
continue
|
||||
|
||||
self.reportError(nameToken, 9, 3)
|
||||
if rule == 904 and not ed.isMisra94Compliant():
|
||||
self.reportError(nameToken, 9, 4)
|
||||
if rule == 905 and not ed.isMisra95Compliant():
|
||||
self.reportError(nameToken, 9, 5)
|
||||
|
||||
def getElementDef(nameToken, rawTokens = None):
|
||||
if nameToken.variable.isArray:
|
||||
ed = ElementDef("array", nameToken.str, nameToken.valueType)
|
||||
createArrayChildrenDefs(ed, nameToken.astParent, nameToken.variable, rawTokens)
|
||||
elif nameToken.variable.isClass:
|
||||
ed = ElementDef("record", nameToken.str, nameToken.valueType)
|
||||
createRecordChildrenDefs(ed, nameToken.variable)
|
||||
else:
|
||||
ed = ElementDef("value", nameToken.str, nameToken.valueType)
|
||||
return ed
|
||||
|
||||
def createArrayChildrenDefs(ed, token, var, rawTokens = None):
|
||||
if token and token.str == '[':
|
||||
if rawTokens is not None:
|
||||
foundToken = next((rawToken for rawToken in rawTokens
|
||||
if rawToken.file == token.file
|
||||
and rawToken.linenr == token.linenr
|
||||
and rawToken.column == token.column
|
||||
), None)
|
||||
|
||||
if foundToken and foundToken.next and foundToken.next.str == ']':
|
||||
ed.markAsFlexibleArray(token)
|
||||
|
||||
if (token.astOperand2 is not None) and (token.astOperand2.getKnownIntValue() is not None):
|
||||
for i in range(token.astOperand2.getKnownIntValue()):
|
||||
createChild(ed, token, i, var)
|
||||
else:
|
||||
ed.markAsFlexibleArray(token)
|
||||
|
||||
|
||||
def createChild(ed, token, name, var):
|
||||
if token.astParent and token.astParent.str == '[':
|
||||
child = ElementDef("array", name, ed.valueType)
|
||||
createArrayChildrenDefs(child, token.astParent, var)
|
||||
else:
|
||||
if ed.valueType and ed.valueType.type == "record":
|
||||
child = ElementDef("record", name, ed.valueType)
|
||||
createRecordChildrenDefs(child, var)
|
||||
else:
|
||||
child = ElementDef("value", name, ed.valueType)
|
||||
|
||||
ed.addChild(child)
|
||||
|
||||
def createRecordChildrenDefs(ed, var):
|
||||
valueType = ed.valueType
|
||||
if not valueType or not valueType.typeScope:
|
||||
return
|
||||
if var is None:
|
||||
return
|
||||
typeToken = var.typeEndToken
|
||||
while typeToken and typeToken.isName:
|
||||
typeToken = typeToken.previous
|
||||
if typeToken and typeToken.str == '*':
|
||||
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)
|
||||
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: "%s %s %s" % (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 [ '.', '[' ]:
|
||||
return None
|
||||
|
||||
while token.str in [ '.', '[' ]:
|
||||
token = token.astOperand1
|
||||
|
||||
while ed and not token.isAssignmentOp:
|
||||
token = token.astParent
|
||||
|
||||
if token.str == '[':
|
||||
if not ed.isArray:
|
||||
ed.markStuctureViolation(token)
|
||||
|
||||
chIndex = -1
|
||||
if token.astOperand2 is not None:
|
||||
chIndex = token.astOperand2.getKnownIntValue()
|
||||
elif token.astOperand1 is not None:
|
||||
chIndex = token.astOperand1.getKnownIntValue()
|
||||
|
||||
ed = ed.getChildByIndex(chIndex) if chIndex is not None else None
|
||||
|
||||
elif token.str == '.':
|
||||
if not ed.isRecord:
|
||||
ed.markStuctureViolation(token)
|
||||
|
||||
name = ""
|
||||
if token.astOperand2 is not None:
|
||||
name = token.astOperand2.str
|
||||
elif token.astOperand1 is not None:
|
||||
name = token.astOperand1.str
|
||||
|
||||
ed = ed.getChildByName(name)
|
||||
|
||||
return ed
|
||||
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# cppcheck addon for naming conventions
|
||||
#
|
||||
# Example usage (variable name must start with lowercase, function name must start with uppercase):
|
||||
# $ cppcheck --dump path-to-src/
|
||||
# $ python addons/naming.py --var='[a-z].*' --function='[A-Z].*' path-to-src/*.dump
|
||||
#
|
||||
|
||||
import cppcheckdata
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
def validate_regex(expr):
|
||||
try:
|
||||
re.compile(expr)
|
||||
except re.error:
|
||||
print('Error: "{}" is not a valid regular expression.'.format(expr))
|
||||
exit(1)
|
||||
|
||||
|
||||
RE_VARNAME = None
|
||||
RE_CONSTNAME = None
|
||||
RE_PRIVATE_MEMBER_VARIABLE = None
|
||||
RE_FUNCTIONNAME = None
|
||||
for arg in sys.argv[1:]:
|
||||
if arg[:6] == '--var=':
|
||||
RE_VARNAME = arg[6:]
|
||||
validate_regex(RE_VARNAME)
|
||||
elif arg.startswith('--const='):
|
||||
RE_CONSTNAME = arg[arg.find('=')+1:]
|
||||
validate_regex(RE_CONSTNAME)
|
||||
elif arg.startswith('--private-member-variable='):
|
||||
RE_PRIVATE_MEMBER_VARIABLE = arg[arg.find('=')+1:]
|
||||
validate_regex(RE_PRIVATE_MEMBER_VARIABLE)
|
||||
elif arg[:11] == '--function=':
|
||||
RE_FUNCTIONNAME = arg[11:]
|
||||
validate_regex(RE_FUNCTIONNAME)
|
||||
|
||||
|
||||
def reportError(token, severity, msg, errorId):
|
||||
cppcheckdata.reportError(token, severity, msg, 'naming', errorId)
|
||||
|
||||
|
||||
for arg in sys.argv[1:]:
|
||||
if not arg.endswith('.dump'):
|
||||
continue
|
||||
print('Checking ' + arg + '...')
|
||||
data = cppcheckdata.CppcheckData(arg)
|
||||
|
||||
for cfg in data.iterconfigurations():
|
||||
print('Checking %s, config %s...' % (arg, cfg.name))
|
||||
if RE_VARNAME:
|
||||
for var in cfg.variables:
|
||||
if var.access == 'Private':
|
||||
continue
|
||||
if var.nameToken and not var.isConst:
|
||||
res = re.match(RE_VARNAME, var.nameToken.str)
|
||||
if not res:
|
||||
reportError(var.typeStartToken, 'style', 'Variable ' +
|
||||
var.nameToken.str + ' violates naming convention', 'varname')
|
||||
if RE_CONSTNAME:
|
||||
for var in cfg.variables:
|
||||
if var.access == 'Private':
|
||||
continue
|
||||
if var.nameToken and var.isConst:
|
||||
res = re.match(RE_CONSTNAME, var.nameToken.str)
|
||||
if not res:
|
||||
reportError(var.typeStartToken, 'style', 'Constant ' +
|
||||
var.nameToken.str + ' violates naming convention', 'constname')
|
||||
if RE_PRIVATE_MEMBER_VARIABLE:
|
||||
for var in cfg.variables:
|
||||
if (var.access is None) or var.access != 'Private':
|
||||
continue
|
||||
res = re.match(RE_PRIVATE_MEMBER_VARIABLE, var.nameToken.str)
|
||||
if not res:
|
||||
reportError(var.typeStartToken, 'style', 'Private member variable ' +
|
||||
var.nameToken.str + ' violates naming convention', 'privateMemberVariable')
|
||||
if RE_FUNCTIONNAME:
|
||||
for scope in cfg.scopes:
|
||||
if scope.type == 'Function':
|
||||
function = scope.function
|
||||
if function is not None and function.type in ('Constructor', 'Destructor', 'CopyConstructor', 'MoveConstructor'):
|
||||
continue
|
||||
res = re.match(RE_FUNCTIONNAME, scope.className)
|
||||
if not res:
|
||||
reportError(
|
||||
scope.bodyStart, 'style', 'Function ' + scope.className + ' violates naming convention', 'functionName')
|
||||
|
||||
sys.exit(cppcheckdata.EXIT_CODE)
|
||||
@ -0,0 +1,19 @@
|
||||
{
|
||||
"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",
|
||||
"uint32_t": "ui32"},
|
||||
"skip_one_char_variables": false
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"script":"namingng.py",
|
||||
"args":[
|
||||
"--configfile=namingng.config.json"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,419 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# 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/
|
||||
# $ python namingng.py test.c.dump
|
||||
#
|
||||
# JSON format:
|
||||
#
|
||||
# {
|
||||
# "RE_VARNAME": ["[a-z]*[a-zA-Z0-9_]*\\Z"],
|
||||
# "RE_PRIVATE_MEMBER_VARIABLE": null,
|
||||
# "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"}
|
||||
# }
|
||||
#
|
||||
# RE_VARNAME, RE_PRIVATE_MEMBER_VARIABLE and RE_FUNCTIONNAME are regular expressions to cover the basic names
|
||||
# In var_prefixes and function_prefixes there are the variable-type/prefix pairs
|
||||
|
||||
import cppcheckdata
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
import json
|
||||
|
||||
# Auxiliary class
|
||||
class DataStruct:
|
||||
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 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):
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
if have_error:
|
||||
sys.exit(1)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def evalExpr(conf, exp, mockToken, msgType):
|
||||
report_as_error = False
|
||||
msg = msgType + ' ' + mockToken.str + ' violates naming convention'
|
||||
|
||||
if isinstance(conf, dict):
|
||||
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:
|
||||
print("invalid config value for 'case': '%s'"%use_case,file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
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,column=0):
|
||||
reportNamingError(directive,msg,errorId,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
|
||||
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(include_guard_header_re,directive.file):
|
||||
phase = -1
|
||||
continue
|
||||
|
||||
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 == 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):
|
||||
conf = loadConfig(configfile)
|
||||
|
||||
if conf.include_guard:
|
||||
global include_guard_header_re
|
||||
include_guard_header_re = conf.include_guard.get('RE_HEADERFILE',"[^/].*\\.h\\Z")
|
||||
|
||||
for afile in dumpfiles:
|
||||
if not afile[-5:] == '.dump':
|
||||
continue
|
||||
if not args.cli:
|
||||
print('Checking ' + afile + '...')
|
||||
data = cppcheckdata.CppcheckData(afile)
|
||||
process_data(conf,data)
|
||||
|
||||
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')
|
||||
|
||||
def check_variable_naming(conf,cfg):
|
||||
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 args.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):
|
||||
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 args.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):
|
||||
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(include_guard_header_re,fn)]
|
||||
|
||||
for cfg in data.configurations:
|
||||
if not args.cli:
|
||||
print('Checking config %s...' % cfg.name)
|
||||
if conf.variable:
|
||||
check_variable_naming(conf,cfg)
|
||||
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)
|
||||
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 = cppcheckdata.ArgumentParser()
|
||||
parser.add_argument("--debugprint", action="store_true", default=False,
|
||||
help="Add debug prints")
|
||||
parser.add_argument("--configfile", type=str, default="namingng.config.json",
|
||||
help="Naming check config file")
|
||||
|
||||
args = parser.parse_args()
|
||||
process(args.dumpfile, args.configfile)
|
||||
|
||||
sys.exit(0)
|
||||
@ -0,0 +1,12 @@
|
||||
import cppcheckdata, cppcheck, runpy, sys, os
|
||||
|
||||
if __name__ == '__main__':
|
||||
addon = sys.argv[1]
|
||||
__addon_name__ = os.path.splitext(os.path.basename(addon))[0]
|
||||
sys.argv.pop(0)
|
||||
|
||||
runpy.run_path(addon, run_name='__main__')
|
||||
|
||||
# Run registered checkers
|
||||
cppcheck.runcheckers()
|
||||
sys.exit(cppcheckdata.EXIT_CODE)
|
||||
@ -0,0 +1,30 @@
|
||||
// To test:
|
||||
// ~/cppcheck/cppcheck --dump misc-test.cpp && python ../misc.py -verify misc-test.cpp.dump
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Warn about string concatenation in array initializers..
|
||||
const char *a[] = {"a" "b"}; // stringConcatInArrayInit
|
||||
const char *b[] = {"a","b" "c"}; // stringConcatInArrayInit
|
||||
#define MACRO "MACRO"
|
||||
const char *c[] = { MACRO "text" }; // stringConcatInArrayInit
|
||||
|
||||
|
||||
// Function is implicitly virtual
|
||||
class base {
|
||||
virtual void dostuff(int);
|
||||
};
|
||||
|
||||
class derived : base {
|
||||
void dostuff(int); // implicitlyVirtual
|
||||
};
|
||||
|
||||
|
||||
// Pass struct to ellipsis function
|
||||
struct {int x;int y;} s;
|
||||
void ellipsis(int x, ...);
|
||||
void foo(std::vector<std::string> v) {
|
||||
ellipsis(321, s); // ellipsisStructArg
|
||||
ellipsis(321, v[0]); // ellipsisStructArg
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
|
||||
struct S {
|
||||
uint32_t some[100];
|
||||
};
|
||||
|
||||
void foo( void )
|
||||
{
|
||||
if (((S *)0x8000)->some[0] != 0U) { }
|
||||
}
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
struct expression {
|
||||
int nargs;
|
||||
struct expression *args[3];
|
||||
};
|
||||
|
||||
struct expression plvar = {0};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
|
||||
// #11793
|
||||
|
||||
typedef struct pfmlib_pmu {
|
||||
int flags ;
|
||||
int (*get_event_encoding[10])(void* this, pfmlib_event_desc_t* e);
|
||||
} pfmlib_pmu_t ;
|
||||
|
||||
pfmlib_pmu_t sparc_ultra3_support = { .flags = 0 };
|
||||
@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
|
||||
|
||||
/* This is the representation of the expressions to determine the
|
||||
plural form. */
|
||||
struct expression
|
||||
{
|
||||
int nargs; /* Number of arguments. */
|
||||
union
|
||||
{
|
||||
unsigned long int num; /* Number value for `num'. */
|
||||
struct expression *args[3]; /* Up to three arguments. */
|
||||
} val;
|
||||
};
|
||||
|
||||
|
||||
struct expression GERMANIC_PLURAL =
|
||||
{
|
||||
.nargs = 2,
|
||||
.val =
|
||||
{
|
||||
.args =
|
||||
{
|
||||
[0] = (struct expression *) &plvar,
|
||||
[1] = (struct expression *) &plone
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
|
||||
struct ConDesDesc {
|
||||
unsigned Order;
|
||||
unsigned Import;
|
||||
};
|
||||
|
||||
// cppcheck-suppress misra-config
|
||||
static ConDesDesc ConDes[CD_TYPE_COUNT] = {
|
||||
{ 0, 0 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
|
||||
struct _boardcnf_ch {
|
||||
// cppcheck-suppress misra-config
|
||||
uint8_t ddr_density[CS_CNT];
|
||||
uint64_t ca_swap;
|
||||
};
|
||||
|
||||
struct _boardcnf {
|
||||
|
||||
uint16_t dqdm_dly_r;
|
||||
// cppcheck-suppress misra-config
|
||||
struct _boardcnf_ch ch[DRAM_CH_CNT];
|
||||
};
|
||||
|
||||
static const struct _boardcnf boardcnfs[1] = {
|
||||
{
|
||||
0x0a0,
|
||||
{
|
||||
{ {0x02, 0x02}, 0x00345201 },
|
||||
{ {0x02, 0x02}, 0x00302154 }
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
typedef struct _tGames
|
||||
{
|
||||
char magicdirname[10];
|
||||
unsigned int expectedmask;
|
||||
unsigned char pictureorder[3];
|
||||
} tGames;
|
||||
|
||||
static const tGames games[1]={
|
||||
{"Pawn", 1, {0,1,2}}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
|
||||
|
||||
static const struct id3_frametype wordlist[] =
|
||||
{
|
||||
{0, "Encryption method registration"},
|
||||
{1, "Popularimeter"},
|
||||
};
|
||||
|
||||
@ -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 } }
|
||||
};
|
||||
@ -0,0 +1,3 @@
|
||||
|
||||
#line 3 "<stdout>"
|
||||
typedef int8_t flex_int8_t;
|
||||
@ -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
|
||||
};
|
||||
@ -0,0 +1,52 @@
|
||||
// Test with command:
|
||||
// ./cppcheck --enable=information --enable=style --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c
|
||||
|
||||
#include "misra-ctu-test.h"
|
||||
|
||||
extern MISRA_2_3_A misra_2_3_a;
|
||||
|
||||
x = MISRA_2_5_OK_1;
|
||||
|
||||
// cppcheck-suppress misra-c2012-2.3
|
||||
// cppcheck-suppress misra-c2012-5.6
|
||||
typedef int MISRA_5_6_VIOLATION;
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.7
|
||||
struct misra_5_7_violation_t {
|
||||
int x; // cppcheck-suppress unusedStructMember
|
||||
};
|
||||
static misra_5_7_violation_t misra_5_7_use_type_1;
|
||||
|
||||
// #11443 - FP
|
||||
static struct
|
||||
{ // no warning
|
||||
uint16_t x; // cppcheck-suppress unusedStructMember
|
||||
} misra_5_7_false_positive_1;
|
||||
|
||||
// cppcheck-suppress misra-c2012-8.4
|
||||
// cppcheck-suppress misra-c2012-5.8
|
||||
int misra_5_8_var1;
|
||||
// cppcheck-suppress misra-c2012-8.4
|
||||
// cppcheck-suppress misra-c2012-5.8
|
||||
int misra_5_8_var2;
|
||||
// cppcheck-suppress misra-c2012-5.8
|
||||
static void misra_5_8_f(void) {}
|
||||
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.9
|
||||
static int misra_5_9_count;
|
||||
// cppcheck-suppress misra-c2012-5.9
|
||||
static void misra_5_8_foo(void) {}
|
||||
|
||||
// cppcheck-suppress misra-c2012-8.5
|
||||
extern int misra_8_5;
|
||||
|
||||
// cppcheck-suppress misra-c2012-8.4
|
||||
// cppcheck-suppress misra-c2012-8.6
|
||||
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(); }
|
||||
@ -0,0 +1,59 @@
|
||||
// Test with command:
|
||||
// ./cppcheck --enable=information --enable=style --addon=misra --inline-suppr addons/test/misra/misra-ctu-*-test.c
|
||||
|
||||
#include "misra-ctu-test.h"
|
||||
|
||||
extern MISRA_2_3_B misra_2_3_b;
|
||||
|
||||
x = MISRA_2_5_OK_2;
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.6
|
||||
typedef int MISRA_5_6_VIOLATION;
|
||||
static MISRA_5_6_VIOLATION misra_5_6_x;
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.7
|
||||
struct misra_5_7_violation_t {
|
||||
int x; // cppcheck-suppress unusedStructMember
|
||||
};
|
||||
static misra_5_7_violation_t misra_5_7_use_type_2;
|
||||
|
||||
// #11443 - FP
|
||||
static struct
|
||||
{ // no warning
|
||||
uint16_t x; // cppcheck-suppress unusedStructMember
|
||||
} misra_5_7_false_positive_2;
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.8
|
||||
static int misra_5_8_var1;
|
||||
// cppcheck-suppress misra-c2012-8.4
|
||||
// cppcheck-suppress misra-c2012-5.8
|
||||
void misra_5_8_f(void) {
|
||||
// cppcheck-suppress [misra-c2012-5.8, unusedVariable]
|
||||
char misra_5_8_var2;
|
||||
}
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.9
|
||||
static int misra_5_9_count;
|
||||
// cppcheck-suppress misra-c2012-5.9
|
||||
static void misra_5_8_foo(void) {}
|
||||
|
||||
// cppcheck-suppress misra-c2012-8.5
|
||||
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) {}
|
||||
static void misra_8_7_caller(void) {
|
||||
misra_8_7();
|
||||
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 };
|
||||
@ -0,0 +1,23 @@
|
||||
|
||||
|
||||
typedef int MISRA_2_3_A;
|
||||
typedef int MISRA_2_3_B;
|
||||
typedef int MISRA_2_3_VIOLATION; // cppcheck-suppress misra-c2012-2.3
|
||||
|
||||
// cppcheck-suppress misra-c2012-2.4
|
||||
struct misra_2_4_violation_t {
|
||||
int x;
|
||||
};
|
||||
|
||||
static inline void misra_5_9_exception(void) {}
|
||||
|
||||
void misra_8_7_external(void);
|
||||
|
||||
#define MISRA_2_5_OK_1 1
|
||||
#define MISRA_2_5_OK_2 2
|
||||
// cppcheck-suppress misra-c2012-2.5
|
||||
#define MISRA_2_5_VIOLATION 0
|
||||
|
||||
// #12362
|
||||
extern void misra_8_7_compliant( void );
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
// To test:
|
||||
// ../../cppcheck --suppressions-list=suppressions.txt --dump misra-suppressions*-test.c && python ../misra.py misra-suppressions*-test.c.dump
|
||||
// There should be no violations reported
|
||||
|
||||
// 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 <stdio.h> //21.6
|
||||
|
||||
extern int misra_5_2_var_hides_var______31x;//8.4
|
||||
static int misra_5_2_var_hides_var______31y;//5.2
|
||||
static int misra_5_2_function_hides_var_31x;
|
||||
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:
|
||||
{
|
||||
do
|
||||
{
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
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()); //17.3
|
||||
}
|
||||
}
|
||||
// cppcheck-suppress-end misra-c2012-16.4
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
// To test:
|
||||
// ../../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
|
||||
};
|
||||
struct misra_5_2_field_hides_field__63y { //5.2
|
||||
int misra_5_2_field_hides_field1_31x;
|
||||
int misra_5_2_field_hides_field1_31y;//5.2
|
||||
};
|
||||
const char *s41_1 = "\x41g"; // 4.1 8.4
|
||||
const char *s41_2 = "\x41\x42"; // 8.4
|
||||
|
||||
// cppcheck-suppress misra-c2012-5.7
|
||||
struct misra_5_7_violation_t {
|
||||
int x;
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
// To test:
|
||||
// ~/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 buf1[1] = {a};
|
||||
const char c = '0';
|
||||
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) {
|
||||
a = (((uint64_t)0xFF) << 32);
|
||||
}
|
||||
|
||||
@ -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 <stdint.h>
|
||||
|
||||
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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
||||
// #8441
|
||||
class C {
|
||||
int a;
|
||||
int b;
|
||||
C(void) : a(1), b(1) { c; }
|
||||
};
|
||||
|
||||
class misra_21_1_C {
|
||||
public:
|
||||
misra_21_1_C operator=(const misra_21_1_C &);
|
||||
};
|
||||
|
||||
class C2 {
|
||||
public:
|
||||
C2(void);
|
||||
private:
|
||||
void* f;
|
||||
};
|
||||
C2::C2(void) : f(NULL) {}
|
||||
|
||||
static void test_misra_21_1_crash(void)
|
||||
{
|
||||
auto misra_21_1_C a, b; // 12.3
|
||||
a = b;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
#ifndef MISRA_TEST_H
|
||||
#define MISRA_TEST_H
|
||||
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);
|
||||
#endif // MISRA_TEST_H
|
||||
@ -0,0 +1,5 @@
|
||||
Appendix A Summary of guidelines
|
||||
Rule 1.1
|
||||
Text of rule 1.1
|
||||
Rule 1.2
|
||||
Text of rule 1.2
|
||||
@ -0,0 +1,5 @@
|
||||
Appendix A Summary of guidelines
|
||||
Rule 1.1
|
||||
Text of rule 1.1, utf8 test: ∑
|
||||
Rule 1.2
|
||||
Text of rule 1.2
|
||||
@ -0,0 +1,22 @@
|
||||
Appendix A Summary of guidelines
|
||||
Rule 3.1 Required
|
||||
R3.1 text.
|
||||
Rule 4.1 Required
|
||||
R4.1 text.
|
||||
Rule 10.4 Mandatory
|
||||
R10.4 text.
|
||||
Rule 11.5 Advisory
|
||||
R11.5 text.
|
||||
Rule 15.5 Advisory
|
||||
R15.5 text.
|
||||
Rule 15.6 Required
|
||||
R15.6 text.
|
||||
Rule 17.7 Required
|
||||
R17.7 text.
|
||||
Rule 20.1 Advisory
|
||||
R20.1 text.
|
||||
Rule 21.3 Required
|
||||
R21.3 text.
|
||||
Rule 21.4
|
||||
R21.4 text.
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
Appendix A Summary of guidelines
|
||||
|
||||
|
||||
Rule 1.1
|
||||
Add this rule and parse to next, skipping empty lines.
|
||||
|
||||
|
||||
|
||||
|
||||
Rule 1.2
|
||||
Rule text.
|
||||
|
||||
Rule 1.3
|
||||
There is 3 rules.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
Appendix A Summary of guidelines
|
||||
|
||||
Rule 1.1
|
||||
Multiple
|
||||
lines
|
||||
text.
|
||||
Rule 1.2
|
||||
Multiple lines
|
||||
text.
|
||||
Rule 1.3 Required
|
||||
Multiple
|
||||
lines
|
||||
text.
|
||||
Rule 1.4
|
||||
Should
|
||||
Starts from lowercase letter.
|
||||
Rule 1.5
|
||||
Should
|
||||
starts from lowercase letter.
|
||||
Rule 1.6
|
||||
Can
|
||||
|
||||
contain empty lines.
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
Here can be any text.
|
||||
|
||||
Incorrect definitions:
|
||||
Appendix A
|
||||
Appendix A Summary:
|
||||
|
||||
Rule 1.1
|
||||
Error!
|
||||
|
||||
Here we go:
|
||||
Appendix A Summary of guidelines
|
||||
|
||||
Rule 1.2
|
||||
Rule text.
|
||||
|
||||
Stop parsing after this line:
|
||||
Appendix B
|
||||
|
||||
Rule 1.3
|
||||
Error!
|
||||
@ -0,0 +1,6 @@
|
||||
misra-c2012-21.6:*/misra-suppressions1-test.c:7
|
||||
misra-c2012-17.3
|
||||
misra-c2012-8.4:*/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
|
||||
@ -0,0 +1,177 @@
|
||||
# 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
|
||||
|
||||
import os
|
||||
import pytest
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from .util import dump_create, dump_remove, convert_json_output
|
||||
|
||||
|
||||
TEST_SOURCE_FILES = ['./addons/test/misra/misra-test.c']
|
||||
|
||||
|
||||
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")
|
||||
def checker():
|
||||
from addons.misra import MisraChecker, MisraSettings, get_args_parser
|
||||
parser = get_args_parser()
|
||||
args = parser.parse_args([])
|
||||
settings = MisraSettings(args)
|
||||
return MisraChecker(settings)
|
||||
|
||||
|
||||
@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)
|
||||
|
||||
|
||||
def test_loadRuleTexts_empty_lines(checker):
|
||||
checker.loadRuleTexts("./addons/test/misra/misra_rules_empty_lines.txt")
|
||||
assert(len(checker.ruleTexts) == 3)
|
||||
assert(len(checker.ruleTexts[102].text) == len("Rule text."))
|
||||
|
||||
|
||||
def test_loadRuleTexts_mutiple_lines(checker):
|
||||
checker.loadRuleTexts("./addons/test/misra/misra_rules_multiple_lines.txt")
|
||||
assert(checker.ruleTexts[101].text == "Multiple lines text.")
|
||||
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[106].text == "Can contain empty lines.")
|
||||
|
||||
|
||||
def test_verifyRuleTexts(checker, capsys):
|
||||
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
|
||||
checker.verifyRuleTexts()
|
||||
captured = capsys.readouterr().out
|
||||
assert("21.3" not in captured)
|
||||
assert("1.3" in captured)
|
||||
|
||||
|
||||
def test_rules_misra_severity(checker):
|
||||
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
|
||||
assert(checker.ruleTexts[1004].misra_severity == 'Mandatory')
|
||||
assert(checker.ruleTexts[401].misra_severity == 'Required')
|
||||
assert(checker.ruleTexts[1505].misra_severity == 'Advisory')
|
||||
assert(checker.ruleTexts[2104].misra_severity == '')
|
||||
|
||||
|
||||
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")
|
||||
captured = capsys.readouterr()
|
||||
captured = captured.out.splitlines()
|
||||
sys.argv.remove("--cli")
|
||||
json_output = convert_json_output(captured)
|
||||
assert("Mandatory" in json_output['c2012-10.4'][0]['extra'])
|
||||
assert("Required" in json_output['c2012-21.3'][0]['extra'])
|
||||
assert("Advisory" in json_output['c2012-20.1'][0]['extra'])
|
||||
|
||||
|
||||
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 remove_misra_config(captured))
|
||||
assert("(warning)" not in captured)
|
||||
assert("(style)" in captured)
|
||||
|
||||
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 remove_misra_config(captured))
|
||||
assert("(warning)" not in captured)
|
||||
assert("(style)" not in captured)
|
||||
assert("(custom-severity)" in captured)
|
||||
|
||||
def test_rules_suppression(checker, capsys):
|
||||
test_sources = ["addons/test/misra/misra-suppressions1-test.c",
|
||||
"addons/test/misra/misra-suppressions2-test.c"]
|
||||
|
||||
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","--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",
|
||||
"--verify-rule-texts",
|
||||
"-t=foo", "--template=foo",
|
||||
"--suppress-rules=15.1",
|
||||
"--quiet",
|
||||
"--cli",
|
||||
"--no-summary",
|
||||
"--show-suppressed-rules",
|
||||
"-P=src/", "--file-prefix=src/",
|
||||
"--severity=misra-warning"]
|
||||
# Arguments with expected SystemExit
|
||||
args_exit = ["--non-exists", "--non-exists-param=42", "-h", "--help"]
|
||||
|
||||
from addons.misra import get_args_parser
|
||||
|
||||
# sys.argv contains all pytest arguments - so clear all existing arguments first and restore afterwards
|
||||
sys_argv_old = sys.argv
|
||||
sys.argv = [sys.argv[0]]
|
||||
|
||||
try:
|
||||
for arg in args_exit:
|
||||
sys.argv.append(arg)
|
||||
with pytest.raises(SystemExit):
|
||||
parser = get_args_parser()
|
||||
parser.parse_args()
|
||||
sys.argv.remove(arg)
|
||||
|
||||
for arg in args_ok:
|
||||
sys.argv.append(arg)
|
||||
try:
|
||||
parser = get_args_parser()
|
||||
parser.parse_args()
|
||||
except SystemExit:
|
||||
pytest.fail("Unexpected SystemExit with '%s'" % arg)
|
||||
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
|
||||
@ -0,0 +1,5 @@
|
||||
// To test:
|
||||
// ~/cppcheck/cppcheck --dump naming_test.c && python ../naming.py --var='[a-z].*' --function='[a-z].*' naming_test.c.dump
|
||||
|
||||
// Should not crash when there is no name
|
||||
void func(int number, int);
|
||||
@ -0,0 +1,11 @@
|
||||
// To test:
|
||||
// ~/cppcheck/cppcheck --dump naming_test.cpp && python ../naming.py --var='[a-z].*' --function='[a-z].*' naming_test.cpp.dump
|
||||
|
||||
// No error for mismatching Constructor/Destructor names should be issued, they can not be changed.
|
||||
class TestClass1
|
||||
{
|
||||
TestClass1() {}
|
||||
~TestClass1() {}
|
||||
TestClass1(const TestClass1 &) {}
|
||||
TestClass1(TestClass1 &&) {}
|
||||
};
|
||||
@ -0,0 +1,33 @@
|
||||
// To test:
|
||||
// ../../cppcheck --suppressions-list=suppressions.txt --dump misra-suppressions*-test.c && python ../misra.py misra-suppressions*-test.c.dump
|
||||
// There should be no violations reported
|
||||
|
||||
// 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
|
||||
#include <stdio.h> //21.6
|
||||
|
||||
extern int misra_5_2_var_hides_var______31x;
|
||||
static int misra_5_2_var_hides_var______31y;//5.2
|
||||
static int misra_5_2_function_hides_var_31x;
|
||||
void misra_5_2_function_hides_var_31y(void) {}//5.2
|
||||
void foo(void)
|
||||
{
|
||||
int i;
|
||||
switch(misra_5_2_func1()) //16.4 16.6
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
do
|
||||
{
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
if(misra_5_2_func3()) //14.4
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
// To test:
|
||||
// ../../cppcheck --suppressions-list=suppressions.txt --dump misra-suppressions*-test.c && python ../misra.py misra-suppressions*-test.c.dump
|
||||
// There should be no violations reported
|
||||
|
||||
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
|
||||
};
|
||||
struct misra_5_2_field_hides_field__63y { //5.2
|
||||
int misra_5_2_field_hides_field1_31x;
|
||||
int misra_5_2_field_hides_field1_31y;//5.2
|
||||
};
|
||||
const char *s41_1 = "\x41g"; // 4.1
|
||||
const char *s41_2 = "\x41\x42";
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Cppcheck - A tool for static C/C++ code analysis
|
||||
* Copyright (C) 2023 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This does not match the standard cppchek test code,
|
||||
* because I haven't figured that out yet.
|
||||
* This code does compile and run, and does demonstrate
|
||||
* the issues that the threadsafety.py addon is supposed to find.
|
||||
* It does not use threads !
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
void threadsafety_static()
|
||||
{
|
||||
// cppcheck-suppress threadsafety-threadsafety
|
||||
static unsigned int nCount = 0;
|
||||
|
||||
nCount++;
|
||||
printf("%d\n", nCount);
|
||||
}
|
||||
|
||||
void threadsafety_call()
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
// cppcheck-suppress threadsafety-unsafe-call
|
||||
printf("%s\n", ctime(&now));
|
||||
}
|
||||
|
||||
// cppcheck --addon=threadsafety
|
||||
// should *not* find any problems with this function.
|
||||
void threadsafety_safecall()
|
||||
{
|
||||
char haystack[] = "alphabet";
|
||||
char needle[] = "Alph";
|
||||
char* found = strcasestr(haystack, needle);
|
||||
printf("%s %sin %s\n", needle, found ? "" : "not ", haystack);
|
||||
}
|
||||
|
||||
int main() {
|
||||
threadsafety_static();
|
||||
|
||||
threadsafety_call();
|
||||
|
||||
threadsafety_safecall();
|
||||
|
||||
threadsafety_static();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
struct Dummy {
|
||||
int x;
|
||||
};
|
||||
void func() {
|
||||
// cppcheck-suppress threadsafety-threadsafety
|
||||
static Dummy dummy;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
struct Dummy {
|
||||
int x;
|
||||
};
|
||||
void func() {
|
||||
// cppcheck-suppress threadsafety-threadsafety-const
|
||||
static const Dummy dummy;
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
# Helpers for pytest tests
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def find_cppcheck_binary():
|
||||
possible_locations = [
|
||||
"./cppcheck",
|
||||
"./build/bin/cppcheck",
|
||||
r".\bin\cppcheck.exe",
|
||||
]
|
||||
for location in possible_locations:
|
||||
if os.path.exists(location):
|
||||
break
|
||||
else:
|
||||
raise RuntimeError("Could not find cppcheck binary")
|
||||
|
||||
return location
|
||||
|
||||
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)
|
||||
p = subprocess.Popen(["sync"])
|
||||
p.communicate()
|
||||
|
||||
|
||||
def dump_remove(fpath):
|
||||
p = subprocess.Popen(["rm", "-f", fpath + ".dump"])
|
||||
p.communicate()
|
||||
|
||||
|
||||
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:
|
||||
try:
|
||||
json_line = json.loads(line)
|
||||
# json_output[json_line['errorId']] = json_line
|
||||
json_output.setdefault(json_line['errorId'], []).append(json_line)
|
||||
except ValueError:
|
||||
pass
|
||||
return json_output
|
||||
@ -0,0 +1,31 @@
|
||||
#ifndef __INC2038
|
||||
#define _INC2038
|
||||
|
||||
/*
|
||||
* This file defines _USE_TIME_BITS64.
|
||||
* It plays the role of a Y2038-proof glibc.
|
||||
*/
|
||||
|
||||
#define _USE_TIME_BITS64
|
||||
|
||||
/*
|
||||
* Declare just enough for clock_gettime
|
||||
*/
|
||||
|
||||
typedef int clockid_t;
|
||||
|
||||
typedef int __time_t;
|
||||
|
||||
typedef long int __syscall_slong_t;
|
||||
|
||||
struct timespec
|
||||
{
|
||||
__time_t tv_sec; /* Seconds. */
|
||||
__syscall_slong_t tv_nsec; /* Nanoseconds. */
|
||||
};
|
||||
|
||||
extern int clock_gettime(clockid_t clk_id, struct timespec *tp);
|
||||
|
||||
#define CLOCK_REALTIME 0
|
||||
|
||||
#endif /* INC2038 */
|
||||
@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
* Define _TIME_BITS unequal to 64 to trigger error
|
||||
*/
|
||||
|
||||
#define _TIME_BITS 62
|
||||
|
||||
#include "y2038-inc.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||
struct timespec *my_tp;
|
||||
|
||||
return clock_gettime(my_clk_id, &my_tp);
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
* Do not define _TIME_BITS but have _USE_TIME_BITS64 defined
|
||||
*/
|
||||
|
||||
#include "y2038-inc.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||
struct timespec *my_tp;
|
||||
|
||||
return clock_gettime(my_clk_id, &my_tp);
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
/*
|
||||
* Include bad _USE_TIME_BITS64 definition to trigger error
|
||||
*/
|
||||
|
||||
#define _TIME_BITS 64
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||
struct timespec *my_tp;
|
||||
|
||||
return clock_gettime(my_clk_id, &my_tp);
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Define _TIME_BITS equal to 64 so that glibc knows we want Y2038 support.
|
||||
*/
|
||||
|
||||
#define _TIME_BITS 64
|
||||
|
||||
#include "y2038-inc.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
clockid_t my_clk_id = CLOCK_REALTIME;
|
||||
struct timespec *my_tp;
|
||||
|
||||
return clock_gettime(my_clk_id, &my_tp);
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* C file that does not use any time functionality -> no errors should
|
||||
* be reported.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
printf("Hello");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,139 @@
|
||||
# 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-y2038.py
|
||||
#
|
||||
# Running the test with Python 3:
|
||||
# Command in cppcheck directory:
|
||||
# PYTHONPATH=./addons python3 -m pytest addons/test/test-y2038.py
|
||||
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
from addons.y2038 import check_y2038_safe
|
||||
|
||||
from .util import dump_create, dump_remove, convert_json_output
|
||||
|
||||
|
||||
TEST_SOURCE_FILES = ['./addons/test/y2038/y2038-test-1-bad-time-bits.c',
|
||||
'./addons/test/y2038/y2038-test-2-no-time-bits.c',
|
||||
'./addons/test/y2038/y2038-test-3-no-use-time-bits.c',
|
||||
'./addons/test/y2038/y2038-test-4-good.c',
|
||||
'./addons/test/y2038/y2038-test-5-good-no-time-used.c']
|
||||
|
||||
|
||||
def setup_module(module):
|
||||
sys.argv.append("--cli")
|
||||
for f in TEST_SOURCE_FILES:
|
||||
dump_create(f)
|
||||
|
||||
|
||||
def teardown_module(module):
|
||||
sys.argv.remove("--cli")
|
||||
for f in TEST_SOURCE_FILES:
|
||||
dump_remove(f)
|
||||
|
||||
|
||||
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)
|
||||
assert(is_safe is False)
|
||||
captured = capsys.readouterr()
|
||||
captured = captured.out.splitlines()
|
||||
json_output = convert_json_output(captured)
|
||||
|
||||
# Has exactly one warnings of _TIME_BITS and _USE_TIME_BITS64 kind.
|
||||
assert(len(json_output['type-bits-undef']) == 1)
|
||||
assert(len(json_output['type-bits-not-64']) == 1)
|
||||
|
||||
# There are 2 unsafe calls in test source and 3 in y2038-in.h
|
||||
unsafe_calls = json_output['unsafe-call']
|
||||
assert(len([c for c in unsafe_calls if c['file'].endswith('h')]) == 3)
|
||||
assert(len([c for c in unsafe_calls if c['file'].endswith('c')]) == 0)
|
||||
|
||||
|
||||
def test_2_no_time_bits(capsys):
|
||||
is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-2-no-time-bits.c.dump', quiet=True)
|
||||
assert(is_safe is False)
|
||||
captured = capsys.readouterr()
|
||||
captured = captured.out.splitlines()
|
||||
json_output = convert_json_output(captured)
|
||||
|
||||
# _USE_TIME_BITS64 defined in y2038-inc.h header, but there is not
|
||||
# _TIME_BITS definition. Here must be appropriate warning.
|
||||
assert(len(json_output['type-bits-undef']) == 1)
|
||||
assert(json_output.get('type-bits-not-64') is None)
|
||||
|
||||
# y2038-in.h still has y2038-unsafe calls.
|
||||
unsafe_calls = json_output['unsafe-call']
|
||||
assert(len([c for c in unsafe_calls if c['file'].endswith('h')]) == 3)
|
||||
|
||||
|
||||
def test_3_no_use_time_bits(capsys):
|
||||
is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-3-no-use-time-bits.c.dump', quiet=True)
|
||||
assert(is_safe is False)
|
||||
captured = capsys.readouterr()
|
||||
captured = captured.out.splitlines()
|
||||
json_output = convert_json_output(captured)
|
||||
|
||||
# Included bad _USE_TIME_BITS64 definition must trigger the errors.
|
||||
unsafe_calls = json_output['unsafe-call']
|
||||
assert(len(unsafe_calls) == 2)
|
||||
|
||||
|
||||
def test_4_good(capsys):
|
||||
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()
|
||||
captured = captured.out.splitlines()
|
||||
json_output = convert_json_output(captured)
|
||||
|
||||
# Defined _TIME_BITS equal to 64 so that glibc knows we want Y2038 support.
|
||||
# There are no warnings from C sources.
|
||||
unsafe_calls = json_output['unsafe-call']
|
||||
assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0)
|
||||
|
||||
|
||||
def test_5_good(capsys):
|
||||
is_safe = check_y2038_safe('./addons/test/y2038/y2038-test-5-good-no-time-used.c.dump', quiet=True)
|
||||
assert(is_safe is True)
|
||||
captured = capsys.readouterr()
|
||||
captured = captured.out.splitlines()
|
||||
json_output = convert_json_output(captured)
|
||||
|
||||
# There are no warnings from C sources.
|
||||
if 'unsafe-call' in json_output:
|
||||
unsafe_calls = json_output['unsafe-call']
|
||||
assert(len([c for c in unsafe_calls if c['file'].endswith('.c')]) == 0)
|
||||
|
||||
|
||||
def test_arguments_regression():
|
||||
args_ok = ["-t=foo", "--template=foo",
|
||||
"-q", "--quiet",
|
||||
"--cli"]
|
||||
# Arguments with expected SystemExit
|
||||
args_exit = ["--non-exists", "--non-exists-param=42", "-h", "--help"]
|
||||
|
||||
from addons.y2038 import get_args_parser
|
||||
|
||||
# sys.argv contains all pytest arguments - so clear all existing arguments first and restore afterwards
|
||||
sys_argv_old = sys.argv
|
||||
sys.argv = [sys.argv[0]]
|
||||
|
||||
try:
|
||||
for arg in args_exit:
|
||||
sys.argv.append(arg)
|
||||
with pytest.raises(SystemExit):
|
||||
parser = get_args_parser()
|
||||
parser.parse_args()
|
||||
sys.argv.remove(arg)
|
||||
|
||||
for arg in args_ok:
|
||||
sys.argv.append(arg)
|
||||
try:
|
||||
parser = get_args_parser()
|
||||
parser.parse_args()
|
||||
except SystemExit:
|
||||
pytest.fail("Unexpected SystemExit with '%s'" % arg)
|
||||
sys.argv.remove(arg)
|
||||
finally:
|
||||
sys.argv = sys_argv_old
|
||||
@ -0,0 +1,350 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
cppcheck addon for threadsafety detection.
|
||||
|
||||
This script analyses Cppcheck dump files to locate threadsafety issues.
|
||||
It warns about
|
||||
- static local objects
|
||||
- MT-Unsafe symbols listed in the "Attributes" sections of man pages.
|
||||
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
import cppcheckdata
|
||||
|
||||
# --------------------------------
|
||||
# List of MT-Unsafe identifiers
|
||||
# --------------------------------
|
||||
|
||||
# This is Work In Progress.
|
||||
# Eventually it should contain all identifiers (types
|
||||
# and functions) which are MT-Unsafe.
|
||||
|
||||
# The script tools/MT-Unsafe.py can help to re-generate this list.
|
||||
# It reads a man-page tree and report identifiers marked as "MT-Unsafe"
|
||||
# (see man 7 attributes for what this means), eg
|
||||
# MT-Unsafe.py /usr/share/man/man3
|
||||
|
||||
id_MTunsafe_full = {
|
||||
# MT-Unsafe types by definition
|
||||
# 'pthread_t',
|
||||
# Types marked MT-Unsafe
|
||||
'const:env',
|
||||
'const:hostid',
|
||||
'const:mallopt',
|
||||
'const:sigintr',
|
||||
'race:LogMask',
|
||||
'race:asctime',
|
||||
'race:crypt',
|
||||
'race:crypt_gensalt',
|
||||
'race:cuserid/!string',
|
||||
'race:dirstream',
|
||||
'race:drand48',
|
||||
'race:ecvt',
|
||||
'race:exit',
|
||||
'race:fcvt',
|
||||
'race:fgetgrent',
|
||||
'race:fgetpwent',
|
||||
'race:fgetspent',
|
||||
'race:fsent',
|
||||
'race:getdate',
|
||||
'race:getlogin',
|
||||
'race:getopt',
|
||||
'race:getspent',
|
||||
'race:getspnam',
|
||||
'race:grent',
|
||||
'race:grgid',
|
||||
'race:grnam',
|
||||
'race:hostbyaddr',
|
||||
'race:hostbyname',
|
||||
'race:hostbyname2',
|
||||
'race:hostent',
|
||||
'race:hsearch',
|
||||
'race:l64a',
|
||||
'race:localeconv',
|
||||
'race:mbrlen/!ps',
|
||||
'race:mbrtowc/!ps',
|
||||
'race:mbsnrtowcs/!ps',
|
||||
'race:mbsrtowcs/!ps',
|
||||
'race:mcheck',
|
||||
'race:mntentbuf',
|
||||
'race:netbyaddr',
|
||||
'race:netbyname',
|
||||
'race:netent',
|
||||
'race:netgrent',
|
||||
'race:protobyname',
|
||||
'race:protobynumber',
|
||||
'race:protoent',
|
||||
'race:ptsname',
|
||||
'race:pwent',
|
||||
'race:pwnam',
|
||||
'race:pwuid',
|
||||
'race:qecvt',
|
||||
'race:qfcvt',
|
||||
'race:servbyname',
|
||||
'race:servbyport',
|
||||
'race:servent',
|
||||
'race:sgetspent',
|
||||
'race:signgam',
|
||||
'race:stdin',
|
||||
'race:stdout',
|
||||
'race:streams',
|
||||
'race:strerror',
|
||||
'race:strsignal',
|
||||
'race:strtok',
|
||||
'race:tmbuf',
|
||||
'race:tmpnam/!s',
|
||||
'race:ttyent',
|
||||
'race:ttyname',
|
||||
'race:utent',
|
||||
'race:wcrtomb/!ps',
|
||||
'race:wcsnrtombs/!ps',
|
||||
'race:wcsrtombs/!ps',
|
||||
'sig:ALRM',
|
||||
'sig:SIGCHLD/linux',
|
||||
# APIs marked MT-Unsafe
|
||||
'asctime',
|
||||
'clearenv',
|
||||
'ctime',
|
||||
'cuserid',
|
||||
'drand48',
|
||||
'ecvt',
|
||||
'encrypt',
|
||||
'endfsent',
|
||||
'endgrent',
|
||||
'endhostent',
|
||||
'endnetent',
|
||||
'endnetgrent',
|
||||
'endprotoent',
|
||||
'endpwent',
|
||||
'endservent',
|
||||
'endspent',
|
||||
'endttyent',
|
||||
'endusershell',
|
||||
'endutent',
|
||||
'erand48',
|
||||
'error_at_line',
|
||||
'ether_aton',
|
||||
'ether_ntoa',
|
||||
'exit',
|
||||
'fcloseall',
|
||||
'fcvt',
|
||||
'fgetgrent',
|
||||
'fgetpwent',
|
||||
'fgetspent',
|
||||
'fts_children',
|
||||
'fts_read',
|
||||
'gamma',
|
||||
'gammaf',
|
||||
'gammal',
|
||||
'getaliasbyname',
|
||||
'getaliasent',
|
||||
'getchar_unlocked',
|
||||
'getdate',
|
||||
'getfsent',
|
||||
'getfsfile',
|
||||
'getfsspec',
|
||||
'getgrent',
|
||||
'getgrent_r',
|
||||
'getgrgid',
|
||||
'getgrnam',
|
||||
'gethostbyaddr',
|
||||
'gethostbyname',
|
||||
'gethostbyname2',
|
||||
'gethostent',
|
||||
'gethostent_r',
|
||||
'getlogin',
|
||||
'getlogin_r',
|
||||
'getmntent',
|
||||
'getnetbyaddr',
|
||||
'getnetbyname',
|
||||
'getnetent',
|
||||
'getnetgrent',
|
||||
'getnetgrent_r',
|
||||
'getopt',
|
||||
'getopt_long',
|
||||
'getopt_long_only',
|
||||
'getpass',
|
||||
'getprotobyname',
|
||||
'getprotobynumber',
|
||||
'getprotoent',
|
||||
'getpwent',
|
||||
'getpwent_r',
|
||||
'getpwnam',
|
||||
'getpwuid',
|
||||
'getrpcbyname',
|
||||
'getrpcbynumber',
|
||||
'getrpcent',
|
||||
'getservbyname',
|
||||
'getservbyport',
|
||||
'getservent',
|
||||
'getspent',
|
||||
'getspent_r',
|
||||
'getspnam',
|
||||
'getttyent',
|
||||
'getttynam',
|
||||
'getusershell',
|
||||
'getutent',
|
||||
'getutid',
|
||||
'getutline',
|
||||
'getwchar_unlocked',
|
||||
'glob',
|
||||
'gmtime',
|
||||
'hcreate',
|
||||
'hdestroy',
|
||||
'hsearch',
|
||||
'innetgr',
|
||||
'jrand48',
|
||||
'l64a',
|
||||
'lcong48',
|
||||
'localeconv',
|
||||
'localtime',
|
||||
'login',
|
||||
'login_tty',
|
||||
'logout',
|
||||
'logwtmp',
|
||||
'lrand48',
|
||||
'mallinfo',
|
||||
'mallinfo2',
|
||||
'mblen',
|
||||
'mbrlen',
|
||||
'mbrtowc',
|
||||
'mbsnrtowcs',
|
||||
'mbsrtowcs',
|
||||
'mbtowc',
|
||||
'mcheck',
|
||||
'mcheck_check_all',
|
||||
'mcheck_pedantic',
|
||||
'mprobe',
|
||||
'mrand48',
|
||||
'mtrace',
|
||||
'muntrace',
|
||||
'nrand48',
|
||||
'profil',
|
||||
'ptsname',
|
||||
'putchar_unlocked',
|
||||
'putenv',
|
||||
'pututline',
|
||||
'putwchar_unlocked',
|
||||
'pvalloc',
|
||||
'qecvt',
|
||||
'qfcvt',
|
||||
'rcmd',
|
||||
'rcmd_af',
|
||||
're_comp',
|
||||
're_exec',
|
||||
'readdir',
|
||||
'rexec',
|
||||
'rexec_af',
|
||||
'seed48',
|
||||
'setenv',
|
||||
'setfsent',
|
||||
'setgrent',
|
||||
'sethostent',
|
||||
'sethostid',
|
||||
'setkey',
|
||||
'setlogmask',
|
||||
'setnetent',
|
||||
'setnetgrent',
|
||||
'setprotoent',
|
||||
'setpwent',
|
||||
'setservent',
|
||||
'setspent',
|
||||
'setttyent',
|
||||
'setusershell',
|
||||
'setutent',
|
||||
'sgetspent',
|
||||
'siginterrupt',
|
||||
'sleep',
|
||||
'srand48',
|
||||
'strerror',
|
||||
'strsignal',
|
||||
'strtok',
|
||||
'tmpnam',
|
||||
'ttyname',
|
||||
'ttyslot',
|
||||
'unsetenv',
|
||||
'updwtmp',
|
||||
'utmpname',
|
||||
'valloc',
|
||||
'wcrtomb',
|
||||
'wcsnrtombs',
|
||||
'wcsrtombs',
|
||||
'wctomb',
|
||||
'wordexp'
|
||||
}
|
||||
|
||||
# From man 7 attributes
|
||||
# the full token could be feature:function/condition - we just want function.
|
||||
id_MTunsafe = [re.sub('^.*:', '', re.sub('/.*$', '', x))
|
||||
for x in id_MTunsafe_full
|
||||
]
|
||||
|
||||
|
||||
def reportError(token, severity, msg, errid): # noqa: D103
|
||||
cppcheckdata.reportError(token, severity, msg, 'threadsafety', errid)
|
||||
|
||||
|
||||
def checkstatic(data): # noqa: D103
|
||||
for var in data.variables:
|
||||
if var.isStatic and var.isLocal:
|
||||
vartype = None
|
||||
if var.isClass:
|
||||
vartype = 'object'
|
||||
else:
|
||||
vartype = 'variable'
|
||||
if var.isConst:
|
||||
if data.standards.cpp == 'c++03':
|
||||
reportError(
|
||||
var.typeStartToken,
|
||||
'warning',
|
||||
'Local constant static '
|
||||
+ vartype + "'" + var.nameToken.str
|
||||
+ "', dangerous if it is initialized"
|
||||
+ ' in parallel threads',
|
||||
'threadsafety-const')
|
||||
else:
|
||||
reportError(var.typeStartToken, 'warning',
|
||||
'Local static ' + vartype + ': '
|
||||
+ var.nameToken.str,
|
||||
'threadsafety')
|
||||
|
||||
|
||||
def check_MTunsafe(cfg):
|
||||
"""
|
||||
Look for functions marked MT-unsafe in their man pages.
|
||||
|
||||
The MT-unsafe functions are listed in id_MTunsafe (and id_MTunsafe_full).
|
||||
That section of code can be regenerated by the external script MT-Unsafe.py
|
||||
"""
|
||||
for token in cfg.tokenlist:
|
||||
if token.str in id_MTunsafe:
|
||||
reportError(token, 'warning', token.str + ' is MT-unsafe',
|
||||
'unsafe-call')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = cppcheckdata.ArgumentParser()
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet or args.cli
|
||||
|
||||
if not args.dumpfile:
|
||||
if not args.quiet:
|
||||
print('no input files.')
|
||||
sys.exit(0)
|
||||
|
||||
for dumpfile in args.dumpfile:
|
||||
# load XML from .dump file
|
||||
data = cppcheckdata.CppcheckData(dumpfile)
|
||||
|
||||
for cfg in data.iterconfigurations():
|
||||
if not args.quiet:
|
||||
srcfile = data.files[0]
|
||||
print('Checking %s, config %s...' % (srcfile, cfg.name))
|
||||
check_MTunsafe(cfg)
|
||||
checkstatic(cfg)
|
||||
|
||||
sys.exit(cppcheckdata.EXIT_CODE)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue