mirror of
https://github.com/Kitware/CMake.git
synced 2026-07-01 12:18:01 +00:00
pvs-studio: Add support for linting with PVS-Studio
This commit is contained in:
@@ -327,6 +327,7 @@ Properties on Targets
|
||||
/prop_tgt/LANG_ICSTAT
|
||||
/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE
|
||||
/prop_tgt/LANG_LINKER_LAUNCHER
|
||||
/prop_tgt/LANG_PVS_STUDIO
|
||||
/prop_tgt/LANG_STANDARD
|
||||
/prop_tgt/LANG_STANDARD_REQUIRED
|
||||
/prop_tgt/LANG_VISIBILITY_PRESET
|
||||
|
||||
@@ -529,6 +529,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE_SUPPORTED
|
||||
/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG
|
||||
/variable/CMAKE_LANG_LINKER_LAUNCHER
|
||||
/variable/CMAKE_LANG_PVS_STUDIO
|
||||
/variable/CMAKE_LANG_USING_LINKER_TYPE
|
||||
/variable/CMAKE_LANG_VISIBILITY_PRESET
|
||||
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
|
||||
|
||||
@@ -6,11 +6,12 @@ SKIP_LINTING
|
||||
This property allows you to exclude a specific source file
|
||||
from the linting process. The linting process involves running
|
||||
tools such as :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
|
||||
:prop_tgt:`<LANG>_CPPCHECK`, :prop_tgt:`<LANG>_ICSTAT` and
|
||||
:prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` on the source files, as well
|
||||
as compiling header files as part of :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`.
|
||||
By setting ``SKIP_LINTING`` on a source file, the mentioned linting tools
|
||||
will not be executed for that particular file.
|
||||
:prop_tgt:`<LANG>_CPPCHECK`, :prop_tgt:`<LANG>_ICSTAT`,
|
||||
:prop_tgt:`<LANG>_PVS_STUDIO` and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE` on the
|
||||
source files, as well as compiling header files as part of
|
||||
:prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`. By setting ``SKIP_LINTING`` on a
|
||||
source file, the mentioned linting tools will not be executed for that
|
||||
particular file.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
39
Help/prop_tgt/LANG_PVS_STUDIO.rst
Normal file
39
Help/prop_tgt/LANG_PVS_STUDIO.rst
Normal file
@@ -0,0 +1,39 @@
|
||||
<LANG>_PVS_STUDIO
|
||||
-----------------
|
||||
|
||||
.. versionadded:: 4.3
|
||||
|
||||
This property is implemented only when ``<LANG>`` is ``C`` or ``CXX``.
|
||||
|
||||
Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing
|
||||
a command line for the ``pvs-studio-analyzer`` tool (named
|
||||
``CompilerCommandsAnalyzer`` on Windows). The :ref:`Makefile Generators` and
|
||||
:ref:`Ninja Generators` will run this tool along with the compiler and
|
||||
report a warning if the tool reports any problems.
|
||||
|
||||
The specified ``pvs-studio-analyzer`` command line will be invoked with
|
||||
the following additional arguments:
|
||||
|
||||
- ``--source-file``: The source file.
|
||||
- ``--output-file``: A path adjacent to the object file to write the PVS log.
|
||||
- ``--cl-params``: The compile options.
|
||||
- ``--preprocessor``: The preprocessor, based on
|
||||
:variable:`CMAKE_<LANG>_COMPILER_ID`, if determined to be one of:
|
||||
``visualcpp``, ``clang``, ``gcc``, ``bcc``, ``iar``.
|
||||
- ``--platform``: The target platform, if determined to be one of: ``arm``,
|
||||
``win32``, ``x64``, ``linux32``, ``linux64``, ``macOS``.
|
||||
|
||||
See the
|
||||
`PVS-Studio documentation <https://pvs-studio.com/en/docs/manual/6615/#flags>`_
|
||||
for details on these and other available options.
|
||||
|
||||
CMake will look for the ``plog-converter`` tool in the same directory as the
|
||||
provided ``pvs-studio-analyzer``, and in the user's path if not present in that
|
||||
directory. The ``plog-converter`` will run automatically with the ``Txt``
|
||||
output type on Windows, and ``errorfile`` on other platforms, and the contents
|
||||
of that file will be sent to ``stderr``. The PVS log file will be deleted after
|
||||
the converter runs.
|
||||
|
||||
This property is initialized by the value of
|
||||
the :variable:`CMAKE_<LANG>_PVS_STUDIO` variable if it is set
|
||||
when a target is created.
|
||||
7
Help/release/dev/pvs-analyze.rst
Normal file
7
Help/release/dev/pvs-analyze.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
pvs-analyze
|
||||
-----------
|
||||
|
||||
* A :prop_tgt:`<LANG>_PVS_STUDIO` target property and supporting
|
||||
:variable:`CMAKE_<LANG>_PVS_STUDIO` variable were introduced to tell
|
||||
:ref:`Makefile Generators` and :ref:`Ninja Generators` to run
|
||||
``pvs-studio-analyzer`` with the compiler for ``C`` and ``CXX`` languages.
|
||||
15
Help/variable/CMAKE_LANG_PVS_STUDIO.rst
Normal file
15
Help/variable/CMAKE_LANG_PVS_STUDIO.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
CMAKE_<LANG>_PVS_STUDIO
|
||||
-----------------------
|
||||
|
||||
.. versionadded:: 4.3
|
||||
|
||||
Default value for :prop_tgt:`<LANG>_PVS_STUDIO` target property
|
||||
when ``<LANG>`` is ``C`` or ``CXX``.
|
||||
|
||||
This variable is used to initialize the property on each target as it is
|
||||
created. For example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(CMAKE_CXX_PVS_STUDIO pvs-studio-analyzer analyze -a "GA\;OP")
|
||||
add_executable(foo foo.cxx)
|
||||
@@ -360,6 +360,7 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules(
|
||||
std::string cpplint;
|
||||
std::string cppcheck;
|
||||
std::string icstat;
|
||||
std::string pvs;
|
||||
|
||||
auto evaluateProp = [&](std::string const& prop) -> std::string {
|
||||
auto const value = this->GeneratorTarget->GetProperty(prop);
|
||||
@@ -386,9 +387,13 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules(
|
||||
|
||||
std::string const icstat_prop = cmStrCat(lang, "_ICSTAT");
|
||||
icstat = evaluateProp(icstat_prop);
|
||||
|
||||
std::string const pvs_prop = cmStrCat(lang, "_PVS_STUDIO");
|
||||
pvs = evaluateProp(pvs_prop);
|
||||
}
|
||||
|
||||
if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
|
||||
cmNonempty(cppcheck) || cmNonempty(icstat)) {
|
||||
cmNonempty(cppcheck) || cmNonempty(icstat) || cmNonempty(pvs)) {
|
||||
std::string code_check = cmakeCmd + " -E __run_co_compile";
|
||||
if (!compilerLauncher.empty()) {
|
||||
// In __run_co_compile case the launcher command is supplied
|
||||
@@ -476,6 +481,29 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules(
|
||||
exportFixes));
|
||||
}
|
||||
}
|
||||
if (cmNonempty(pvs)) {
|
||||
cmMakefile* mf =
|
||||
this->GeneratorTarget->GetLocalGenerator()->GetMakefile();
|
||||
std::string extraPvsArgs;
|
||||
if (lang == "CXX") {
|
||||
extraPvsArgs +=
|
||||
cmStrCat(";--cxx;", mf->GetDefinition("CMAKE_CXX_COMPILER"));
|
||||
} else if (lang == "C") {
|
||||
extraPvsArgs +=
|
||||
cmStrCat(";--cc;", mf->GetDefinition("CMAKE_C_COMPILER"));
|
||||
}
|
||||
// cocompile args
|
||||
code_check += " --pvs-studio=";
|
||||
code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
|
||||
cmStrCat(pvs, extraPvsArgs));
|
||||
code_check += " --object=";
|
||||
code_check +=
|
||||
this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmSystemTools::CollapseFullPath(
|
||||
cmStrCat(this->GeneratorTarget->GetObjectDirectory(config), '/',
|
||||
this->GeneratorTarget->GetObjectName(&source))),
|
||||
cmOutputConverter::SHELL);
|
||||
}
|
||||
if (cmNonempty(cpplint)) {
|
||||
code_check += " --cpplint=";
|
||||
code_check +=
|
||||
@@ -504,7 +532,8 @@ std::string cmCommonTargetGenerator::GenerateCodeCheckRules(
|
||||
code_check += this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
|
||||
cmStrCat(icstat, checksParam, dbParam));
|
||||
}
|
||||
if (cmNonempty(tidy) || (cmNonempty(cpplint)) || (cmNonempty(cppcheck))) {
|
||||
if (cmNonempty(tidy) || (cmNonempty(cpplint)) || (cmNonempty(cppcheck)) ||
|
||||
cmNonempty(pvs)) {
|
||||
code_check += " --source=";
|
||||
code_check +=
|
||||
this->GeneratorTarget->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
|
||||
@@ -473,6 +473,7 @@ TargetProperty const StaticTargetProperties[] = {
|
||||
{ "C_CPPCHECK"_s, IC::CanCompileSources },
|
||||
{ "C_ICSTAT"_s, IC::CanCompileSources },
|
||||
{ "C_INCLUDE_WHAT_YOU_USE"_s, IC::CanCompileSources },
|
||||
{ "C_PVS_STUDIO"_s, IC::CanCompileSources },
|
||||
// -- C++
|
||||
{ "CXX_CLANG_TIDY"_s, IC::CanCompileSources },
|
||||
{ "CXX_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
|
||||
@@ -480,6 +481,7 @@ TargetProperty const StaticTargetProperties[] = {
|
||||
{ "CXX_CPPCHECK"_s, IC::CanCompileSources },
|
||||
{ "CXX_ICSTAT"_s, IC::CanCompileSources },
|
||||
{ "CXX_INCLUDE_WHAT_YOU_USE"_s, IC::CanCompileSources },
|
||||
{ "CXX_PVS_STUDIO"_s, IC::CanCompileSources },
|
||||
// -- Objective C
|
||||
{ "OBJC_CLANG_TIDY"_s, IC::CanCompileSources },
|
||||
{ "OBJC_CLANG_TIDY_EXPORT_FIXES_DIR"_s, IC::CanCompileSources },
|
||||
@@ -1808,6 +1810,7 @@ void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
|
||||
"CXX_CPPCHECK",
|
||||
"CXX_ICSTAT",
|
||||
"CXX_INCLUDE_WHAT_YOU_USE",
|
||||
"CXX_PVS_STUDIO",
|
||||
"SKIP_LINTING",
|
||||
|
||||
// Build graph properties
|
||||
|
||||
@@ -411,6 +411,81 @@ int HandleTidy(std::string const& runCmd, std::string const& sourceFile,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HandlePVSStudio(std::string const& runCmd, std::string const& sourceFile,
|
||||
std::string const& objectFile,
|
||||
std::vector<std::string> const& orig_cmd)
|
||||
{
|
||||
cmList pvsCmd{ runCmd, cmList::EmptyElements::Yes };
|
||||
std::string logFile = cmStrCat(objectFile, "-pvs.log");
|
||||
std::string errFile = cmStrCat(objectFile, "-pvs.err");
|
||||
pvsCmd.reserve(pvsCmd.size() + 5 + orig_cmd.size());
|
||||
pvsCmd.emplace_back("--source-file");
|
||||
pvsCmd.emplace_back(sourceFile);
|
||||
pvsCmd.emplace_back("--output-file");
|
||||
pvsCmd.emplace_back(logFile);
|
||||
pvsCmd.emplace_back("--cl-params");
|
||||
for (size_t i = 1; i < orig_cmd.size(); ++i) {
|
||||
pvsCmd.emplace_back(orig_cmd[i]);
|
||||
}
|
||||
int ret;
|
||||
std::string stdOut;
|
||||
std::string stdErr;
|
||||
|
||||
// Run the PVS command line. Capture its stdout and hide its stderr.
|
||||
if (!cmSystemTools::RunSingleCommand(pvsCmd, &stdOut, &stdErr, &ret, nullptr,
|
||||
cmSystemTools::OUTPUT_NONE)) {
|
||||
std::cerr << "Error running '" << pvsCmd[0] << "': " << stdErr << '\n';
|
||||
return 1;
|
||||
}
|
||||
if (ret != 0) {
|
||||
if (ret == 7 && !cmSystemTools::FileExists(logFile)) {
|
||||
return 0; // Analyzer generated no output from source
|
||||
}
|
||||
std::cout << stdOut;
|
||||
std::cerr << stdErr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Find the plog-converter tool
|
||||
#ifdef _WIN32
|
||||
std::string plogConvertName = "HtmlGenerator.exe";
|
||||
#else
|
||||
std::string plogConvertName = "plog-converter";
|
||||
#endif
|
||||
std::string plogConvert = cmStrCat(
|
||||
cmSystemTools::GetFilenamePath(pvsCmd.front()), '/', plogConvertName);
|
||||
if (!cmSystemTools::FileIsExecutable(plogConvert)) {
|
||||
plogConvert = cmSystemTools::FindProgram(plogConvertName);
|
||||
}
|
||||
if (plogConvert.empty()) {
|
||||
std::cerr << "Could not find " << plogConvertName << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run the plog-converter tool
|
||||
std::vector<std::string> plogCmd{ plogConvert, "-t", "errorfile",
|
||||
"-o", errFile, logFile };
|
||||
if (!cmSystemTools::RunSingleCommand(plogCmd, &stdOut, &stdErr, &ret,
|
||||
nullptr, cmSystemTools::OUTPUT_NONE)) {
|
||||
std::cerr << "Error running '" << plogCmd[0] << "': " << stdErr << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Show error messages from plog-converter output
|
||||
if (stdOut.find("Total messages 0") == std::string::npos) {
|
||||
cmsys::ifstream errFileStream(errFile.c_str());
|
||||
// output always begins with a Help message
|
||||
errFileStream.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
|
||||
std::cerr << errFileStream.rdbuf();
|
||||
}
|
||||
cmSystemTools::RemoveFile(logFile);
|
||||
|
||||
if (ret != 0) {
|
||||
std::cerr << stdErr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HandleLWYU(std::string const& runCmd, std::string const& sourceFile,
|
||||
std::string const& /*objectFile*/,
|
||||
std::vector<std::string> const&)
|
||||
@@ -585,15 +660,16 @@ struct CoCompiler
|
||||
bool NoOriginalCommand;
|
||||
};
|
||||
|
||||
std::array<CoCompiler, 6> const CoCompilers = {
|
||||
{ // Table of options and handlers.
|
||||
{ "--cppcheck=", HandleCppCheck, false },
|
||||
{ "--cpplint=", HandleCppLint, false },
|
||||
{ "--icstat=", HandleIcstat, false },
|
||||
{ "--iwyu=", HandleIWYU, false },
|
||||
{ "--lwyu=", HandleLWYU, true },
|
||||
{ "--tidy=", HandleTidy, false } }
|
||||
};
|
||||
std::array<CoCompiler, 7> const CoCompilers = { {
|
||||
// Table of options and handlers.
|
||||
{ "--cppcheck=", HandleCppCheck, false },
|
||||
{ "--cpplint=", HandleCppLint, false },
|
||||
{ "--icstat=", HandleIcstat, false },
|
||||
{ "--iwyu=", HandleIWYU, false },
|
||||
{ "--lwyu=", HandleLWYU, true },
|
||||
{ "--pvs-studio=", HandlePVSStudio, false },
|
||||
{ "--tidy=", HandleTidy, false },
|
||||
} };
|
||||
|
||||
struct CoCompileJob
|
||||
{
|
||||
|
||||
@@ -310,6 +310,7 @@ if(CMake_TEST_Qt6 AND Qt6Widgets_FOUND)
|
||||
"-DCMAKE_PREFIX_PATH:STRING=${base_dir}"
|
||||
-DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
|
||||
-DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>
|
||||
-DPSEUDO_PVS=$<TARGET_FILE:pseudo_pvs>
|
||||
-DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>
|
||||
-DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>
|
||||
)
|
||||
@@ -1166,6 +1167,13 @@ add_executable(pseudo_tidy pseudo_tidy.c)
|
||||
add_executable(pseudo_iwyu pseudo_iwyu.c)
|
||||
add_executable(pseudo_cpplint pseudo_cpplint.c)
|
||||
add_executable(pseudo_cppcheck pseudo_cppcheck.c)
|
||||
add_executable(pseudo_pvs pseudo_pvs.c)
|
||||
add_executable(pseudo_plog_converter pseudo_plog_converter.c)
|
||||
if (WIN32)
|
||||
set_target_properties(pseudo_plog_converter PROPERTIES OUTPUT_NAME HtmlGenerator)
|
||||
else()
|
||||
set_target_properties(pseudo_plog_converter PROPERTIES OUTPUT_NAME plog-converter)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja|FASTBuild")
|
||||
if(UNIX AND NOT CYGWIN)
|
||||
@@ -1179,11 +1187,13 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja|FASTBuild")
|
||||
endif()
|
||||
add_RunCMake_test(ClangTidy -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>)
|
||||
add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>)
|
||||
add_RunCMake_test(PVSStudio -DPSEUDO_PVS=$<TARGET_FILE:pseudo_pvs>)
|
||||
add_RunCMake_test(Cpplint -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>)
|
||||
add_RunCMake_test(Cppcheck -DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>)
|
||||
add_RunCMake_test(MultiLint
|
||||
-DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
|
||||
-DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>
|
||||
-DPSEUDO_PVS=$<TARGET_FILE:pseudo_pvs>
|
||||
-DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>
|
||||
-DPSEUDO_CPPCHECK=$<TARGET_FILE:pseudo_cppcheck>
|
||||
)
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
--icstat=
|
||||
--iwyu=
|
||||
--lwyu=
|
||||
--pvs-studio=
|
||||
--tidy=
|
||||
|
||||
@@ -3,4 +3,5 @@ set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
|
||||
set(CMAKE_C_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
|
||||
set(CMAKE_C_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80)
|
||||
set(CMAKE_C_CPPCHECK "${PSEUDO_CPPCHECK}")
|
||||
set(CMAKE_C_PVS_STUDIO "${PSEUDO_PVS}" analyze)
|
||||
add_executable(main main.c)
|
||||
|
||||
@@ -3,4 +3,5 @@ set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -some -args)
|
||||
set(CMAKE_CXX_CLANG_TIDY "$<1:${PSEUDO_TIDY}>" -some -args)
|
||||
set(CMAKE_CXX_CPPLINT "$<1:${PSEUDO_CPPLINT}>" --verbose=0 --linelength=80)
|
||||
set(CMAKE_CXX_CPPCHECK "$<1:${PSEUDO_CPPCHECK}>")
|
||||
set(CMAKE_CXX_PVS_STUDIO "$<1:${PSEUDO_PVS}>" analyze)
|
||||
add_executable(main main.cxx)
|
||||
|
||||
@@ -5,6 +5,7 @@ set(RunCMake_TEST_OPTIONS
|
||||
"-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}"
|
||||
"-DPSEUDO_IWYU=${PSEUDO_IWYU}"
|
||||
"-DPSEUDO_TIDY=${PSEUDO_TIDY}"
|
||||
"-DPSEUDO_PVS=${PSEUDO_PVS}"
|
||||
)
|
||||
|
||||
function(run_multilint lang)
|
||||
|
||||
3
Tests/RunCMake/PVSStudio/CMakeLists.txt
Normal file
3
Tests/RunCMake/PVSStudio/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 4.1)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
17
Tests/RunCMake/PVSStudio/RunCMakeTest.cmake
Normal file
17
Tests/RunCMake/PVSStudio/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,17 @@
|
||||
include(RunCMake)
|
||||
|
||||
set(RunCMake_TEST_OPTIONS "-DPSEUDO_PVS=${PSEUDO_PVS}")
|
||||
|
||||
function(run_pvs test)
|
||||
# Use a single build tree for tests without cleaning.
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
run_cmake(${test})
|
||||
set(RunCMake_TEST_OUTPUT_MERGE 1)
|
||||
run_cmake_command(${test}-build ${CMAKE_COMMAND} --build .)
|
||||
endfunction()
|
||||
|
||||
run_pvs(pvs)
|
||||
run_pvs(pvs-bad-arg)
|
||||
4
Tests/RunCMake/PVSStudio/main.cxx
Normal file
4
Tests/RunCMake/PVSStudio/main.cxx
Normal file
@@ -0,0 +1,4 @@
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
1
Tests/RunCMake/PVSStudio/pvs-bad-arg-build-result.txt
Normal file
1
Tests/RunCMake/PVSStudio/pvs-bad-arg-build-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
[^0]
|
||||
1
Tests/RunCMake/PVSStudio/pvs-bad-arg-build-stdout.txt
Normal file
1
Tests/RunCMake/PVSStudio/pvs-bad-arg-build-stdout.txt
Normal file
@@ -0,0 +1 @@
|
||||
stderr from bad command line arg '-bad'
|
||||
3
Tests/RunCMake/PVSStudio/pvs-bad-arg.cmake
Normal file
3
Tests/RunCMake/PVSStudio/pvs-bad-arg.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_CXX_PVS_STUDIO "${PSEUDO_PVS};-bad")
|
||||
add_executable(main main.cxx)
|
||||
8
Tests/RunCMake/PVSStudio/pvs-build-check.cmake
Normal file
8
Tests/RunCMake/PVSStudio/pvs-build-check.cmake
Normal file
@@ -0,0 +1,8 @@
|
||||
file (GLOB_RECURSE errFiles "${RunCMake_TEST_BINARY_DIR}/*-pvs.err")
|
||||
file (GLOB_RECURSE logFiles "${RunCMake_TEST_BINARY_DIR}/*-pvs.log")
|
||||
if (NOT errFiles)
|
||||
set(RunCMake_TEST_FAILED ".err file not found.")
|
||||
endif()
|
||||
if (logFiles)
|
||||
set(RunCMake_TEST_FAILED "Leftover .log file found:\n ${logFiles}\n.err files:\n ${errFiles}")
|
||||
endif()
|
||||
1
Tests/RunCMake/PVSStudio/pvs-build-stdout.txt
Normal file
1
Tests/RunCMake/PVSStudio/pvs-build-stdout.txt
Normal file
@@ -0,0 +1 @@
|
||||
example warning
|
||||
3
Tests/RunCMake/PVSStudio/pvs.cmake
Normal file
3
Tests/RunCMake/PVSStudio/pvs.cmake
Normal file
@@ -0,0 +1,3 @@
|
||||
enable_language(CXX)
|
||||
set(CMAKE_CXX_PVS_STUDIO "$<1:${PSEUDO_PVS}>")
|
||||
add_executable(main main.cxx)
|
||||
@@ -120,12 +120,14 @@ set(properties
|
||||
"C_CPPLINT" "cpplint" "<SAME>"
|
||||
"C_CPPCHECK" "cppcheck" "<SAME>"
|
||||
"C_INCLUDE_WHAT_YOU_USE" "iwyu" "<SAME>"
|
||||
"C_PVS_STUDIO" "pvs-studio-analyzer" "<SAME>"
|
||||
## C++
|
||||
"CXX_CLANG_TIDY" "clang-tidy" "<SAME>"
|
||||
"CXX_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
|
||||
"CXX_CPPLINT" "cpplint" "<SAME>"
|
||||
"CXX_CPPCHECK" "cppcheck" "<SAME>"
|
||||
"CXX_INCLUDE_WHAT_YOU_USE" "iwyu" "<SAME>"
|
||||
"CXX_PVS_STUDIO" "pvs-studio-analyzer" "<SAME>"
|
||||
## Objective C
|
||||
"OBJC_CLANG_TIDY" "clang-tidy" "<SAME>"
|
||||
"OBJC_CLANG_TIDY_EXPORT_FIXES_DIR" "${dir}" "<SAME>"
|
||||
|
||||
46
Tests/RunCMake/pseudo_plog_converter.c
Normal file
46
Tests/RunCMake/pseudo_plog_converter.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE* fin;
|
||||
FILE* fout;
|
||||
char* outFile = NULL;
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "-o") == 0) {
|
||||
outFile = argv[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outFile == NULL) {
|
||||
printf("No output file.\n");
|
||||
return 1;
|
||||
}
|
||||
fin = fopen(argv[argc - 1], "r");
|
||||
if (fin == NULL) {
|
||||
printf("Error: Could not open input file.\n");
|
||||
return 1;
|
||||
}
|
||||
fout = fopen(outFile, "w");
|
||||
if (fout == NULL) {
|
||||
printf("Error: Could not open output file.\n");
|
||||
fclose(fin);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
int ch;
|
||||
while ((ch = fgetc(fin)) != EOF) {
|
||||
fputc(ch, fout);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "Total Messages: 1\n");
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
return 0;
|
||||
}
|
||||
30
Tests/RunCMake/pseudo_pvs.c
Normal file
30
Tests/RunCMake/pseudo_pvs.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
FILE* f;
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "-bad") == 0) {
|
||||
fprintf(stdout, "stdout from bad command line arg '-bad'\n");
|
||||
fprintf(stderr, "stderr from bad command line arg '-bad'\n");
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[i], "--output-file") == 0) {
|
||||
i++;
|
||||
f = fopen(argv[i], "w");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Error opening %s for writing\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
fprintf(f, "discard this line\nexample warning\n");
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user