Skip to content

Commit 50cff42

Browse files
Merge branch 'cppcheck-opensource:main' into chr_14911
2 parents 0736e65 + 6edf26e commit 50cff42

18 files changed

Lines changed: 434 additions & 22 deletions

.github/workflows/CI-unixish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ jobs:
150150
- name: Run CMake install
151151
run: |
152152
cmake --build cmake.output --target install
153+
# TODO: validate the installed files
153154
154155
- name: Run CMake on ubuntu (no CLI)
155156
if: matrix.os == 'ubuntu-22.04'

.github/workflows/CI-windows.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ defaults:
2121

2222
jobs:
2323

24+
# TODO: use Debug build to speed it up?
2425
build_qt:
2526
strategy:
2627
matrix:
@@ -68,7 +69,10 @@ jobs:
6869

6970
- name: Run CMake install
7071
run: |
72+
rem TODO: this performs a Debug build
73+
rem TODO: the Qt DLLS are not being installed (because of the missing windeployqt?)
7174
cmake --build build --target install
75+
rem TODO: validate the installed files
7276
7377
build_cmake_cxxstd:
7478
strategy:

cli/CMakeLists.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,32 @@ if (BUILD_CLI)
4040
endif()
4141

4242
install(TARGETS cppcheck
43-
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
43+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
4444
COMPONENT applications)
4545

4646
install(PROGRAMS ${CMAKE_SOURCE_DIR}/htmlreport/cppcheck-htmlreport
47-
DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
47+
DESTINATION ${CMAKE_INSTALL_BINDIR}
4848
COMPONENT applications)
4949

50+
# TODO: leverage CMAKE_INSTALL_DATAROOTDIR (share)?
51+
5052
install(FILES ${addons_py}
51-
DESTINATION ${FILESDIR_DEF}/addons
53+
DESTINATION ${FILESDIR_INSTALL}/addons
5254
COMPONENT headers)
5355

5456
install(FILES ${addons_json}
55-
DESTINATION ${FILESDIR_DEF}/addons
57+
DESTINATION ${FILESDIR_INSTALL}/addons
5658
COMPONENT headers)
5759

5860
install(FILES ${cfgs}
59-
DESTINATION ${FILESDIR_DEF}/cfg
61+
DESTINATION ${FILESDIR_INSTALL}/cfg
6062
COMPONENT headers)
6163

6264
install(FILES ${platforms}
63-
DESTINATION ${FILESDIR_DEF}/platforms
65+
DESTINATION ${FILESDIR_INSTALL}/platforms
6466
COMPONENT headers)
6567

68+
# TODO: install manpage into CMAKE_INSTALL_MANDIR
69+
# TODO: install documentation into CMAKE_INSTALL_DOCDIR?
70+
6671
endif()

cmake/options.cmake

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,22 @@ set(CMAKE_DISABLE_PRECOMPILE_HEADERS Off CACHE BOOL "Disable precompiled headers
134134
# see https://gitlab.kitware.com/cmake/cmake/-/issues/21219
135135
set(CMAKE_PCH_PROLOGUE "")
136136

137+
# TODO: do we need to set these?
137138
set(CMAKE_INCLUDE_DIRS_CONFIGCMAKE ${CMAKE_INSTALL_PREFIX}/include CACHE PATH "Output directory for headers")
138139
set(CMAKE_LIB_DIRS_CONFIGCMAKE ${CMAKE_INSTALL_PREFIX}/lib CACHE PATH "Output directory for libraries")
139140

141+
# TODO: do we need to set these?
140142
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
141143
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
142144
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
143145

144146
string(LENGTH "${FILESDIR}" _filesdir_len)
145147
# override FILESDIR if it is set or empty
148+
# needs to be an absolute path in Cppcheck but a relative one for CMake install
146149
if(FILESDIR OR ${_filesdir_len} EQUAL 0)
147-
# TODO: verify that it is an absolute path?
150+
set(FILESDIR_INSTALL "${FILESDIR}") # TODO: make relative - leverage CMAKE_INSTALL_DATAROOTDIR?
148151
set(FILESDIR_DEF "${FILESDIR}")
149152
else()
150-
set(FILESDIR_DEF ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME} CACHE STRING "Cppcheck files directory")
153+
set(FILESDIR_INSTALL "share/${PROJECT_NAME}")
154+
set(FILESDIR_DEF "${CMAKE_INSTALL_PREFIX}/${FILESDIR_INSTALL}")
151155
endif()

