diff --git a/.github/workflows/CI-cygwin.yml b/.github/workflows/CI-cygwin.yml
index 91552735d74..fac0b8ac24b 100644
--- a/.github/workflows/CI-cygwin.yml
+++ b/.github/workflows/CI-cygwin.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/CI-mingw.yml b/.github/workflows/CI-mingw.yml
index 931a629deda..0cc09177965 100644
--- a/.github/workflows/CI-mingw.yml
+++ b/.github/workflows/CI-mingw.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/CI-unixish-docker.yml b/.github/workflows/CI-unixish-docker.yml
index 21d54052ef2..cacb81b6991 100644
--- a/.github/workflows/CI-unixish-docker.yml
+++ b/.github/workflows/CI-unixish-docker.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/CI-unixish.yml b/.github/workflows/CI-unixish.yml
index be7b227333c..223817b3206 100644
--- a/.github/workflows/CI-unixish.yml
+++ b/.github/workflows/CI-unixish.yml
@@ -3,508 +3,22 @@
name: CI-unixish
on:
- push:
- branches:
- - 'main'
- - 'releases/**'
- - '2.*'
- tags:
- - '2.*'
pull_request:
-permissions:
- contents: read
-
jobs:
- build_cmake_tinyxml2:
-
- strategy:
- matrix:
- os: [ubuntu-20.04, ubuntu-22.04, macos-13]
- 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@v4
-
- - name: ccache
- uses: hendrikmuhs/ccache-action@v1.2
- with:
- key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
-
- - name: Install missing software on ubuntu
- if: contains(matrix.os, 'ubuntu') && 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
- sudo apt-get install libxml2-utils libtinyxml2-dev
- # qt6-tools-dev-tools for lprodump
- # qt6-l10n-tools for lupdate
- sudo apt-get install qt6-base-dev libqt6charts6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libglx-dev libgl1-mesa-dev
-
- # coreutils contains "nproc"
- - name: Install missing software on macos
- if: contains(matrix.os, 'macos')
- run: |
- # pcre was removed from runner images in November 2022
- brew install coreutils qt@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-13]
- 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@v4
-
- - name: ccache
- uses: hendrikmuhs/ccache-action@v1.2
- with:
- key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
-
- - name: Install missing software on ubuntu
- if: contains(matrix.os, 'ubuntu') && 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: false # matrix.os == 'ubuntu-22.04'
- with:
- version: 13
- platform: x64
-
- - name: Select compiler
- if: false # matrix.os == 'ubuntu-22.04'
- run: |
- echo "CXX=g++-13" >> $GITHUB_ENV
-
- - name: Install missing software on ubuntu
- if: contains(matrix.os, 'ubuntu') && matrix.use_qt6 == 'On'
- run: |
- sudo apt-get update
- sudo apt-get install libxml2-utils
- # qt6-tools-dev-tools for lprodump
- # qt6-l10n-tools for lupdate
- sudo apt-get install qt6-base-dev libqt6charts6-dev qt6-tools-dev qt6-tools-dev-tools qt6-l10n-tools libglx-dev libgl1-mesa-dev
-
- # coreutils contains "nproc"
- - name: Install missing software on macos
- if: contains(matrix.os, 'macos')
- run: |
- # pcre was removed from runner images in November 2022
- brew install coreutils qt@6 pcre
-
- - name: 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-13]
- fail-fast: false # Prefer quick result
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - uses: actions/checkout@v4
-
- - name: ccache
- uses: hendrikmuhs/ccache-action@v1.2
- 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-13]
- fail-fast: false # Prefer quick result
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - uses: actions/checkout@v4
-
- - name: ccache
- uses: hendrikmuhs/ccache-action@v1.2
- 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-13]
- fail-fast: false # Prefer quick result
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - uses: actions/checkout@v4
-
- # 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@v4
-
- - 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
- 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/resultstree
- qmake CONFIG+=debug CONFIG+=ccache
- make -j$(nproc)
- export QT_QPA_PLATFORM=offscreen
- ./test-resultstree
- 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-13]
- fail-fast: false # Prefer quick result
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - uses: actions/checkout@v4
-
- - name: ccache
- uses: hendrikmuhs/ccache-action@v1.2
- with:
- key: ${{ github.workflow }}-${{ github.job }}-${{ matrix.os }}
-
- - name: Install missing software on ubuntu
- if: contains(matrix.os, 'ubuntu')
- run: |
- sudo apt-get update
- sudo apt-get install libxml2-utils
-
- # 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 libselinux-dev libwxgtk3.0-gtk3-dev xmlstarlet qtbase5-dev
-
- # coreutils contains "nproc"
- - name: Install missing software on macos
- if: contains(matrix.os, 'macos')
- run: |
- # pcre was removed from runner images in November 2022
- brew install coreutils python3 pcre gnu-sed
-
- - name: Install missing Python packages
- run: |
- python3 -m pip install pip --upgrade
- python3 -m pip install pytest
- python3 -m pip install pytest-timeout
- python3 -m pip install psutil
-
- - 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: |
- set -x
- ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety addons/test/threadsafety
- ./cppcheck --error-exitcode=1 --inline-suppr --addon=threadsafety --std=c++03 addons/test/threadsafety
- ./cppcheck --error-exitcode=1 --inline-suppr --addon=misra addons/test/misra/crash*.c
- ./cppcheck --error-exitcode=1 --inline-suppr --addon=misra --enable=information addons/test/misra/config*.c
-
- ./cppcheck --addon=misra --enable=style --inline-suppr --enable=information --error-exitcode=1 addons/test/misra/misra-ctu-*-test.c
- pushd addons/test
- # We'll force C89 standard to enable an additional verification for
- # rules 5.4 and 5.5 which have standard-dependent options.
- ../../cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test.c --std=c89 --platform=unix64
- python3 ../misra.py -verify misra/misra-test.c.dump
- # Test slight MISRA differences in C11 standard
- ../../cppcheck --dump -DDUMMY --suppress=uninitvar --inline-suppr misra/misra-test-c11.c --std=c11 --platform=unix64
- python3 ../misra.py -verify misra/misra-test-c11.c.dump
- # TODO: do we need to verify something here?
- ../../cppcheck --dump -DDUMMY --suppress=uninitvar --suppress=uninitStructMember --std=c89 misra/misra-test.h
- ../../cppcheck --dump misra/misra-test.cpp
- 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
+ permissions:
+ # https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github
+
+ # required for all workflows
+ security-events: write
+ # only required for workflows in private repositories
+ actions: read
+ contents: read
+
steps:
- uses: actions/checkout@v4
@@ -549,18 +63,16 @@ jobs:
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 || ec=1
- ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b1 --addon=naming.json --enable=internal lib || ec=1
- # check gui with qt settings
- mkdir b2
- ./cppcheck $selfcheck_options $cppcheck_options --cppcheck-build-dir=b2 -DQT_VERSION=0x060000 -DQ_MOC_OUTPUT_REVISION=68 -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=68 -DQT_CHARTS_LIB --library=qt -Icmake.output/tools/triage -Igui tools/triage/*.cpp cmake.output/tools/triage || ec=1
- exit $ec
+
+ # test sarif output
+ ./cppcheck --enable=style --error-exitcode=0 --platform=unix64 --inconclusive samples/incorrectLogicOperator/bad.c --output-file=samples.sarif --output-format=sarif
+ cat samples.sarif
+
+ - name: Upload SARIF file
+ uses: github/codeql-action/upload-sarif@v3
+ with:
+ # Path to SARIF file relative to the root of the repository
+ sarif_file: samples.sarif
+ # Optional category for the results
+ # Used to differentiate multiple results for one commit
+ category: samples
diff --git a/.github/workflows/CI-windows.yml b/.github/workflows/CI-windows.yml
index 420c470fa5a..47136dccd3f 100644
--- a/.github/workflows/CI-windows.yml
+++ b/.github/workflows/CI-windows.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/asan.yml b/.github/workflows/asan.yml
index 0225f975f8e..787591777f1 100644
--- a/.github/workflows/asan.yml
+++ b/.github/workflows/asan.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/buildman.yml b/.github/workflows/buildman.yml
index 601180c8916..530d0a2b86c 100644
--- a/.github/workflows/buildman.yml
+++ b/.github/workflows/buildman.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml
index 7b462c688f0..e3c77b35b5e 100644
--- a/.github/workflows/cifuzz.yml
+++ b/.github/workflows/cifuzz.yml
@@ -2,7 +2,14 @@
# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
name: CIFuzz
-on: [pull_request]
+on:
+ push:
+ branches:
+ - 'main'
+ - 'releases/**'
+ - '2.*'
+ tags:
+ - '2.*'
permissions:
contents: read
diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml
index b1744dd31d4..476cda76fb4 100644
--- a/.github/workflows/clang-tidy.yml
+++ b/.github/workflows/clang-tidy.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 4f7f66be27d..4c8d19de3e0 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 75d72a93f28..1139de7f7fd 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/cppcheck-premium.yml b/.github/workflows/cppcheck-premium.yml
index d45b0f18789..5143e3f7687 100644
--- a/.github/workflows/cppcheck-premium.yml
+++ b/.github/workflows/cppcheck-premium.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
workflow_dispatch:
inputs:
premium_version:
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
index 6b30eb70e97..f944ff58b8b 100644
--- a/.github/workflows/format.yml
+++ b/.github/workflows/format.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/scriptcheck.yml b/.github/workflows/scriptcheck.yml
index 7b7eff9d26c..5eab7b45d42 100644
--- a/.github/workflows/scriptcheck.yml
+++ b/.github/workflows/scriptcheck.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/selfcheck.yml b/.github/workflows/selfcheck.yml
index 88c4462375a..5c8fc97c7b0 100644
--- a/.github/workflows/selfcheck.yml
+++ b/.github/workflows/selfcheck.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/tsan.yml b/.github/workflows/tsan.yml
index cefacf1221e..6a9f67f8799 100644
--- a/.github/workflows/tsan.yml
+++ b/.github/workflows/tsan.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/ubsan.yml b/.github/workflows/ubsan.yml
index 8d4cbda076b..6f3018e0d7a 100644
--- a/.github/workflows/ubsan.yml
+++ b/.github/workflows/ubsan.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/.github/workflows/valgrind.yml b/.github/workflows/valgrind.yml
index 25297ebf19b..10ab5d98620 100644
--- a/.github/workflows/valgrind.yml
+++ b/.github/workflows/valgrind.yml
@@ -10,7 +10,6 @@ on:
- '2.*'
tags:
- '2.*'
- pull_request:
permissions:
contents: read
diff --git a/Makefile b/Makefile
index 827f5233221..afd4da64213 100644
--- a/Makefile
+++ b/Makefile
@@ -173,7 +173,7 @@ ifndef INCLUDE_FOR_LIB
endif
ifndef INCLUDE_FOR_CLI
- INCLUDE_FOR_CLI=-Ilib -isystem externals/simplecpp -isystem externals/tinyxml2
+ INCLUDE_FOR_CLI=-Ilib -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2
endif
ifndef INCLUDE_FOR_TEST
@@ -762,7 +762,7 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli
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/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
+cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/cppcheckexecutorseh.h cli/executor.h cli/processexecutor.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.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/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h
$(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/path.h lib/platform.h lib/standards.h lib/utils.h
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
index 51e9aee6718..c05743becb3 100644
--- a/cli/CMakeLists.txt
+++ b/cli/CMakeLists.txt
@@ -12,6 +12,7 @@ if (BUILD_CLI)
else()
target_include_directories(cli_objs SYSTEM PRIVATE ${tinyxml2_INCLUDE_DIRS})
endif()
+ target_externals_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/picojson/)
target_externals_include_directories(cli_objs PRIVATE ${PROJECT_SOURCE_DIR}/externals/simplecpp/)
if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
target_precompile_headers(cli_objs PRIVATE precompiled.h)
diff --git a/cli/cli.vcxproj b/cli/cli.vcxproj
index f532fa46e7d..a508d3bf55b 100644
--- a/cli/cli.vcxproj
+++ b/cli/cli.vcxproj
@@ -85,7 +85,7 @@
- ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
true
ProgramDatabase
Disabled
@@ -114,7 +114,7 @@
- ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
true
ProgramDatabase
Disabled
@@ -143,7 +143,7 @@
- ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
false
MaxSpeed
CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions)
@@ -181,7 +181,7 @@
- ..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
false
MaxSpeed
CPPCHECKLIB_IMPORT;TINYXML2_IMPORT;NDEBUG;WIN32;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions)
diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp
index 06543326757..a5f8a424ed3 100644
--- a/cli/cmdlineparser.cpp
+++ b/cli/cmdlineparser.cpp
@@ -917,6 +917,20 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
else if (std::strncmp(argv[i], "--output-file=", 14) == 0)
mSettings.outputFile = Path::simplifyPath(argv[i] + 14);
+ else if (std::strncmp(argv[i], "--output-format=", 16) == 0) {
+ const std::string format = argv[i] + 16;
+ if (format == "sarif")
+ mSettings.outputFormat = Settings::OutputFormat::sarif;
+ else if (format == "xml")
+ mSettings.outputFormat = Settings::OutputFormat::xml;
+ else {
+ mLogger.printError("argument to '--output-format=' must be 'sarif' or 'xml'.");
+ return Result::Fail;
+ }
+ mSettings.xml = (mSettings.outputFormat == Settings::OutputFormat::xml);
+ }
+
+
// Experimental: limit execution time for extended valueflow analysis. basic valueflow analysis
// is always executed.
else if (std::strncmp(argv[i], "--performance-valueflow-max-time=", 33) == 0) {
@@ -951,6 +965,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
// Write results in results.plist
else if (std::strncmp(argv[i], "--plist-output=", 15) == 0) {
+ mSettings.outputFormat = Settings::OutputFormat::plist;
mSettings.plistOutput = Path::simplifyPath(argv[i] + 15);
if (mSettings.plistOutput.empty())
mSettings.plistOutput = ".";
@@ -1363,8 +1378,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
mSettings.verbose = true;
// Write results in results.xml
- else if (std::strcmp(argv[i], "--xml") == 0)
+ else if (std::strcmp(argv[i], "--xml") == 0) {
mSettings.xml = true;
+ mSettings.outputFormat = Settings::OutputFormat::xml;
+ }
// Define the XML file version (and enable XML output)
else if (std::strncmp(argv[i], "--xml-version=", 14) == 0) {
@@ -1380,6 +1397,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
mSettings.xml_version = tmp;
// Enable also XML if version is set
mSettings.xml = true;
+ mSettings.outputFormat = Settings::OutputFormat::xml;
}
else {
@@ -1625,6 +1643,10 @@ void CmdLineParser::printHelp() const
" is 2. A larger value will mean more errors can be found\n"
" but also means the analysis will be slower.\n"
" --output-file= Write results to file, rather than standard error.\n"
+ " --output-format=\n"
+ " Specify the output format. The available formats are:\n"
+ " * sarif\n"
+ " * xml\n"
" --platform=, --platform=\n"
" Specifies platform specific types and sizes. The\n"
" available builtin platforms are:\n"
diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp
index a39685f03f4..82503bc4b18 100644
--- a/cli/cppcheckexecutor.cpp
+++ b/cli/cppcheckexecutor.cpp
@@ -28,6 +28,7 @@
#include "errorlogger.h"
#include "errortypes.h"
#include "filesettings.h"
+#include "json.h"
#include "settings.h"
#include "singleexecutor.h"
#include "suppressions.h"
@@ -71,6 +72,117 @@
#endif
namespace {
+ class SarifReport {
+ public:
+ void addFinding(ErrorMessage msg) {
+ mFindings.push_back(std::move(msg));
+ }
+
+ picojson::array serializeRules() const {
+ picojson::array ret;
+ std::set ruleIds;
+ for (const auto& finding : mFindings) {
+ if (ruleIds.insert(finding.id).second) {
+ picojson::object rule;
+ rule["id"] = picojson::value(finding.id);
+ picojson::object shortDescription;
+ shortDescription["text"] = picojson::value(finding.shortMessage());
+ rule["shortDescription"] = picojson::value(shortDescription);
+ ret.emplace_back(rule);
+ }
+ }
+ return ret;
+ }
+
+ static picojson::array serializeLocations(const ErrorMessage& finding) {
+ picojson::array ret;
+ for (const auto& location : finding.callStack) {
+ picojson::object physicalLocation;
+ picojson::object artifactLocation;
+ artifactLocation["uri"] = picojson::value(location.getOrigFile(false));
+ physicalLocation["artifactLocation"] = picojson::value(artifactLocation);
+ picojson::object region;
+ region["startLine"] = picojson::value(static_cast(location.line));
+ region["startColumn"] = picojson::value(static_cast(location.column));
+ physicalLocation["region"] = picojson::value(region);
+ picojson::object loc;
+ loc["physicalLocation"] = picojson::value(physicalLocation);
+ ret.emplace_back(loc);
+ }
+ return ret;
+ }
+
+ picojson::array serializeResults() const {
+ picojson::array results;
+ for (const auto& finding : mFindings) {
+ picojson::object res;
+ res["level"] = picojson::value(sarifLevel(finding.severity));
+ if (!finding.callStack.empty())
+ res["locations"] = picojson::value(serializeLocations(finding));
+ picojson::object message;
+ message["text"] = picojson::value(finding.shortMessage());
+ res["message"] = picojson::value(message);
+ res["ruleId"] = picojson::value(finding.id);
+ results.emplace_back(res);
+ }
+ return results;
+ }
+
+ picojson::value serializeRuns(const std::string& productName, const std::string& version) const {
+ picojson::object driver;
+ driver["name"] = picojson::value(productName);
+ driver["version"] = picojson::value(version);
+ driver["informationUri"] = picojson::value("https://cppcheck.sourceforge.io");
+ driver["rules"] = picojson::value(serializeRules());
+ picojson::object tool;
+ tool["driver"] = picojson::value(driver);
+ picojson::object run;
+ run["tool"] = picojson::value(tool);
+ run["results"] = picojson::value(serializeResults());
+ picojson::array runs{picojson::value(run)};
+ return picojson::value(runs);
+ }
+
+ std::string serialize(std::string productName) const {
+ const auto nameAndVersion = Settings::getNameAndVersion(productName);
+ productName = nameAndVersion.first.empty() ? "Cppcheck" : nameAndVersion.first;
+ std::string version = nameAndVersion.first.empty() ? CppCheck::version() : nameAndVersion.second;
+ if (version.find(" ") != std::string::npos)
+ version.erase(version.find(" "), std::string::npos);
+
+ picojson::object doc;
+ doc["version"] = picojson::value("2.1.0");
+ doc["$schema"] = picojson::value("https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json");
+ doc["runs"] = serializeRuns(productName, version);
+
+ return picojson::value(doc).serialize(true);
+ }
+ private:
+
+
+ static std::string sarifLevel(Severity severity) {
+ switch (severity) {
+ case Severity::error:
+ return "error";
+ case Severity::warning:
+ case Severity::style:
+ case Severity::portability:
+ case Severity::performance:
+ return "warning";
+ case Severity::information:
+ case Severity::internal:
+ case Severity::debug:
+ case Severity::none:
+ return "note";
+ }
+ return "note";
+ }
+
+
+
+ std::vector mFindings;
+ };
+
class CmdLineLoggerStd : public CmdLineLogger
{
public:
@@ -104,6 +216,9 @@ namespace {
}
~StdLogger() override {
+ if (mSettings.outputFormat == Settings::OutputFormat::sarif) {
+ reportErr(mSarifReport.serialize(mSettings.cppcheckCfgProductName));
+ }
delete mErrorOutput;
}
@@ -173,6 +288,8 @@ namespace {
* True if there are critical errors
*/
std::string mCriticalErrors;
+
+ SarifReport mSarifReport;
};
}
@@ -447,7 +564,9 @@ void StdLogger::reportErr(const ErrorMessage &msg)
if (!mShownErrors.insert(msg.toString(mSettings.verbose)).second)
return;
- if (mSettings.xml)
+ if (mSettings.outputFormat == Settings::OutputFormat::sarif)
+ mSarifReport.addFinding(msg);
+ else if (mSettings.xml)
reportErr(msg.toXML());
else
reportErr(msg.toString(mSettings.verbose, mSettings.templateFormat, mSettings.templateLocation));
diff --git a/lib/settings.h b/lib/settings.h
index ef4207cced9..11ea5e502fa 100644
--- a/lib/settings.h
+++ b/lib/settings.h
@@ -271,6 +271,9 @@ class CPPCHECKLIB WARN_UNUSED Settings {
/** @brief write results (--output-file=<file>) */
std::string outputFile;
+ enum class OutputFormat : std::uint8_t {text, plist, sarif, xml};
+ OutputFormat outputFormat = OutputFormat::text;
+
Platform platform;
/** @brief pid of cppcheck. Intention is that this is set in the main process. */
diff --git a/releasenotes.txt b/releasenotes.txt
index 8c0edafd07f..ffee14f39fd 100644
--- a/releasenotes.txt
+++ b/releasenotes.txt
@@ -10,6 +10,8 @@ GUI:
-
Changed interface:
+- SARIF output. Use --output-format=sarif to activate this.
+- Add option --output-format=. Allowed formats are sarif and xml.
-
Deprecations:
diff --git a/samples/incorrectLogicOperator/bad.c b/samples/incorrectLogicOperator/bad.c
new file mode 100644
index 00000000000..11daaf4e4ce
--- /dev/null
+++ b/samples/incorrectLogicOperator/bad.c
@@ -0,0 +1,6 @@
+
+void foo(int x) {
+ if (x >= 0 || x <= 10) {}
+}
+
+dummy=foo();
diff --git a/samples/incorrectLogicOperator/good.c b/samples/incorrectLogicOperator/good.c
new file mode 100644
index 00000000000..a2d122fb128
--- /dev/null
+++ b/samples/incorrectLogicOperator/good.c
@@ -0,0 +1,6 @@
+
+void foo(int x) {
+ if (x >= 0 && x <= 10) {}
+}
+
+dummy=foo();
diff --git a/samples/incorrectLogicOperator/out.txt b/samples/incorrectLogicOperator/out.txt
new file mode 100644
index 00000000000..cbd29f23fc2
--- /dev/null
+++ b/samples/incorrectLogicOperator/out.txt
@@ -0,0 +1,3 @@
+samples/incorrectLogicOperator/bad.c:3:16: warning: Logical disjunction always evaluates to true: x >= 0 || x <= 10. [incorrectLogicOperator]
+ if (x >= 0 || x <= 10) {}
+ ^
diff --git a/test/cli/helloworld_test.py b/test/cli/helloworld_test.py
index fafb9d562d5..d74d02be414 100644
--- a/test/cli/helloworld_test.py
+++ b/test/cli/helloworld_test.py
@@ -4,6 +4,7 @@
import os
import re
import glob
+import json
from testutils import create_gui_project_file, cppcheck
@@ -319,3 +320,17 @@ def test_missing_include_system(): # #11283
_, _, stderr = cppcheck(args, cwd=__script_dir)
assert stderr.replace('\\', '/') == 'helloworld/main.c:1:0: information: Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results. [missingIncludeSystem]\n'
+
+
+def test_sarif():
+ args = [
+ '--output-format=sarif',
+ 'helloworld'
+ ]
+ ret, stdout, stderr = cppcheck(args, cwd=__script_dir)
+ assert ret == 0, stdout
+ res = json.loads(stderr)
+ assert res['version'] == '2.1.0'
+ assert res['runs'][0]['results'][0]['locations'][0]['physicalLocation']['artifactLocation']['uri'] == 'helloworld/main.c'
+ assert res['runs'][0]['results'][0]['ruleId'] == 'zerodiv'
+ assert res['runs'][0]['results'][0]['message']['text'] == 'Division by zero.'
diff --git a/test/testcmdlineparser.cpp b/test/testcmdlineparser.cpp
index 08dbe16b4db..8ba6017c223 100644
--- a/test/testcmdlineparser.cpp
+++ b/test/testcmdlineparser.cpp
@@ -208,6 +208,11 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(maxConfigsMissingCount);
TEST_CASE(maxConfigsInvalid);
TEST_CASE(maxConfigsTooSmall);
+ TEST_CASE(outputFormatSarif);
+ TEST_CASE(outputFormatXml);
+ TEST_CASE(outputFormatOther);
+ TEST_CASE(outputFormatImplicitPlist);
+ TEST_CASE(outputFormatImplicitXml);
TEST_CASE(premiumOptions1);
TEST_CASE(premiumOptions2);
TEST_CASE(premiumOptions3);
@@ -1247,6 +1252,41 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("cppcheck: error: argument to '--max-configs=' must be greater than 0.\n", logger->str());
}
+ void outputFormatSarif() {
+ REDIRECT;
+ const char * const argv[] = {"cppcheck", "--output-format=sarif", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS_ENUM(Settings::OutputFormat::sarif, settings->outputFormat);
+ }
+
+ void outputFormatXml() {
+ REDIRECT;
+ const char * const argv[] = {"cppcheck", "--output-format=xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS_ENUM(Settings::OutputFormat::xml, settings->outputFormat);
+ }
+
+ void outputFormatOther() {
+ REDIRECT;
+ const char * const argv[] = {"cppcheck", "--output-format=text", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS("cppcheck: error: argument to '--output-format=' must be 'sarif' or 'xml'.\n", logger->str());
+ }
+
+ void outputFormatImplicitPlist() {
+ REDIRECT;
+ const char * const argv[] = {"cppcheck", "--plist-output=.", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS_ENUM(Settings::OutputFormat::plist, settings->outputFormat);
+ }
+
+ void outputFormatImplicitXml() {
+ REDIRECT;
+ const char * const argv[] = {"cppcheck", "--xml", "file.cpp"};
+ ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
+ ASSERT_EQUALS_ENUM(Settings::OutputFormat::xml, settings->outputFormat);
+ }
+
void premiumOptions1() {
REDIRECT;
asPremium();
diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj
index 5951a2770ba..89ab1d43a4c 100755
--- a/test/testrunner.vcxproj
+++ b/test/testrunner.vcxproj
@@ -197,7 +197,7 @@
- ..\cli;..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\cli;..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
true
ProgramDatabase
Disabled
@@ -226,7 +226,7 @@
- ..\cli;..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\cli;..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
true
ProgramDatabase
Disabled
@@ -255,7 +255,7 @@
- ..\cli;..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\cli;..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
false
MaxSpeed
CPPCHECKLIB_IMPORT;SIMPLECPP_IMPORT;NDEBUG;WIN32;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions)
@@ -295,7 +295,7 @@
- ..\cli;..\lib;..\externals;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
+ ..\cli;..\lib;..\externals;..\externals\picojson;..\externals\simplecpp;..\externals\tinyxml2;%(AdditionalIncludeDirectories)
false
MaxSpeed
CPPCHECKLIB_IMPORT;SIMPLECPP_IMPORT;NDEBUG;WIN32;HAVE_RULES;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WIN64;%(PreprocessorDefinitions)
diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp
index 3b50040779b..6e11eff7caa 100644
--- a/tools/dmake/dmake.cpp
+++ b/tools/dmake/dmake.cpp
@@ -754,7 +754,7 @@ int main(int argc, char **argv)
makeConditionalVariable(fout, "PREFIX", "/usr");
makeConditionalVariable(fout, "INCLUDE_FOR_LIB", "-Ilib -isystem externals -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2");
- makeConditionalVariable(fout, "INCLUDE_FOR_CLI", "-Ilib -isystem externals/simplecpp -isystem externals/tinyxml2");
+ makeConditionalVariable(fout, "INCLUDE_FOR_CLI", "-Ilib -isystem externals/picojson -isystem externals/simplecpp -isystem externals/tinyxml2");
makeConditionalVariable(fout, "INCLUDE_FOR_TEST", "-Ilib -Icli -isystem externals/simplecpp -isystem externals/tinyxml2");
fout << "BIN=$(DESTDIR)$(PREFIX)/bin\n\n";