Skip to content

Commit 6916e84

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

7 files changed

Lines changed: 166 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: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,49 @@
1818

1919
#include "frontend.h"
2020

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

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: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
#include "settings.h"
24+
#include "standards.h"
25+
26+
#include <list>
27+
#include <string>
28+
29+
class TestFrontend : public TestFixture {
30+
public:
31+
TestFrontend() : TestFixture("TestFrontend") {}
32+
33+
private:
34+
void run() override {
35+
TEST_CASE(applyLangFS);
36+
}
37+
38+
void applyLangFS() const {
39+
const char xmldata[] = R"(<def format="2"><markup ext=".ml" reporterrors="false"/></def>)";
40+
const Settings s = settingsBuilder().libraryxml(xmldata).build();
41+
42+
const std::list<FileSettings> fs = {
43+
{"nolang", Standards::Language::None, 0 },
44+
{"c", Standards::Language::None, 0 }, // TODO: should be C - FileSettings are currently expected to not be pre-identified
45+
{"cpp", Standards::Language::None, 0 }, // TODO: should be CPP - FileSettings arecurrently expected to not be pre-identified
46+
{"nolang.c", Standards::Language::None, 0 },
47+
{"nolang.cpp", Standards::Language::None, 0 },
48+
{"nolang.ml", Standards::Language::None, 0 }
49+
};
50+
51+
// no language to enforce - identify only
52+
{
53+
std::list<FileSettings> fs1 = fs;
54+
frontend::applyLang(fs1, s, Standards::Language::None);
55+
auto it = fs1.cbegin();
56+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP); // unknown defaults to C++
57+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP); // unknown defaults to C++
58+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP); // unknown defaults to C++
59+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
60+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
61+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C); // markup files are always C
62+
}
63+
64+
// language to enforce (C)
65+
{
66+
std::list<FileSettings> fs1 = fs;
67+
frontend::applyLang(fs1, s, Standards::Language::C);
68+
auto it = fs1.cbegin();
69+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
70+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
71+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
72+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
73+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C);
74+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C); // markup files are always C
75+
}
76+
77+
// language to enforce (C++)
78+
{
79+
std::list<FileSettings> fs1 = fs;
80+
frontend::applyLang(fs1, s, Standards::Language::CPP);
81+
auto it = fs1.cbegin();
82+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
83+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
84+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
85+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
86+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::CPP);
87+
ASSERT_EQUALS_ENUM((it++)->file.lang(), Standards::Language::C); // markup files are always C
88+
}
89+
}
90+
};
91+
92+
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)