Skip to content

Commit 23b0c9a

Browse files
authored
refs #13789 - --project-configuration had no effect with wrapped Visual Studio project (danmar#7476)
1 parent 6a71e3b commit 23b0c9a

File tree

5 files changed

+71
-21
lines changed

5 files changed

+71
-21
lines changed

cli/cmdlineparser.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
441441
bool def = false;
442442
bool maxconfigs = false;
443443

444+
ImportProject::Type projectType = ImportProject::Type::NONE;
444445
ImportProject project;
446+
std::string vsConfig;
445447

446448
bool executorAuto = true;
447449

@@ -1160,17 +1162,16 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
11601162

11611163
// --project
11621164
else if (std::strncmp(argv[i], "--project=", 10) == 0) {
1163-
if (project.projectType != ImportProject::Type::NONE)
1165+
if (projectType != ImportProject::Type::NONE)
11641166
{
11651167
mLogger.printError("multiple --project options are not supported.");
11661168
return Result::Fail;
11671169
}
11681170

11691171
mSettings.checkAllConfigurations = false; // Can be overridden with --max-configs or --force
11701172
std::string projectFile = argv[i]+10;
1171-
ImportProject::Type projType = project.import(projectFile, &mSettings, &mSuppressions);
1172-
project.projectType = projType;
1173-
if (projType == ImportProject::Type::CPPCHECK_GUI) {
1173+
projectType = project.import(projectFile, &mSettings, &mSuppressions);
1174+
if (projectType == ImportProject::Type::CPPCHECK_GUI) {
11741175
for (const std::string &lib : project.guiProject.libraries)
11751176
mSettings.libraries.emplace_back(lib);
11761177

@@ -1193,38 +1194,43 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
11931194
if (!projectFileGui.empty()) {
11941195
// read underlying project
11951196
projectFile = projectFileGui;
1196-
projType = project.import(projectFileGui, &mSettings, &mSuppressions);
1197-
if (projType == ImportProject::Type::CPPCHECK_GUI) {
1197+
projectType = project.import(projectFileGui, &mSettings, &mSuppressions);
1198+
if (projectType == ImportProject::Type::CPPCHECK_GUI) {
11981199
mLogger.printError("nested Cppcheck GUI projects are not supported.");
11991200
return Result::Fail;
12001201
}
12011202
}
12021203
}
1203-
if (projType == ImportProject::Type::VS_SLN || projType == ImportProject::Type::VS_VCXPROJ) {
1204+
if (projectType == ImportProject::Type::VS_SLN || projectType == ImportProject::Type::VS_VCXPROJ) {
12041205
if (project.guiProject.analyzeAllVsConfigs == "false")
12051206
project.selectOneVsConfig(mSettings.platform.type);
12061207
mSettings.libraries.emplace_back("windows");
12071208
}
1208-
if (projType == ImportProject::Type::MISSING) {
1209+
if (projectType == ImportProject::Type::MISSING) {
12091210
mLogger.printError("failed to open project '" + projectFile + "'. The file does not exist.");
12101211
return Result::Fail;
12111212
}
1212-
if (projType == ImportProject::Type::UNKNOWN) {
1213+
if (projectType == ImportProject::Type::UNKNOWN) {
12131214
mLogger.printError("failed to load project '" + projectFile + "'. The format is unknown.");
12141215
return Result::Fail;
12151216
}
1216-
if (projType == ImportProject::Type::FAILURE) {
1217+
if (projectType == ImportProject::Type::FAILURE) {
12171218
mLogger.printError("failed to load project '" + projectFile + "'. An error occurred.");
12181219
return Result::Fail;
12191220
}
12201221
}
12211222

12221223
// --project-configuration
12231224
else if (std::strncmp(argv[i], "--project-configuration=", 24) == 0) {
1224-
mVSConfig = argv[i] + 24;
1225-
// TODO: provide error when this does nothing
1226-
if (!mVSConfig.empty() && (project.projectType == ImportProject::Type::VS_SLN || project.projectType == ImportProject::Type::VS_VCXPROJ))
1227-
project.ignoreOtherConfigs(mVSConfig);
1225+
vsConfig = argv[i] + 24;
1226+
if (vsConfig.empty()) {
1227+
mLogger.printError("--project-configuration parameter is empty.");
1228+
return Result::Fail;
1229+
}
1230+
if (projectType != ImportProject::Type::VS_SLN && projectType != ImportProject::Type::VS_VCXPROJ) {
1231+
mLogger.printError("--project-configuration has no effect - no Visual Studio project provided.");
1232+
return Result::Fail;
1233+
}
12281234
}
12291235

12301236
// Only print something when there are errors
@@ -1594,11 +1600,15 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
15941600
//mLogger.printMessage("whole program analysis requires --cppcheck-build-dir to be active with -j.");
15951601
}
15961602

1597-
if (!mPathNames.empty() && project.projectType != ImportProject::Type::NONE) {
1603+
if (!mPathNames.empty() && projectType != ImportProject::Type::NONE) {
15981604
mLogger.printError("--project cannot be used in conjunction with source files.");
15991605
return Result::Fail;
16001606
}
16011607

1608+
if (!vsConfig.empty()) {
1609+
project.ignoreOtherConfigs(vsConfig);
1610+
}
1611+
16021612
if (!mSettings.buildDir.empty() && !Path::isDirectory(mSettings.buildDir)) {
16031613
mLogger.printError("Directory '" + mSettings.buildDir + "' specified by --cppcheck-build-dir argument has to be existent.");
16041614
return Result::Fail;

cli/cmdlineparser.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ class CmdLineParser {
164164
std::vector<std::string> mIgnoredPaths;
165165
Settings &mSettings;
166166
Suppressions &mSuppressions;
167-
std::string mVSConfig;
168167
};
169168

170169
/// @}

lib/importproject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class CPPCHECKLIB WARN_UNUSED ImportProject {
7070
static void fsSetIncludePaths(FileSettings& fs, const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables);
7171

7272
std::list<FileSettings> fileSettings;
73-
Type projectType{Type::NONE};
7473

7574
ImportProject() = default;
7675
virtual ~ImportProject() = default;

test/cli/helloworld_test.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import json
88
import xml.etree.ElementTree as ET
99

10+
import pytest
11+
1012
from testutils import create_gui_project_file, cppcheck
1113

1214
__script_dir = os.path.dirname(os.path.abspath(__file__))
@@ -145,16 +147,27 @@ def test_basepath_absolute_path():
145147
assert ret == 0, stdout
146148
assert stderr == '[main.c:5]: (error) Division by zero.\n'
147149

148-
def test_vs_project_local_path():
150+
def __test_vs_project_local_path(extra_args=None, exp_vs_cfg='Debug|Win32 Debug|x64 Release|Win32 Release|x64'):
149151
args = [
150152
'--template=cppcheck1',
151153
'--project=helloworld.vcxproj'
152154
]
155+
if extra_args:
156+
args += extra_args
153157
ret, stdout, stderr = cppcheck(args, cwd=__proj_dir)
154158
assert ret == 0, stdout
155-
assert __getVsConfigs(stdout, 'main.c') == 'Debug|Win32 Debug|x64 Release|Win32 Release|x64'
159+
assert __getVsConfigs(stdout, 'main.c') == exp_vs_cfg
156160
assert stderr == '[main.c:5]: (error) Division by zero.\n'
157161

162+
def test_vs_project_local_path():
163+
__test_vs_project_local_path()
164+
165+
def test_vs_project_local_path_select_one():
166+
__test_vs_project_local_path(['--project-configuration=Release|Win32'], 'Release|Win32')
167+
168+
def test_vs_project_local_path_select_one_multiple():
169+
__test_vs_project_local_path(['--project-configuration=Debug|Win32', '--project-configuration=Release|Win32'], 'Release|Win32')
170+
158171
def test_vs_project_relative_path():
159172
args = [
160173
'--template=cppcheck1',
@@ -177,17 +190,30 @@ def test_vs_project_absolute_path():
177190
assert __getVsConfigs(stdout, filename) == 'Debug|Win32 Debug|x64 Release|Win32 Release|x64'
178191
assert stderr == '[%s:5]: (error) Division by zero.\n' % filename
179192

180-
def test_cppcheck_project_local_path():
193+
def __test_cppcheck_project_local_path(extra_args=None, exp_vs_cfg='Debug|x64'):
181194
args = [
182195
'--template=cppcheck1',
183196
'--platform=win64',
184197
'--project=helloworld.cppcheck'
185198
]
199+
if extra_args:
200+
args += extra_args
186201
ret, stdout, stderr = cppcheck(args, cwd=__proj_dir)
187202
assert ret == 0, stdout
188-
assert __getVsConfigs(stdout, 'main.c') == 'Debug|x64'
203+
assert __getVsConfigs(stdout, 'main.c') == exp_vs_cfg
189204
assert stderr == '[main.c:5]: (error) Division by zero.\n'
190205

206+
def test_cppcheck_project_local_path():
207+
__test_cppcheck_project_local_path()
208+
209+
@pytest.mark.xfail # TODO: no source files found
210+
def test_cppcheck_project_local_path_select_one():
211+
__test_cppcheck_project_local_path(['--project-configuration=Release|Win32'], 'Release|Win32')
212+
213+
@pytest.mark.xfail # TODO: no source files found
214+
def test_cppcheck_project_local_path_select_one_multiple():
215+
__test_cppcheck_project_local_path(['--project-configuration=Debug|Win32', '--project-configuration=Release|Win32'], 'Release|Win32')
216+
191217
def test_cppcheck_project_relative_path():
192218
args = [
193219
'--template=cppcheck1',

test/testcmdlineparser.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ class TestCmdlineParser : public TestFixture {
450450
TEST_CASE(noCheckUnusedTemplates);
451451
TEST_CASE(clangTidy);
452452
TEST_CASE(clangTidyCustom);
453+
TEST_CASE(projectConfigurationNoProject);
454+
TEST_CASE(projectConfigurationEmpty);
453455

454456
TEST_CASE(ignorepaths1);
455457
TEST_CASE(ignorepaths2);
@@ -3066,6 +3068,20 @@ class TestCmdlineParser : public TestFixture {
30663068
ASSERT_EQUALS("clang-tidy-14", settings->clangTidyExecutable);
30673069
}
30683070

3071+
void projectConfigurationNoProject() {
3072+
REDIRECT;
3073+
const char * const argv[] = {"cppcheck", "--project-configuration=Debug|Win32", "file.cpp"};
3074+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv));
3075+
ASSERT_EQUALS("cppcheck: error: --project-configuration has no effect - no Visual Studio project provided.\n", logger->str());
3076+
}
3077+
3078+
void projectConfigurationEmpty() {
3079+
REDIRECT;
3080+
const char * const argv[] = {"cppcheck", "--project-configuration=", "file.cpp"};
3081+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv));
3082+
ASSERT_EQUALS("cppcheck: error: --project-configuration parameter is empty.\n", logger->str());
3083+
}
3084+
30693085
void ignorepaths1() {
30703086
REDIRECT;
30713087
const char * const argv[] = {"cppcheck", "-isrc", "file.cpp"};

0 commit comments

Comments
 (0)