cmake/printInfo.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ message(STATUS "Compiler Version = ${CMAKE_CXX_COMPILER_VERSION}")
88
message(STATUS "Build type = ${CMAKE_BUILD_TYPE}")
99
message(STATUS "CMake C++ Standard = ${CMAKE_CXX_STANDARD}")
1010
message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
11+
message(STATUS "CMAKE_INSTALL_BINDIR = ${CMAKE_INSTALL_BINDIR}")
1112
message(STATUS "CMAKE_DISABLE_PRECOMPILE_HEADERS = ${CMAKE_DISABLE_PRECOMPILE_HEADERS}")
1213
message(STATUS "C++ flags (General) = ${CMAKE_CXX_FLAGS}")
1314
message(STATUS "C++ flags (Release) = ${CMAKE_CXX_FLAGS_RELEASE}")
@@ -109,6 +110,7 @@ message(STATUS)
109110
message(STATUS "USE_LIBCXX = ${USE_LIBCXX}")
110111
message(STATUS)
111112
message(STATUS "FILESDIR = ${FILESDIR}")
113+
message(STATUS "FILESDIR_INSTALL = ${FILESDIR_INSTALL}")
112114
message(STATUS "FILESDIR_DEF = ${FILESDIR_DEF}")
113115
message(STATUS)
114116

gui/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ CheckOptions:
7171
add_dependencies(cppcheck-gui online-help.qhc)
7272
endif()
7373

74-
install(TARGETS cppcheck-gui RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} COMPONENT applications)
75-
install(FILES ${qms} DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} COMPONENT applications)
74+
install(TARGETS cppcheck-gui RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications)
75+
install(FILES ${qms} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT applications)
7676

