Skip to content

Commit 539aa4f

Browse files
authored
fixed #13939 - look for platform file relative to project file (first) with CLI (danmar#7612)
1 parent 1af769e commit 539aa4f

File tree

3 files changed

+60
-37
lines changed

3 files changed

+60
-37
lines changed

cli/cmdlineparser.cpp

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
420420
ImportProject project;
421421
std::string vsConfig;
422422

423+
std::string platform;
424+
char defaultSign = '\0';
425+
426+
std::vector<std::string> lookupPaths{argv[0]};
427+
423428
bool executorAuto = true;
424429

425430
for (int i = 1; i < argc; i++) {
@@ -816,10 +821,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
816821
mSettings.force = true;
817822

818823
else if (std::strcmp(argv[i], "--fsigned-char") == 0)
819-
mSettings.platform.defaultSign = 's';
824+
defaultSign = 's';
820825

821826
else if (std::strcmp(argv[i], "--funsigned-char") == 0)
822-
mSettings.platform.defaultSign = 'u';
827+
defaultSign = 'u';
823828

824829
// Ignored paths
825830
else if (std::strncmp(argv[i], "-i", 2) == 0) {
@@ -1067,26 +1072,12 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
10671072

10681073
// Specify platform
10691074
else if (std::strncmp(argv[i], "--platform=", 11) == 0) {
1070-
const std::string platform(11+argv[i]);
1071-
1072-
std::string errstr;
1073-
const std::vector<std::string> paths = {argv[0]};
1074-
if (!mSettings.platform.set(platform, errstr, paths, mSettings.debuglookup || mSettings.debuglookupPlatform)) {
1075-
mLogger.printError(errstr);
1075+
std::string p = 11 + argv[i];
1076+
if (p.empty()) {
1077+
mLogger.printError("empty platform specified.");
10761078
return Result::Fail;
10771079
}
1078-
1079-
// TODO: remove
1080-
// these are loaded via external files and thus have Settings::PlatformFile set instead.
1081-
// override the type so they behave like the regular platforms.
1082-
if (platform == "unix32-unsigned") {
1083-
mSettings.platform.type = Platform::Type::Unix32;
1084-
mLogger.printMessage("The platform 'unix32-unsigned' has been deprecated and will be removed in Cppcheck 2.19. Please use '--platform=unix32 --funsigned-char' instead");
1085-
}
1086-
else if (platform == "unix64-unsigned") {
1087-
mSettings.platform.type = Platform::Type::Unix64;
1088-
mLogger.printMessage("The platform 'unix64-unsigned' has been deprecated and will be removed in Cppcheck 2.19. Please use '--platform=unix64 --funsigned-char' instead");
1089-
}
1080+
platform = std::move(p);
10901081
}
10911082

10921083
// Write results in results.plist
@@ -1179,17 +1170,11 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
11791170
const auto& excludedPaths = project.guiProject.excludedPaths;
11801171
std::copy(excludedPaths.cbegin(), excludedPaths.cend(), std::back_inserter(mIgnoredPaths));
11811172

1182-
std::string platform(project.guiProject.platform);
1173+
if (!project.guiProject.platform.empty())
1174+
platform = project.guiProject.platform;
11831175

1184-
// keep existing platform from command-line intact
1185-
if (!platform.empty()) {
1186-
std::string errstr;
1187-
const std::vector<std::string> paths = {projectFile, argv[0]};
1188-
if (!mSettings.platform.set(platform, errstr, paths, mSettings.debuglookup || mSettings.debuglookupPlatform)) {
1189-
mLogger.printError(errstr);
1190-
return Result::Fail;
1191-
}
1192-
}
1176+
// look for external files relative to project first
1177+
lookupPaths.insert(lookupPaths.cbegin(), projectFile);
11931178

11941179
const auto& projectFileGui = project.guiProject.projectFile;
11951180
if (!projectFileGui.empty()) {
@@ -1614,6 +1599,30 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
16141599
project.ignoreOtherConfigs(vsConfig);
16151600
}
16161601

1602+
if (!platform.empty())
1603+
{
1604+
std::string errstr;
1605+
if (!mSettings.platform.set(platform, errstr, lookupPaths, mSettings.debuglookup || mSettings.debuglookupPlatform)) {
1606+
mLogger.printError(errstr);
1607+
return Result::Fail;
1608+
}
1609+
1610+
// TODO: remove
1611+
// these are loaded via external files and thus have Settings::PlatformFile set instead.
1612+
// override the type so they behave like the regular platforms.
1613+
if (platform == "unix32-unsigned") {
1614+
mSettings.platform.type = Platform::Type::Unix32;
1615+
mLogger.printMessage("The platform 'unix32-unsigned' has been deprecated and will be removed in Cppcheck 2.19. Please use '--platform=unix32 --funsigned-char' instead");
1616+
}
1617+
else if (platform == "unix64-unsigned") {
1618+
mSettings.platform.type = Platform::Type::Unix64;
1619+
mLogger.printMessage("The platform 'unix64-unsigned' has been deprecated and will be removed in Cppcheck 2.19. Please use '--platform=unix64 --funsigned-char' instead");
1620+
}
1621+
}
1622+
1623+
if (defaultSign != '\0')
1624+
mSettings.platform.defaultSign = defaultSign;
1625+
16171626
if (!mSettings.analyzeAllVsConfigs) {
16181627
if (projectType != ImportProject::Type::VS_SLN && projectType != ImportProject::Type::VS_VCXPROJ) {
16191628
if (mAnalyzeAllVsConfigsSetOnCmdLine) {

test/cli/lookup_test.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def test_lib_lookup_notfound_project(tmpdir): # #13938
134134
]
135135

136136

137-
def test_lib_lookup_notfound_compdb(tmpdir): # #13938
137+
def test_lib_lookup_notfound_compdb(tmpdir):
138138
compdb_file, _ = __create_compdb(tmpdir)
139139

140140
exitcode, stdout, _, exe = cppcheck_ex(['--debug-lookup=library', '--library=none', '--project={}'.format(compdb_file)])
@@ -144,7 +144,6 @@ def test_lib_lookup_notfound_compdb(tmpdir): # #13938
144144
assert exitcode == 1, stdout
145145
lines = __remove_std_lookup_log(stdout.splitlines(), exepath)
146146
assert lines == [
147-
# TODO: needs to look relative to the project first
148147
# TODO: specify which folder is actually used for lookup here
149148
"looking for library 'none.cfg'",
150149
"looking for library '{}/none.cfg'".format(exepath),
@@ -409,18 +408,27 @@ def test_platform_lookup_notfound(tmpdir):
409408

410409
def test_platform_lookup_notfound_project(tmpdir): # #13939
411410
project_file, _ = __create_gui_project(tmpdir)
411+
project_path = os.path.dirname(project_file)
412412

413413
exitcode, stdout, _, exe = cppcheck_ex(['--debug-lookup=platform', '--platform=none', '--project={}'.format(project_file)])
414414
exepath = os.path.dirname(exe)
415415
exepath_bin = os.path.join(exepath, 'cppcheck')
416416
if sys.platform == 'win32':
417417
exepath = exepath.replace('\\', '/')
418418
exepath_bin += '.exe'
419+
project_path = project_path.replace('\\', '/')
419420
assert exitcode == 1, stdout
420421
lines = stdout.splitlines()
421422
assert lines == [
422-
# TODO: needs to look relative to project file first
423+
# TODO: the CWD lookups are duplicated
424+
# TODO: needs to do the relative project lookup first
425+
"looking for platform 'none' relative to '{}'".format(project_file),
426+
"try to load platform file 'none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename=none.xml",
427+
"try to load platform file 'platforms/none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename=platforms/none.xml",
428+
"try to load platform file '{}/none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename={}/none.xml".format(project_path, project_path),
429+
"try to load platform file '{}/platforms/none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename={}/platforms/none.xml".format(project_path, project_path),
423430
"looking for platform 'none' relative to '{}'".format(exepath_bin),
431+
# TODO: should we really check CWD before relative to executable? should we check CWD at all?
424432
"try to load platform file 'none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename=none.xml",
425433
"try to load platform file 'platforms/none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename=platforms/none.xml",
426434
"try to load platform file '{}/none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename={}/none.xml".format(exepath, exepath),
@@ -429,7 +437,7 @@ def test_platform_lookup_notfound_project(tmpdir): # #13939
429437
]
430438

431439

432-
def test_platform_lookup_notfound_compdb(tmpdir): # #13939
440+
def test_platform_lookup_notfound_compdb(tmpdir):
433441
compdb_file, _ = __create_compdb(tmpdir)
434442

435443
exitcode, stdout, _, exe = cppcheck_ex(['--debug-lookup=platform', '--platform=none', '--project={}'.format(compdb_file)])
@@ -441,7 +449,6 @@ def test_platform_lookup_notfound_compdb(tmpdir): # #13939
441449
assert exitcode == 1, stdout
442450
lines = stdout.splitlines()
443451
assert lines == [
444-
# TODO: needs to look relative to project file first
445452
"looking for platform 'none' relative to '{}'".format(exepath_bin),
446453
"try to load platform file 'none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename=none.xml",
447454
"try to load platform file 'platforms/none.xml' ... Error=XML_ERROR_FILE_NOT_FOUND ErrorID=3 (0x3) Line number=0: filename=platforms/none.xml",
@@ -686,7 +693,7 @@ def test_addon_lookup_notfound_project(tmpdir): # #13940 / #13941
686693
]
687694

688695

689-
def test_addon_lookup_notfound_compdb(tmpdir): # #13940
696+
def test_addon_lookup_notfound_compdb(tmpdir):
690697
compdb_file, _ = __create_compdb(tmpdir)
691698

692699
exitcode, stdout, _, exe = cppcheck_ex(['--debug-lookup=addon', '--addon=none', '--project={}'.format(compdb_file)])
@@ -695,7 +702,6 @@ def test_addon_lookup_notfound_compdb(tmpdir): # #13940
695702
assert exitcode == 1, stdout
696703
lines = stdout.splitlines()
697704
assert lines == [
698-
# TODO: needs to look relative to the project file first
699705
"looking for addon 'none.py'",
700706
"looking for addon '{}none.py'".format(exepath_sep),
701707
"looking for addon '{}addons/none.py'".format(exepath_sep), # TODO: mixed separators

test/testcmdlineparser.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ class TestCmdlineParser : public TestFixture {
271271
TEST_CASE(platformUnspecified);
272272
TEST_CASE(platformPlatformFile);
273273
TEST_CASE(platformUnknown);
274+
TEST_CASE(platformEmpty);
274275
TEST_CASE(plistEmpty);
275276
TEST_CASE(plistDoesNotExist);
276277
TEST_CASE(suppressionsOld);
@@ -1728,6 +1729,13 @@ class TestCmdlineParser : public TestFixture {
17281729
ASSERT_EQUALS("cppcheck: error: unrecognized platform: 'win128'.\n", logger->str());
17291730
}
17301731

1732+
void platformEmpty() {
1733+
REDIRECT;
1734+
const char * const argv[] = {"cppcheck", "--platform=", "file.cpp"};
1735+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv));
1736+
ASSERT_EQUALS("cppcheck: error: empty platform specified.\n", logger->str());
1737+
}
1738+
17311739
void plistEmpty() {
17321740
REDIRECT;
17331741
const char * const argv[] = {"cppcheck", "--plist-output=", "file.cpp"};

0 commit comments

Comments
 (0)