Skip to content

Commit 5a8e365

Browse files
committed
fixed #13909 / refs #13914 - added (enforced) language handling for imported projects in GUI
1 parent e8c5e0c commit 5a8e365

7 files changed

Lines changed: 157 additions & 39 deletions

File tree

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ TESTOBJ = test/fixture.o \
295295
test/testexecutor.o \
296296
test/testfilelister.o \
297297
test/testfilesettings.o \
298+
test/testfrontend.o \
298299
test/testfunctions.o \
299300
test/testgarbage.o \
300301
test/testimportproject.o \
@@ -659,7 +660,7 @@ $(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/addoninfo.h lib/as
659660
$(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h
660661
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vfvalue.cpp
661662

662-
frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h
663+
frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/addoninfo.h lib/checkers.h lib/config.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/utils.h
663664
$(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp
664665

665666
cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.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
@@ -770,6 +771,9 @@ test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h
770771
test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.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/utils.h test/fixture.h
771772
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp
772773

774+
test/testfrontend.o: test/testfrontend.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.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/utils.h test/fixture.h
775+
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp
776+
773777
test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
774778
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp
775779

cli/cmdlineparser.cpp

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#include "timer.h"
4040
#include "utils.h"
4141

42+
#include "frontend.h"
43+
4244
#include <algorithm>
4345
#include <cassert>
4446
#include <climits>
@@ -221,40 +223,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
221223

222224
mFileSettings.clear();
223225

224-
if (mEnforcedLang != Standards::Language::None)
225-
{
226-
// apply enforced language
227-
for (auto& fs : fileSettings)
228-
{
229-
if (mSettings.library.markupFile(fs.filename()))
230-
continue;
231-
fs.file.setLang(mEnforcedLang);
232-
}
233-
}
234-
else
235-
{
236-
// identify files
237-
for (auto& fs : fileSettings)
238-
{
239-
if (mSettings.library.markupFile(fs.filename()))
240-
continue;
241-
assert(fs.file.lang() == Standards::Language::None);
242-
bool header = false;
243-
fs.file.setLang(Path::identify(fs.filename(), mSettings.cppHeaderProbe, &header));
244-
// unknown extensions default to C++
245-
if (!header && fs.file.lang() == Standards::Language::None)
246-
fs.file.setLang(Standards::Language::CPP);
247-
}
248-
}
249-
250-
// enforce the language since markup files are special and do not adhere to the enforced language
251-
for (auto& fs : fileSettings)
252-
{
253-
if (mSettings.library.markupFile(fs.filename())) {
254-
assert(fs.file.lang() == Standards::Language::None);
255-
fs.file.setLang(Standards::Language::C);
256-
}
257-
}
226+
frontend::applyLang(fileSettings, mSettings, mEnforcedLang);
258227

259228
// sort the markup last
260229
std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) {

frontend/frontend.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,45 @@
1818

1919
#include "frontend.h"
2020

21-
namespace frontend
22-
{}
21+
#include "filesettings.h"
22+
#include "settings.h"
23+
24+
namespace frontend {
25+
void applyLang(std::list<FileSettings>& fileSettings, const Settings& settings, Standards::Language enforcedLang)
26+
{
27+
if (enforcedLang != Standards::Language::None)
28+
{
29+
// apply enforced language
30+
for (auto& fs : fileSettings)
31+
{
32+
if (settings.library.markupFile(fs.filename()))
33+
continue;
34+
fs.file.setLang(enforcedLang);
35+
}
36+
}
37+
else
38+
{
39+
// identify files
40+
for (auto& fs : fileSettings)
41+
{
42+
if (settings.library.markupFile(fs.filename()))
43+
continue;
44+
assert(fs.file.lang() == Standards::Language::None);
45+
bool header = false;
46+
fs.file.setLang(Path::identify(fs.filename(), settings.cppHeaderProbe, &header));
47+
// unknown extensions default to C++
48+
if (!header && fs.file.lang() == Standards::Language::None)
49+
fs.file.setLang(Standards::Language::CPP);
50+
}
51+
}
52+
53+
// enforce the language since markup files are special and do not adhere to the enforced language
54+
for (auto& fs : fileSettings)
55+
{
56+
if (settings.library.markupFile(fs.filename())) {
57+
assert(fs.file.lang() == Standards::Language::None);
58+
fs.file.setLang(Standards::Language::C);
59+
}
60+
}
61+
}
62+
}

frontend/frontend.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,19 @@
1919
#ifndef FRONTEND_H
2020
#define FRONTEND_H
2121

22+
#include "standards.h"
23+
24+
#include <list>
25+
26+
struct FileSettings;
27+
class Settings;
28+
2229
namespace frontend
23-
{}
30+
{
31+
/**
32+
Applies the enforced language as all as identifying remaining files - also taking markup files into consideration.
33+
*/
34+
void applyLang(std::list<FileSettings> &fileSettings, const Settings &settings, Standards::Language enforcedLang);
35+
}
2436

2537
#endif // FRONTEND_H

gui/mainwindow.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454

5555
#include "ui_mainwindow.h"
5656

57+
#include "frontend.h"
58+
5759
#include <algorithm>
5860
#include <iterator>
5961
#include <list>
@@ -604,6 +606,10 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLibrary, cons
604606
mThread->setClangIncludePaths(clangHeaders.split(";"));
605607
mThread->setSuppressions(mProjectFile->getSuppressions());
606608
}
609+
610+
const Standards::Language enforcedLang = static_cast<Standards::Language>(mSettings->value(SETTINGS_ENFORCED_LANGUAGE, 0).toInt());
611+
frontend::applyLang(p.fileSettings, checkSettings, enforcedLang);
612+
607613
mThread->setProject(p);
608614
mThread->check(checkSettings, supprs);
609615
mUI->mResults->setCheckSettings(checkSettings);
@@ -1208,7 +1214,6 @@ bool MainWindow::getCppcheckSettings(Settings& settings, Suppressions& supprs)
12081214
settings.platform.set(static_cast<Platform::Type>(mSettings->value(SETTINGS_CHECKED_PLATFORM, 0).toInt()));
12091215
settings.standards.setCPP(mSettings->value(SETTINGS_STD_CPP, QString()).toString().toStdString());
12101216
settings.standards.setC(mSettings->value(SETTINGS_STD_C, QString()).toString().toStdString());
1211-
Standards::Language enforcedLang = static_cast<Standards::Language>(mSettings->value(SETTINGS_ENFORCED_LANGUAGE, 0).toInt());
12121217

12131218
settings.jobs = std::max(settings.jobs, 1u);
12141219

test/testfrontend.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2025 Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include <filesettings.h>
20+
21+
#include "fixture.h"
22+
#include "frontend.h"
23+
24+
class TestFrontend : public TestFixture {
25+
public:
26+
TestFrontend() : TestFixture("TestFrontend") {}
27+
28+
private:
29+
void run() override {
30+
TEST_CASE(applyLangFS);
31+
}
32+
33+
void applyLangFS() const {
34+
const char xmldata[] = R"(<def format="2"><markup ext=".ml" reporterrors="false"/></def>)";
35+
const Settings s = settingsBuilder().libraryxml(xmldata).build();
36+
37+
const std::list<FileSettings> fs = {
38+
{"nolang", Standards::Language::None, 0 },
39+
{"c", Standards::Language::None, 0 }, // TODO: should be C - FileSettings are currently expected to not be pre-identified
40+
{"cpp", Standards::Language::None, 0 }, // TODO: should be CPP - FileSettings arecurrently expected to not be pre-identified
41+
{"nolang.c", Standards::Language::None, 0 },
42+
{"nolang.cpp", Standards::Language::None, 0 },
43+
{"nolang.ml", Standards::Language::None, 0 }
44+
};
45+
46+
// no language to enforce - identify only
47+
{
48+
std::list<FileSettings> fs1 = fs;
49+
frontend::applyLang(fs1, s, Standards::Language::None);
50+
auto it = fs1.cbegin();
51+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP); // unknown defaults to C++
52+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP); // unknown defaults to C++
53+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP); // unknown defaults to C++
54+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
55+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
56+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C); // markup files are always C
57+
}
58+
59+
// language to enforce (C)
60+
{
61+
std::list<FileSettings> fs1 = fs;
62+
frontend::applyLang(fs1, s, Standards::Language::C);
63+
auto it = fs1.cbegin();
64+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
65+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
66+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
67+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
68+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
69+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C); // markup files are always C
70+
}
71+
72+
// language to enforce (C++)
73+
{
74+
std::list<FileSettings> fs1 = fs;
75+
frontend::applyLang(fs1, s, Standards::Language::CPP);
76+
auto it = fs1.cbegin();
77+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
78+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
79+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
80+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
81+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
82+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C); // markup files are always C
83+
}
84+
}
85+
};
86+
87+
REGISTER_TEST(TestFrontend)

test/testrunner.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
<ClCompile Include="testexecutor.cpp" />
6666
<ClCompile Include="testfilelister.cpp" />
6767
<ClCompile Include="testfilesettings.cpp" />
68+
<ClCompile Include="testfrontend.cpp" />
6869
<ClCompile Include="testfunctions.cpp" />
6970
<ClCompile Include="testgarbage.cpp" />
7071
<ClCompile Include="testimportproject.cpp" />

0 commit comments

Comments
 (0)