7777
install(FILES cppcheck-gui.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
7878

lib/astutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3001,7 +3001,7 @@ bool isVariableChanged(const Variable * var, const Settings &settings, int depth
30013001
const Token * start = var->declEndToken();
30023002
if (!start)
30033003
return false;
3004-
if (Token::Match(start, "; %varid% =", var->declarationId()))
3004+
if (Token::Match(start, "; %varid% =", var->declarationId()) && !Token::simpleMatch(start->previous(), ")"))
30053005
start = start->tokAt(2);
30063006
if (Token::simpleMatch(start, "=")) {
30073007
const Token* next = nextAfterAstRightmostLeafGeneric(start);

lib/importproject.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -529,27 +529,51 @@ bool ImportProject::importSlnx(const std::string& filename, const std::vector<st
529529
return false;
530530
}
531531

532+
if (std::strcmp(rootnode->Name(), "Solution") != 0) {
533+
errors.emplace_back("Invalid Visual Studio solution file format");
534+
return false;
535+
}
536+
532537
std::map<std::string, std::string, cppcheck::stricmp> variables;
533538
variables["SolutionDir"] = Path::simplifyPath(Path::getPathFromFilename(filename));
534539

535540
bool found = false;
536541
std::vector<SharedItemsProject> sharedItemsProjects;
537542

543+
auto processProject = [&](const tinyxml2::XMLElement* projectNode) {
544+
const char* pathAttribute = projectNode->Attribute("Path");
545+
if (pathAttribute == nullptr)
546+
return true;
547+
548+
std::string vcxproj(pathAttribute);
549+
vcxproj = Path::toNativeSeparators(std::move(vcxproj));
550+
551+
if (Path::getFilenameExtensionInLowerCase(vcxproj) != ".vcxproj")
552+
return true; // skip other project types
553+
554+
if (!Path::isAbsolute(vcxproj))
555+
vcxproj = variables["SolutionDir"] + vcxproj;
556+
557+
vcxproj = Path::fromNativeSeparators(std::move(vcxproj));
558+
if (!importVcxproj(vcxproj, variables, "", fileFilters, sharedItemsProjects)) {
559+
errors.emplace_back("failed to load '" + vcxproj + "' from Visual Studio solution");
560+
return false;
561+
}
562+
found = true;
563+
return true;
564+
};
565+
538566
for (const tinyxml2::XMLElement* node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
539567
const char* name = node->Name();
540568
if (std::strcmp(name, "Project") == 0) {
541-
const char* labelAttribute = node->Attribute("Path");
542-
if (labelAttribute) {
543-
std::string vcxproj(labelAttribute);
544-
vcxproj = Path::toNativeSeparators(std::move(vcxproj));
545-
if (!Path::isAbsolute(vcxproj))
546-
vcxproj = variables["SolutionDir"] + vcxproj;
547-
vcxproj = Path::fromNativeSeparators(std::move(vcxproj));
548-
if (!importVcxproj(vcxproj, variables, "", fileFilters, sharedItemsProjects)) {
549-
errors.emplace_back("failed to load '" + vcxproj + "' from Visual Studio solution");
550-
return false;
569+
if (!processProject(node))
570+
return false;
571+
} else if (std::strcmp(name, "Folder") == 0) {
572+
for (const tinyxml2::XMLElement* childNode = node->FirstChildElement(); childNode; childNode = childNode->NextSiblingElement()) {
573+
if (std::strcmp(childNode->Name(), "Project") == 0) {
574+
if (!processProject(childNode))
575+
return false;
551576
}
552-
found = true;
553577
}
554578
}
555579
}

test/cli/project_test.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ def test_slnx_no_xml_root(tmpdir):
147147
__test_project_error(tmpdir, "slnx", content, expected)
148148

149149

150+
def test_slnx_invalid_xml_root(tmpdir):
151+
content = '<?xml version="1.0" encoding="UTF-8"?>\r\n' \
152+
"<Invalid>\r\n" \
153+
"</Invalid>\r\n"
154+
155+
expected = "Invalid Visual Studio solution file format"
156+
157+
__test_project_error(tmpdir, "slnx", content, expected)
158+
159+
150160
def test_slnx_no_projects(tmpdir):
151161
content = '<?xml version="1.0" encoding="UTF-8"?>\r\n' \
152162
"<Solution>\r\n" \
@@ -161,6 +171,22 @@ def test_slnx_no_projects(tmpdir):
161171
__test_project_error(tmpdir, "slnx", content, expected)
162172

163173

174+
def test_slnx_no_projects_in_folder(tmpdir):
175+
content = '<?xml version="1.0" encoding="UTF-8"?>\r\n' \
176+
"<Solution>\r\n" \
177+
" <Configurations>\r\n" \
178+
' <Platform Name="x64" />\r\n' \
179+
' <Platform Name="x86" />\r\n' \
180+
" </Configurations>\r\n" \
181+
' <Folder Name="/common/">\r\n' \
182+
' </Folder>\r\n' \
183+
"</Solution>\r\n"
184+
185+
expected = "no projects found in Visual Studio solution file"
186+
187+
__test_project_error(tmpdir, "slnx", content, expected)
188+
189+
164190
def test_slnx_project_file_not_found(tmpdir):
165191
content = '<?xml version="1.0" encoding="UTF-8"?>\r\n' \
166192
"<Solution>\r\n" \
@@ -179,6 +205,26 @@ def test_slnx_project_file_not_found(tmpdir):
179205
__test_project_error(tmpdir, "slnx", content, expected)
180206

181207

208+
def test_slnx_project_file_in_folder_not_found(tmpdir):
209+
content = '<?xml version="1.0" encoding="UTF-8"?>\r\n' \
210+
"<Solution>\r\n" \
211+
" <Configurations>\r\n" \
212+
' <Platform Name="x64" />\r\n' \
213+
' <Platform Name="x86" />\r\n' \
214+
" </Configurations>\r\n" \
215+
' <Folder Name="/common/">\r\n' \
216+
' <Project Path="common/test.vcxproj" />\r\n' \
217+
' </Folder>\r\n' \
218+
"</Solution>\r\n"
219+
220+
expected = "Visual Studio project file is not a valid XML - XML_ERROR_FILE_NOT_FOUND\n" \
221+
"cppcheck: error: failed to load '{}' from Visual Studio solution".format(os.path.join(tmpdir, "common/test.vcxproj"))
222+
if sys.platform == "win32":
223+
expected = expected.replace('\\', '/')
224+
225+
__test_project_error(tmpdir, "slnx", content, expected)
226+
227+
182228
def test_vcxproj_no_xml_root(tmpdir):
183229
content = '<?xml version="1.0" encoding="utf-8"?>'
184230

test/cli/slnx-folders/app/app.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "../lib/lib.h"
2+
3+
int main(int argc, char *argv[])
4+
{
5+
int x = 3 / 0; (void)x; // ERROR
6+
return foo();
7+
}

0 commit comments

Comments
 (0)