mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-24 14:22:40 -06:00
Merge 87ef93a2be into f99920247f
This commit is contained in:
commit
a6cabeb488
20 changed files with 1425 additions and 2 deletions
173
uppsrc/ide/Linter/ClangTidy.cpp
Normal file
173
uppsrc/ide/Linter/ClangTidy.cpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#include "ClangTidy.h"
|
||||
|
||||
static String sExeFilePath;
|
||||
|
||||
String ClangTidy::GetConfigFilePath() const
|
||||
{
|
||||
return ConfigFile(AppendFileName("clangtidy", IdeGetCurrentMainPackage() + "-clangtidy.json"));
|
||||
}
|
||||
|
||||
Value ClangTidy::LoadConfig()
|
||||
{
|
||||
String path = GetConfigFilePath();
|
||||
if(!FileExists(path))
|
||||
return Null;
|
||||
return ParseJSON(LoadFile(path));
|
||||
}
|
||||
|
||||
void ClangTidy::SaveConfig(const Value& cfg)
|
||||
{
|
||||
String path = GetConfigFilePath();
|
||||
RealizePath(path);
|
||||
SaveChangedFile(path, cfg);
|
||||
}
|
||||
|
||||
bool ClangTidy::Exists() const
|
||||
{
|
||||
static bool b = false;
|
||||
ONCELOCK
|
||||
{
|
||||
#ifdef flagWIN32
|
||||
// FIXME: Check path.
|
||||
constexpr const char *exe = "C:\\Program Files\\LLVM\\bin\\clang-tidy.exe";
|
||||
b = FileExists(exe);
|
||||
if(b) sExeFilePath << "\"" << exe << "\"";
|
||||
#else
|
||||
b = Sys("which clang-tidy", sExeFilePath) == 0;
|
||||
if(b) sExeFilePath = TrimRight(sExeFilePath);
|
||||
else sExeFilePath.Clear();
|
||||
#endif
|
||||
}
|
||||
return b && TheIde();
|
||||
}
|
||||
|
||||
void ClangTidy::Settings()
|
||||
{
|
||||
ClangTidyConfigDlg dlg(*this);
|
||||
dlg.Load();
|
||||
if(dlg.ExecuteOK())
|
||||
dlg.Save();
|
||||
}
|
||||
|
||||
Vector<String> ClangTidy::ResolveProject(const String& ccjpath)
|
||||
{
|
||||
Vector<String> files;
|
||||
Value ccj = ParseJSON(LoadFile(ccjpath));
|
||||
for(int i = 0; i < ccj.GetCount(); i++)
|
||||
files.Add(ccj[i]["file"]);
|
||||
return files;
|
||||
}
|
||||
|
||||
Vector<String> ClangTidy::ResolvePackage(const String& ccjpath, const Vector<String>& paths)
|
||||
{
|
||||
Vector<String> files;
|
||||
Value ccj = ParseJSON(LoadFile(ccjpath));
|
||||
for(int i = 0; i < ccj.GetCount(); i++) {
|
||||
String file = ccj[i]["file"];
|
||||
// Length-check prevents prefix collisions (e.g. /upp/Core vs /upp/Core2)
|
||||
for(const String& p : paths) {
|
||||
int pl = p.GetLength();
|
||||
if(file.StartsWith(p) && (file.GetLength() == pl || file[pl] == '/' || file[pl] == '\\')) {
|
||||
files.Add(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
Vector<String> ClangTidy::ResolveFiles(Scope sc, const String& ccjpath, const Vector<String>& paths)
|
||||
{
|
||||
bool hasccj = FileExists(ccjpath);
|
||||
switch(sc) {
|
||||
case Scope::File:
|
||||
return clone(paths);
|
||||
case Scope::Project:
|
||||
return hasccj ? ResolveProject(ccjpath) : clone(paths);
|
||||
case Scope::Package:
|
||||
return hasccj ? ResolvePackage(ccjpath, paths) : clone(paths);
|
||||
}
|
||||
return clone(paths);
|
||||
}
|
||||
|
||||
String ClangTidy::MakeCmdLine(Scope sc, Vector<String>& paths)
|
||||
{
|
||||
Value v = LoadConfig()["ClangTidy"];
|
||||
|
||||
// Is there a better way to obtain compile_commands.json file?
|
||||
String ccjdir = GetTempPath();
|
||||
String ccjpath = AppendFileName(ccjdir, "compile_commands.json");
|
||||
|
||||
if(MakeBuild *mb = dynamic_cast<MakeBuild *>(TheIdeContext()))
|
||||
mb->SaveCCJ(ccjpath, false);
|
||||
|
||||
String path;
|
||||
for(const String& f : ResolveFiles(sc, ccjpath, paths))
|
||||
path << "\"" << f << "\" ";
|
||||
|
||||
if(IsNull(v))
|
||||
return sExeFilePath + " --checks=* " + path;
|
||||
|
||||
String checks = Nvl(v["checks"], "*");
|
||||
String extraargs = Nvl(v["extra_args"], "");
|
||||
String standard = Nvl(v["standard"], "c++14");
|
||||
|
||||
String s;
|
||||
s << sExeFilePath << " "
|
||||
<< "--checks=\"" << checks << "\" "
|
||||
<< "--quiet ";
|
||||
|
||||
if(FileExists(ccjpath))
|
||||
s << "-p=\"" << ccjdir << "\" ";
|
||||
|
||||
return s + extraargs + (extraargs.GetCount() ? " " : "") + path
|
||||
+ (FileExists(ccjpath) ? "" : "-- -std=" + standard);
|
||||
}
|
||||
|
||||
void ClangTidy::OnResults(const String& results)
|
||||
{
|
||||
// FIXME: This is fragile, but not all versions of clang have JSON output...
|
||||
RegExp r("([A-Za-z]?:?[/\\\\][^:]+\\.[ch]pp):(\\d+):(\\d+): (\\w+): (.+?)(\\s+\\[[\\w,.-]+\\])?$");
|
||||
|
||||
for(const String& line : Split(results, '\n', false)) {
|
||||
if(!r.Match(line))
|
||||
continue;
|
||||
|
||||
Vector<String> v = r.GetStrings();
|
||||
if(v.GetCount() < 5)
|
||||
continue;
|
||||
|
||||
String severity = v.At(3);
|
||||
if(severity == "note")
|
||||
continue;
|
||||
|
||||
Ide::ListLineInfo e;
|
||||
e.file = v.At(0);
|
||||
e.lineno = StrInt(v.At(1));
|
||||
e.linepos = StrInt(v.At(2));
|
||||
e.kind = severity == "error" ? 0 : 1;
|
||||
e.message = v.At(4) + TrimLeft(v.At(5));
|
||||
|
||||
Image img = decode(
|
||||
severity,
|
||||
"error", LinterImg::error(),
|
||||
"warning", LinterImg::warning(),
|
||||
LinterImg::warning()
|
||||
);
|
||||
Color paper = HighlightSetup::GetHlStyle(e.kind == 0 ? HighlightSetup::PAPER_ERROR
|
||||
: HighlightSetup::PAPER_WARNING).color;
|
||||
int linecy;
|
||||
AttrText txt(TheIde()->FormatErrorLine(e.message, linecy));
|
||||
txt.NormalPaper(paper);
|
||||
txt.SetImage(img);
|
||||
|
||||
ArrayCtrl& error = TheIde()->error;
|
||||
error.Add(e.file, e.lineno, txt, RawToValue(e));
|
||||
error.SetLineCy(error.GetCount() - 1, linecy);
|
||||
}
|
||||
}
|
||||
|
||||
INITIALIZER(ClangTidy)
|
||||
{
|
||||
RegisterLinterModule(Single<ClangTidy>("ClangTidy"));
|
||||
}
|
||||
39
uppsrc/ide/Linter/ClangTidy.h
Normal file
39
uppsrc/ide/Linter/ClangTidy.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef _ClangTidy_h_
|
||||
#define _ClangTidy_h_
|
||||
|
||||
#include "Linter.h"
|
||||
|
||||
#define LAYOUTFILE <ide/Linter/ClangTidyConfig.lay>
|
||||
#include <CtrlCore/lay.h>
|
||||
|
||||
class ClangTidy : public Linter {
|
||||
public:
|
||||
ClangTidy(const String& name) : Linter(name) {}
|
||||
|
||||
virtual String GetConfigFilePath() const final;
|
||||
virtual Value LoadConfig() final;
|
||||
virtual void SaveConfig(const Value& cfg) final;
|
||||
virtual bool Exists() const final;
|
||||
virtual void Settings() final;
|
||||
|
||||
private:
|
||||
Vector<String> ResolveProject(const String& ccjpath);
|
||||
Vector<String> ResolvePackage(const String& ccjpath, const Vector<String>& paths);
|
||||
Vector<String> ResolveFiles (Scope sc, const String& ccjpath, const Vector<String>& paths);
|
||||
|
||||
virtual String MakeCmdLine(Scope sc, Vector<String>& paths) final;
|
||||
virtual void OnResults(const String& results) final;
|
||||
};
|
||||
|
||||
INITIALIZE(ClangTidy);
|
||||
|
||||
class ClangTidyConfigDlg : public WithClangTidyConfigLayout<TopWindow>, public Linter::Config {
|
||||
public:
|
||||
ClangTidyConfigDlg(Linter& l);
|
||||
|
||||
virtual void Load() final;
|
||||
virtual void Save() final;
|
||||
virtual void Reset() final;
|
||||
};
|
||||
|
||||
#endif
|
||||
19
uppsrc/ide/Linter/ClangTidyConfig.cpp
Normal file
19
uppsrc/ide/Linter/ClangTidyConfig.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "Linter.h"
|
||||
|
||||
ClangTidyConfigDlg::ClangTidyConfigDlg(Linter& l)
|
||||
: Linter::Config(l)
|
||||
{
|
||||
}
|
||||
|
||||
void ClangTidyConfigDlg::Load()
|
||||
{
|
||||
}
|
||||
|
||||
void ClangTidyConfigDlg::Save()
|
||||
{
|
||||
}
|
||||
|
||||
void ClangTidyConfigDlg::Reset()
|
||||
{
|
||||
}
|
||||
|
||||
3
uppsrc/ide/Linter/ClangTidyConfig.lay
Normal file
3
uppsrc/ide/Linter/ClangTidyConfig.lay
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
LAYOUT(ClangTidyConfigLayout, 400, 200)
|
||||
END_LAYOUT
|
||||
|
||||
22
uppsrc/ide/Linter/Copying
Normal file
22
uppsrc/ide/Linter/Copying
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Copyright (c) 1998, 2023, The U++ Project
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of
|
||||
conditions and the following disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
167
uppsrc/ide/Linter/CppCheck.cpp
Normal file
167
uppsrc/ide/Linter/CppCheck.cpp
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#include "CppCheck.h"
|
||||
|
||||
static String sExeFilePath;
|
||||
static bool sVerboseMode = false;
|
||||
|
||||
String CppCheck::GetConfigFilePath() const
|
||||
{
|
||||
return ConfigFile(AppendFileName("cppcheck", IdeGetCurrentMainPackage() + "-cppcheck.json"));
|
||||
}
|
||||
|
||||
Value CppCheck::LoadConfig()
|
||||
{
|
||||
String path = GetConfigFilePath();
|
||||
if(!FileExists(path))
|
||||
return Null;
|
||||
return ParseJSON(LoadFile(path));
|
||||
}
|
||||
|
||||
void CppCheck::SaveConfig(const Value& cfg)
|
||||
{
|
||||
String path = GetConfigFilePath();
|
||||
RealizePath(path);
|
||||
SaveChangedFile(path, cfg);
|
||||
}
|
||||
|
||||
bool CppCheck::Exists() const
|
||||
{
|
||||
static bool b = false;
|
||||
ONCELOCK {
|
||||
#ifdef flagWIN32
|
||||
constexpr const char *exe = "C:\\Program Files\\CppCheck\\cppcheck.exe";
|
||||
b = FileExists(exe);
|
||||
if(b) sExeFilePath << "\"" << exe << "\"";
|
||||
#else
|
||||
b = Sys("which cppcheck", sExeFilePath) == 0;
|
||||
if(b) sExeFilePath = TrimRight(sExeFilePath);
|
||||
else sExeFilePath.Clear();
|
||||
#endif
|
||||
}
|
||||
return b && TheIde();
|
||||
}
|
||||
|
||||
void CppCheck::Settings()
|
||||
{
|
||||
CppCheckConfigDlg dlg(static_cast<Linter&>(*this));
|
||||
dlg.Load();
|
||||
if(dlg.ExecuteOK())
|
||||
dlg.Save();
|
||||
}
|
||||
|
||||
String CppCheck::MakeCmdLine(Scope sc, Vector<String>& paths)
|
||||
{
|
||||
String path;
|
||||
for(const String& s : paths)
|
||||
path << "\"" << s << "\" ";
|
||||
|
||||
Value v = LoadConfig()["CppCheck"];
|
||||
if(IsNull(v))
|
||||
return sExeFilePath
|
||||
+ " --language=c++ --std=c++17 --platform=native"
|
||||
" --enable=all --xml -i *.tpp " + path;
|
||||
|
||||
int depth = v["depth"];
|
||||
int jobs = v["jobs"];
|
||||
String opts = v["cmdline_options"];
|
||||
|
||||
Vector<String> severity;
|
||||
for(const Value& q : v["severity"])
|
||||
if(!IsNull(q))
|
||||
severity.Add() = q;
|
||||
|
||||
String s;
|
||||
s << sExeFilePath << " "
|
||||
<< "--force "
|
||||
<< "--xml "
|
||||
<< "--language=" << Nvl(v["language"], "c++") << " "
|
||||
<< "--platform=" << Nvl(v["platform"], "native") << " "
|
||||
<< "--std=" << Nvl(v["standard"], "c++17") << " "
|
||||
<< "--max-ctu-depth=" << AsString(clamp(depth, 1, 6)) << " "
|
||||
<< "-j " << AsString(clamp(jobs, 1, 1024)) << " ";
|
||||
|
||||
if(severity.GetCount())
|
||||
s << "--enable=" << Join(severity, ",", true) << " ";
|
||||
|
||||
for(const String& q : v["libraries"])
|
||||
if(FileExists(q))
|
||||
s << "--library=\"" << q << "\" ";
|
||||
|
||||
for(const String& q : v["addons"])
|
||||
if(FileExists(q))
|
||||
s << "--plugin=\"" << q << "\" ";
|
||||
|
||||
sVerboseMode = v["verbose_mode"];
|
||||
|
||||
// Ensure clean spacing between user options and paths
|
||||
return s + opts + (opts.GetCount() ? " " : "") + path;
|
||||
}
|
||||
|
||||
void CppCheck::OnResults(const String& results)
|
||||
{
|
||||
DecodeXML(ParseXML(results)["results"]);
|
||||
}
|
||||
|
||||
void CppCheck::DecodeXML(const XmlNode& results)
|
||||
{
|
||||
if(results.IsTag("results")) {
|
||||
DecodeXML(results["errors"]);
|
||||
}
|
||||
else
|
||||
if(results.IsTag("errors")) {
|
||||
for(const XmlNode& node : results) {
|
||||
if(!node.IsTag("error"))
|
||||
continue;
|
||||
|
||||
const XmlNode& loc = node["location"];
|
||||
String severity = node.Attr("severity");
|
||||
Ide::ListLineInfo e;
|
||||
e.file = loc.Attr("file");
|
||||
e.lineno = StrInt(loc.Attr("line"));
|
||||
e.linepos = StrInt(loc.Attr("column"));
|
||||
e.kind = severity == "error" ? 0 : 1;
|
||||
|
||||
Image img = decode(
|
||||
severity,
|
||||
"warning", LinterImg::warning(),
|
||||
"style", LinterImg::style(),
|
||||
"performance", LinterImg::performance(),
|
||||
"portability", LinterImg::portability(),
|
||||
"information", LinterImg::information(),
|
||||
"unusedFunction", LinterImg::unusedfunction(),
|
||||
"missingInclude", LinterImg::missinginclude(),
|
||||
LinterImg::error()
|
||||
);
|
||||
|
||||
Color paper = HighlightSetup::GetHlStyle(e.kind == 0 ? HighlightSetup::PAPER_ERROR
|
||||
: HighlightSetup::PAPER_WARNING).color;
|
||||
|
||||
e.message = node.Attr("msg");
|
||||
int linecy;
|
||||
AttrText txt(TheIde()->FormatErrorLine(e.message, linecy));
|
||||
txt.NormalPaper(paper);
|
||||
txt.SetImage(img);
|
||||
|
||||
ArrayCtrl& error = TheIde()->error;
|
||||
error.Add(e.file, e.lineno, txt, RawToValue(e));
|
||||
|
||||
ValueArray notes;
|
||||
if(sVerboseMode) {
|
||||
e.message = node.Attr("verbose");
|
||||
if(e.message.GetCount())
|
||||
notes.Add(RawToValue(e));
|
||||
}
|
||||
if(node.Attr("inconclusive") == "true") {
|
||||
e.message = "[Note that this is an inconclusive result!]";
|
||||
notes.Add(RawToValue(e));
|
||||
}
|
||||
|
||||
error.Set(error.GetCount() - 1, "NOTES", notes);
|
||||
error.SetLineCy(error.GetCount() - 1, linecy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INITIALIZER(CppCheck)
|
||||
{
|
||||
RegisterLinterModule(Single<CppCheck>("CppCheck"));
|
||||
}
|
||||
45
uppsrc/ide/Linter/CppCheck.h
Normal file
45
uppsrc/ide/Linter/CppCheck.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _ide_Linter_CppCheck_h_
|
||||
#define _ide_Linter_CppCheck_h_
|
||||
|
||||
#include "Linter.h"
|
||||
|
||||
#define LAYOUTFILE <ide/Linter/CppCheckConfig.lay>
|
||||
#include <CtrlCore/lay.h>
|
||||
|
||||
class CppCheck final : public Linter {
|
||||
public:
|
||||
CppCheck(const String& name) : Linter(name) {}
|
||||
|
||||
String GetConfigFilePath() const final;
|
||||
Value LoadConfig() final;
|
||||
void SaveConfig(const Value& cfg) final;
|
||||
|
||||
bool Exists() const final;
|
||||
void Settings() final;
|
||||
|
||||
protected:
|
||||
String MakeCmdLine(Scope sc, Vector<String>& paths) final;
|
||||
void OnResults(const String& results) final;
|
||||
|
||||
private:
|
||||
void DecodeXML(const XmlNode& results);
|
||||
};
|
||||
|
||||
INITIALIZE(CppCheck);
|
||||
|
||||
struct CppCheckConfigDlg final : Linter::Config, WithCppCheckConfigLayout<TopWindow> {
|
||||
CppCheckConfigDlg(Linter& l);
|
||||
|
||||
void Load() final;
|
||||
void Save() final;
|
||||
void Reset() final;
|
||||
|
||||
struct Pane : WithCppCheckConfigPaneLayout<ParentCtrl> {
|
||||
Pane();
|
||||
|
||||
void SetData(const Value& data) final;
|
||||
Value GetData() const final;
|
||||
void Load(const String& path, const String& ext);
|
||||
} libs, addons;
|
||||
};
|
||||
#endif
|
||||
20
uppsrc/ide/Linter/CppCheck.lay
Normal file
20
uppsrc/ide/Linter/CppCheck.lay
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
LAYOUT(CppCheckSetupLayout, 436, 384)
|
||||
ITEM(Upp::DropList, language, HCenterPosZ(64, 32).TopPosZ(20, 19))
|
||||
ITEM(Upp::DropList, standard, HCenterPosZ(64, 32).TopPosZ(44, 19))
|
||||
ITEM(Upp::DropList, platform, HCenterPosZ(64, 32).TopPosZ(68, 19))
|
||||
ITEM(Upp::DropList, depth, HCenterPosZ(64, 32).TopPosZ(92, 19))
|
||||
ITEM(Upp::EditInt, jobs, Min(1).Max(6).HCenterPosZ(64, 32).TopPosZ(120, 19))
|
||||
ITEM(Upp::Option, style, SetLabel(t_("Style")).HCenterPosZ(160, 0).TopPosZ(188, 16))
|
||||
ITEM(Upp::Option, performance, SetLabel(t_("Performance")).HCenterPosZ(160, 0).TopPosZ(208, 16))
|
||||
ITEM(Upp::Option, portability, SetLabel(t_("Portability")).HCenterPosZ(160, 0).TopPosZ(228, 16))
|
||||
ITEM(Upp::Option, information, SetLabel(t_("Information")).HCenterPosZ(160, 0).TopPosZ(248, 16))
|
||||
ITEM(Upp::Option, unusedfunction, SetLabel(t_("Unused functions")).HCenterPosZ(160, 0).TopPosZ(268, 16))
|
||||
ITEM(Upp::Option, missinginclude, SetLabel(t_("Missing Includes")).HCenterPosZ(160, 0).TopPosZ(288, 16))
|
||||
ITEM(Upp::LabelBox, dv___11, SetLabel(t_("Additional Checks")).SetFont(Serif()).HCenterPosZ(188, 0).TopPosZ(160, 160))
|
||||
ITEM(Upp::Label, dv___12, SetLabel(t_("Threads")).HCenterPosZ(56, -36).TopPosZ(120, 19))
|
||||
ITEM(Upp::Label, dv___13, SetLabel(t_("Language")).HCenterPosZ(56, -36).TopPosZ(20, 19))
|
||||
ITEM(Upp::Label, dv___14, SetLabel(t_("Standard")).HCenterPosZ(56, -36).TopPosZ(44, 19))
|
||||
ITEM(Upp::Label, dv___15, SetLabel(t_("Depth")).HCenterPosZ(56, -36).TopPosZ(92, 19))
|
||||
ITEM(Upp::Label, dv___16, SetLabel(t_("Platform")).HCenterPosZ(56, -36).TopPosZ(68, 19))
|
||||
END_LAYOUT
|
||||
|
||||
205
uppsrc/ide/Linter/CppCheckConfig.cpp
Normal file
205
uppsrc/ide/Linter/CppCheckConfig.cpp
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
#include "CppCheck.h"
|
||||
|
||||
CppCheckConfigDlg::CppCheckConfigDlg(Linter& l)
|
||||
: Linter::Config(l)
|
||||
{
|
||||
CtrlLayoutOKCancel(*this, "CppCheck Settings");
|
||||
|
||||
for(const Value& v : { "c", "c++"})
|
||||
language.Add(v);
|
||||
|
||||
for(const Value& v : { "c89", "c99", "c11", "c++03", "c++11", "c++14", "c++17", "c++20"})
|
||||
standard.Add(v);
|
||||
|
||||
for(const Value& v : { "native", "unix32", "unix64", "win32A", "win32W", "win64"})
|
||||
platform.Add(v);
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
depth.Add(i);
|
||||
|
||||
CtrlLayout(libs);
|
||||
CtrlLayout(addons);
|
||||
|
||||
libs.dirpath.WhenAction = [this] { libs.Load(SelectDirectory(), "*.cfg"); };
|
||||
addons.dirpath.WhenAction = [this] { addons.Load(SelectDirectory(), "*.py"); };
|
||||
|
||||
tabs.Add(libs.SizePos(), "Libraries");
|
||||
tabs.Add(addons.SizePos(), "Addons");
|
||||
|
||||
defaults.WhenAction = [this] { Reset(); };
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void CppCheckConfigDlg::Reset()
|
||||
{
|
||||
language.SetIndex(1);
|
||||
standard.SetIndex(5);
|
||||
platform.SetIndex(0);
|
||||
depth.SetIndex(1);
|
||||
jobs.MinMax(1, CPU_Cores()) <<= CPU_Cores();
|
||||
warning = false;
|
||||
style = false;
|
||||
performance = false;
|
||||
portability = false;
|
||||
information = false;
|
||||
unusedfunction = false;
|
||||
missinginclude = false;
|
||||
verbose = false;
|
||||
options <<= "-isrc.tpp -isrcdoc.tpp";
|
||||
|
||||
#ifdef flagWIN32
|
||||
constexpr const char *deflibrarypath = "C:\\Program Files\\CppCheck\\cfg";
|
||||
constexpr const char *defpluginspath = "C:\\Program Files\\CppCheck\\addons";
|
||||
#else
|
||||
constexpr const char *deflibrarypath = "/usr/share/cppcheck/cfg";
|
||||
constexpr const char *defpluginspath = "/usr/share/cppcheck/addons";
|
||||
#endif
|
||||
|
||||
libs.Load(deflibrarypath, "*.cfg");
|
||||
addons.Load(defpluginspath, "*.py");
|
||||
|
||||
Title("CppCheck Configuration [" + IdeGetCurrentMainPackage() + "]");
|
||||
}
|
||||
|
||||
void CppCheckConfigDlg::Load()
|
||||
{
|
||||
Reset();
|
||||
|
||||
try
|
||||
{
|
||||
Value v = linter.LoadConfig()["CppCheck"];
|
||||
if(IsNull(v))
|
||||
return;
|
||||
|
||||
auto LoadList = [this, &v](DropList& lst, const String& id, const Value& def)
|
||||
{
|
||||
int i = lst.FindValue(v[id]);
|
||||
lst.SetIndex(i >= 0 ? i : lst.FindValue(def));
|
||||
};
|
||||
|
||||
LoadList(language, "language", "c++");
|
||||
LoadList(standard, "standard", "c++14");
|
||||
LoadList(platform, "platform", "native");
|
||||
LoadList(depth, "depth", 2);
|
||||
|
||||
jobs <<= clamp((int) v["jobs"], 1, INT_MAX);
|
||||
|
||||
options <<= v["cmdline_options"];
|
||||
|
||||
for(const Value& q : v["severity"]) {
|
||||
if(q == "warning")
|
||||
warning = true;
|
||||
else
|
||||
if(q == "style")
|
||||
style = true;
|
||||
else
|
||||
if(q == "performance")
|
||||
performance = true;
|
||||
else
|
||||
if(q == "portability")
|
||||
portability = true;
|
||||
else
|
||||
if(q == "information")
|
||||
information = true;
|
||||
else
|
||||
if(q == "unusedFunction")
|
||||
unusedfunction = true;
|
||||
else
|
||||
if(q == "missingInclude") // FIXED TYPO: Was "missingInglude"
|
||||
missinginclude = true;
|
||||
}
|
||||
|
||||
libs <<= v["libraries"];
|
||||
addons <<= v["addons"];
|
||||
|
||||
verbose <<= v["verbose_mode"];
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CppCheckConfigDlg::Save()
|
||||
{
|
||||
JsonArray jl, jq;
|
||||
for(const String& s : ~libs) jl << s;
|
||||
for(const String& s : ~addons) jq << s;
|
||||
|
||||
JsonArray ja;
|
||||
|
||||
if(~warning) ja << "warning";
|
||||
if(~style) ja << "style";
|
||||
if(~performance) ja << "performance";
|
||||
if(~portability) ja << "portability";
|
||||
if(~information) ja << "information";
|
||||
if(~unusedfunction) ja << "unusedFunction";
|
||||
if(~missinginclude) ja << "missingInclude";
|
||||
|
||||
Json j;
|
||||
|
||||
j("language", language.GetValue());
|
||||
j("standard", standard.GetValue());
|
||||
j("platform", platform.GetValue());
|
||||
j("depth", depth.GetValue());
|
||||
j("jobs", ~jobs);
|
||||
j("severity", ja);
|
||||
j("libraries", jl);
|
||||
j("addons", jq);
|
||||
j("cmdline_options", ~options);
|
||||
j("verbose_mode", ~verbose);
|
||||
|
||||
linter.SaveConfig(Json("CppCheck", j).ToString());
|
||||
}
|
||||
|
||||
CppCheckConfigDlg::Pane::Pane()
|
||||
{
|
||||
struct NameDisplay : Display
|
||||
{
|
||||
void Paint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style) const override
|
||||
{
|
||||
StdDisplay().Paint(w, r, GetFileTitle(q.To<String>()), ink, paper, style);
|
||||
};
|
||||
};
|
||||
|
||||
list.AddColumn("Enable").Ctrls<Option>();
|
||||
list.AddColumn("Name").SetDisplay(Single<NameDisplay>());;
|
||||
list.ColumnWidths("20 300");
|
||||
dirpath.NullText("Select a valid library path");
|
||||
}
|
||||
|
||||
void CppCheckConfigDlg::Pane::SetData(const Value& data)
|
||||
{
|
||||
if(IsValueArray(data)) {
|
||||
for(const Value& q : data) {
|
||||
int i = list.Find(q, 1);
|
||||
if(i >= 0)
|
||||
list.Set(i, 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Value CppCheckConfigDlg::Pane::GetData() const
|
||||
{
|
||||
ValueArray va;
|
||||
for(int i = 0; i < list.GetCount(); i++)
|
||||
if(list.Get(i, 0) == true)
|
||||
va << list.Get(i, 1);
|
||||
return va;
|
||||
}
|
||||
|
||||
void CppCheckConfigDlg::Pane::Load(const String& path, const String& ext)
|
||||
{
|
||||
if(path.IsEmpty())
|
||||
return;
|
||||
if(!DirectoryExists(path)) {
|
||||
dirpath <<= Null;
|
||||
return;
|
||||
}
|
||||
list.Clear();
|
||||
for(const FindFile& f : FindFile(AppendFileName(path, ext)))
|
||||
list.Add(false, f.GetPath());
|
||||
dirpath <<= path;
|
||||
list.Enable(list.GetCount());
|
||||
}
|
||||
34
uppsrc/ide/Linter/CppCheckConfig.lay
Normal file
34
uppsrc/ide/Linter/CppCheckConfig.lay
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
LAYOUT(CppCheckConfigLayout, 620, 408)
|
||||
ITEM(Upp::DropList, language, LeftPosZ(79, 64).TopPosZ(12, 19))
|
||||
ITEM(Upp::DropList, standard, LeftPosZ(79, 64).TopPosZ(36, 19))
|
||||
ITEM(Upp::DropList, platform, LeftPosZ(79, 64).TopPosZ(60, 19))
|
||||
ITEM(Upp::DropList, depth, LeftPosZ(79, 64).TopPosZ(84, 19))
|
||||
ITEM(Upp::EditInt, jobs, Min(1).Max(6).LeftPosZ(79, 64).TopPosZ(108, 19))
|
||||
ITEM(Upp::Option, warning, SetLabel(t_("Warnings")).LeftPosZ(16, 124).TopPosZ(176, 16))
|
||||
ITEM(Upp::Option, style, SetLabel(t_("Style")).LeftPosZ(16, 124).TopPosZ(196, 16))
|
||||
ITEM(Upp::Option, performance, SetLabel(t_("Performance")).LeftPosZ(16, 124).TopPosZ(216, 16))
|
||||
ITEM(Upp::Option, portability, SetLabel(t_("Portability")).LeftPosZ(16, 124).TopPosZ(236, 16))
|
||||
ITEM(Upp::Option, information, SetLabel(t_("Information")).LeftPosZ(16, 124).TopPosZ(256, 16))
|
||||
ITEM(Upp::Option, unusedfunction, SetLabel(t_("Unused functions")).LeftPosZ(16, 124).TopPosZ(276, 16))
|
||||
ITEM(Upp::Option, missinginclude, SetLabel(t_("Missing Includes")).LeftPosZ(16, 124).TopPosZ(296, 16))
|
||||
ITEM(Upp::TabCtrl, tabs, HSizePosZ(164, 8).VSizePosZ(12, 84))
|
||||
ITEM(Upp::EditString, options, HSizePosZ(116, 8).BottomPosZ(53, 19))
|
||||
ITEM(Upp::Button, defaults, SetLabel(t_("Restore defaults")).LeftPosZ(8, 116).BottomPosZ(8, 24))
|
||||
ITEM(Upp::Option, verbose, SetLabel(t_("Be verbose")).LeftPosZ(144, 124).BottomPosZ(12, 16))
|
||||
ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).RightPosZ(128, 116).BottomPosZ(8, 24))
|
||||
ITEM(Upp::Button, ok, SetLabel(t_("OK")).RightPosZ(8, 116).BottomPosZ(8, 24))
|
||||
ITEM(Upp::Label, dv___18, SetLabel(t_("Threads")).LeftPosZ(16, 56).TopPosZ(108, 19))
|
||||
ITEM(Upp::Label, dv___19, SetLabel(t_("Language")).LeftPosZ(16, 56).TopPosZ(12, 19))
|
||||
ITEM(Upp::Label, dv___20, SetLabel(t_("Standard")).LeftPosZ(16, 56).TopPosZ(36, 19))
|
||||
ITEM(Upp::Label, dv___21, SetLabel(t_("Max depth")).LeftPosZ(16, 56).TopPosZ(84, 19))
|
||||
ITEM(Upp::Label, dv___22, SetLabel(t_("Platform")).LeftPosZ(16, 56).TopPosZ(60, 19))
|
||||
ITEM(Upp::Label, dv___23, SetLabel(t_("Additional checks")).LeftPosZ(16, 124).TopPosZ(148, 16))
|
||||
ITEM(Upp::Label, dv___24, SetLabel(t_("Additional options")).LeftPosZ(16, 96).BottomPosZ(53, 19))
|
||||
END_LAYOUT
|
||||
|
||||
LAYOUT(CppCheckConfigPaneLayout, 408, 264)
|
||||
ITEM(Upp::ArrayCtrl, list, AutoHideSb(true).Header(false).AskRemove(false).VertGrid(false).HorzGrid(false).NoCursor(true).HSizePosZ(4, 0).VSizePosZ(28, 0))
|
||||
ITEM(Upp::Label, dv___1, SetLabel(t_("Path")).LeftPosZ(4, 36).TopPosZ(4, 19))
|
||||
ITEM(Upp::DataPusher, dirpath, HSizePosZ(44, 0).TopPosZ(4, 19))
|
||||
END_LAYOUT
|
||||
|
||||
248
uppsrc/ide/Linter/Linter.cpp
Normal file
248
uppsrc/ide/Linter/Linter.cpp
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
#include "Linter.h"
|
||||
|
||||
#define IMAGECLASS LinterImg
|
||||
#define IMAGEFILE <ide/Linter/Linter.iml>
|
||||
#include <Draw/iml_source.h>
|
||||
|
||||
#define KEYGROUPNAME "Linter"
|
||||
#define KEYNAMESPACE LinterKeys
|
||||
#define KEYFILE <ide/Linter/Linter.key>
|
||||
#include <CtrlLib/key_source.h>
|
||||
|
||||
using namespace LinterKeys;
|
||||
|
||||
static String sActiveModuleName;
|
||||
|
||||
static Vector<Linter*>& sLM()
|
||||
{
|
||||
static Vector<Linter*> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
void RegisterLinterModule(Linter& linter_module)
|
||||
{
|
||||
sLM().Add(&linter_module);
|
||||
}
|
||||
|
||||
int GetLinterModuleCount()
|
||||
{
|
||||
return sLM().GetCount();
|
||||
}
|
||||
|
||||
Linter& GetLinterModule(int i)
|
||||
{
|
||||
ASSERT(i >= 0 && i < GetLinterModuleCount());
|
||||
return *sLM()[i];
|
||||
}
|
||||
|
||||
Linter* GetActiveLinterModulePtr()
|
||||
{
|
||||
for(Linter *p : sLM())
|
||||
if(p->Exists() && p->GetName() == sActiveModuleName)
|
||||
return p;
|
||||
|
||||
for(Linter *p : sLM())
|
||||
if(p->Exists()) {
|
||||
sActiveModuleName = p->GetName();
|
||||
return p;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Linter::CanCheck() const
|
||||
{
|
||||
return !running
|
||||
&& TheIde()
|
||||
&& TheIde()->idestate == Ide::EDITING
|
||||
&& !IdeIsDebugLock();
|
||||
}
|
||||
|
||||
String Linter::GetFileName() const
|
||||
{
|
||||
return Nvl(TheIde()->GetActiveFileName(), Upp::GetFileName(TheIde()->editfile));
|
||||
}
|
||||
|
||||
String Linter::GetFilePath() const
|
||||
{
|
||||
return Nvl(TheIde()->GetActiveFilePath(), TheIde()->editfile);
|
||||
}
|
||||
|
||||
String Linter::GetPackageName() const
|
||||
{
|
||||
return TheIde()->GetActivePackage();
|
||||
}
|
||||
|
||||
String Linter::GetPackagePath() const
|
||||
{
|
||||
return TheIde()->GetActivePackageDir();
|
||||
}
|
||||
|
||||
void Linter::CheckFile()
|
||||
{
|
||||
if(!Exists())
|
||||
return;
|
||||
Vector<String> paths = { GetFilePath() };
|
||||
DoCheck(Scope::File, paths);
|
||||
}
|
||||
|
||||
void Linter::CheckPackage()
|
||||
{
|
||||
if(!Exists())
|
||||
return;
|
||||
Vector<String> paths = { GetPackagePath() };
|
||||
DoCheck(Scope::Package, paths);
|
||||
}
|
||||
|
||||
void Linter::CheckProject()
|
||||
{
|
||||
if(!Exists())
|
||||
return;
|
||||
Vector<String> paths;
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
for(int i = 0; i < wspc.GetCount(); i++)
|
||||
paths.Add() = PackageDirectory(wspc[i]);
|
||||
DoCheck(Scope::Project, paths);
|
||||
}
|
||||
|
||||
void Linter::SysCmd(const String& cmd, const String& text, Stream& fs)
|
||||
{
|
||||
MakeBuild *mb = dynamic_cast<MakeBuild *>(TheIdeContext());
|
||||
if(!mb)
|
||||
throw Exc("Cannot get TheIDE context");
|
||||
Host host;
|
||||
mb->CreateHost(host, false, false);
|
||||
LocalProcess p;
|
||||
if(!host.StartProcess(p, ~cmd))
|
||||
throw Exc("Cannot start linter process");
|
||||
Progress pi;
|
||||
pi.Title("Linter");
|
||||
pi.SetText(text);
|
||||
for(;;) {
|
||||
String out = p.Get();
|
||||
if(p.IsRunning()) {
|
||||
if(!IsNull(out))
|
||||
fs.Put(out);
|
||||
}
|
||||
else {
|
||||
if(out.IsVoid()) {
|
||||
p.Kill();
|
||||
break;
|
||||
}
|
||||
else
|
||||
fs.Put(out);
|
||||
}
|
||||
if(pi.StepCanceled()) {
|
||||
pi.Close();
|
||||
p.Kill();
|
||||
throw Exc("User break.");
|
||||
}
|
||||
IdeProcessEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void Linter::DoCheck(Scope sc, Vector<String>& paths)
|
||||
{
|
||||
if(running)
|
||||
return;
|
||||
running = true;
|
||||
|
||||
Ide *ide = TheIde();
|
||||
String tmp = GetTempFileName();
|
||||
|
||||
try {
|
||||
FileOut fo(tmp);
|
||||
if(!fo)
|
||||
throw Exc("Unable to open temporary file");
|
||||
ide->ConsoleClear();
|
||||
ide->ShowConsole();
|
||||
ide->PutConsole("Running linter..");
|
||||
String text = "Analyzing " + (paths.GetCount() == 1 ? Upp::GetFileName(paths[0]) : "all packages");
|
||||
SysCmd(MakeCmdLine(sc, paths), text, fo);
|
||||
fo.Close();
|
||||
ide->Sync();
|
||||
ide->PutConsole("Parsing linter output..");
|
||||
String rawresults = LoadFile(tmp);
|
||||
DeleteFile(tmp);
|
||||
ide->ClearErrorsPane();
|
||||
OnResults(rawresults);
|
||||
ide->PutConsole("done");
|
||||
if(ide->error.GetCount()) {
|
||||
ide->BeepMuteExclamation();
|
||||
ide->SetBottom(Ide::BERRORS);
|
||||
}
|
||||
else
|
||||
ide->BeepMuteInformation();
|
||||
}
|
||||
catch(const Exc& e) {
|
||||
ide->PutConsole(e);
|
||||
ide->BeepMuteExclamation();
|
||||
if(FileExists(tmp))
|
||||
DeleteFile(tmp);
|
||||
}
|
||||
|
||||
running = false;
|
||||
}
|
||||
|
||||
void sListMenu(Linter& l, Bar& menu)
|
||||
{
|
||||
auto list = [&l](Bar& menu) {
|
||||
Vector<int> ndx = FindAll(sLM(), [](const Linter *p) { return p->Exists(); });
|
||||
for(int i : ndx) {
|
||||
const Linter& q = GetLinterModule(i);
|
||||
menu.Add(q.GetName(), [&q]() { sActiveModuleName = q.GetName(); })
|
||||
.Radio(q.GetName() == l.GetName());
|
||||
}
|
||||
menu.Separator();
|
||||
menu.Add("Configure " + l.GetName(), [&l]() { l.Settings(); })
|
||||
.Key(AK_CONFIGURE);
|
||||
};
|
||||
|
||||
menu.Sub("Static analyzers", list);
|
||||
}
|
||||
|
||||
void sFileMenu(Linter& l, String name, Bar& menu)
|
||||
{
|
||||
menu.Add(l.CanCheck(), "Analyze " + name, [&l]() { l.CheckFile(); })
|
||||
.Key(AK_CHECKFILE);
|
||||
}
|
||||
|
||||
void sPackageMenu(Linter& l, String name, Bar& menu)
|
||||
{
|
||||
menu.Add(l.CanCheck(), "Analyze package " + name, [&l]() { l.CheckPackage(); })
|
||||
.Key(AK_CHECKPACKAGE);
|
||||
}
|
||||
|
||||
void Linter::StdMenu(Bar& menu)
|
||||
{
|
||||
Linter *p = GetActiveLinterModulePtr();
|
||||
if(!p)
|
||||
return;
|
||||
sListMenu(*p, menu);
|
||||
sFileMenu(*p, p->GetFileName(), menu);
|
||||
sPackageMenu(*p, p->GetPackageName(), menu);
|
||||
menu.Add(p->CanCheck(), "Analyze all..", [p]() { p->CheckProject(); })
|
||||
.Key(AK_CHECKALL);
|
||||
menu.Separator();
|
||||
}
|
||||
|
||||
void Linter::FileMenu(Bar& menu)
|
||||
{
|
||||
Linter *p = GetActiveLinterModulePtr();
|
||||
if(p) sFileMenu(*p, p->GetFileName(), menu);
|
||||
}
|
||||
|
||||
void Linter::PackageMenu(Bar& menu)
|
||||
{
|
||||
Linter *p = GetActiveLinterModulePtr();
|
||||
if(p) sPackageMenu(*p, p->GetPackageName(), menu);
|
||||
}
|
||||
|
||||
INITIALIZER(Linter)
|
||||
{
|
||||
RegisterGlobalSerialize("Linters", [](Stream& s) {
|
||||
int version = 0;
|
||||
s / version;
|
||||
s % sActiveModuleName;
|
||||
});
|
||||
}
|
||||
82
uppsrc/ide/Linter/Linter.h
Normal file
82
uppsrc/ide/Linter/Linter.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#ifndef TheIde_Linter_h
|
||||
#define TheIde_Linter_h
|
||||
|
||||
#include <Core/Core.h>
|
||||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
#include <ide/Common/Common.h>
|
||||
#include <ide/Core/Core.h>
|
||||
#include <ide/ide.h>
|
||||
|
||||
#define IMAGECLASS LinterImg
|
||||
#define IMAGEFILE <ide/Linter/Linter.iml>
|
||||
#include <Draw/iml_header.h>
|
||||
|
||||
// Base class for command-line driven linter modules (static analyzers)
|
||||
class Linter {
|
||||
public:
|
||||
Linter(const String& name) : module_name(name) {}
|
||||
virtual ~Linter() {}
|
||||
|
||||
virtual String GetConfigFilePath() const = 0;
|
||||
virtual Value LoadConfig() = 0;
|
||||
virtual void SaveConfig(const Value& cfg) = 0;
|
||||
virtual bool Exists() const = 0;
|
||||
virtual void Settings() = 0;
|
||||
|
||||
String GetName() const { return module_name; }
|
||||
|
||||
bool CanCheck() const;
|
||||
void CheckFile();
|
||||
void CheckPackage();
|
||||
void CheckProject();
|
||||
|
||||
static void StdMenu(Bar& menu);
|
||||
static void FileMenu(Bar& menu);
|
||||
static void PackageMenu(Bar& menu);
|
||||
|
||||
class Config {
|
||||
public:
|
||||
Config(Linter& l) : linter(l) {}
|
||||
virtual void Load() = 0;
|
||||
virtual void Save() = 0;
|
||||
virtual void Reset() = 0;
|
||||
protected:
|
||||
Linter& linter;
|
||||
};
|
||||
|
||||
protected:
|
||||
enum class Scope { File, Package, Project };
|
||||
|
||||
virtual String MakeCmdLine(Scope sc, Vector<String>& paths) = 0;
|
||||
virtual void OnResults(const String& results) = 0;
|
||||
|
||||
String GetFileName() const;
|
||||
String GetFilePath() const;
|
||||
String GetPackageName() const;
|
||||
String GetPackagePath() const;
|
||||
|
||||
private:
|
||||
void SysCmd(const String& cmd, const String& text, Stream& fs);
|
||||
void DoCheck(Scope sc, Vector<String>& paths);
|
||||
String module_name;
|
||||
bool running = false;
|
||||
};
|
||||
|
||||
INITIALIZE(Linter)
|
||||
|
||||
void RegisterLinterModule(Linter& linter_module);
|
||||
int GetLinterModuleCount();
|
||||
Linter& GetLinterModule(int i);
|
||||
Linter* GetActiveLinterModulePtr();
|
||||
|
||||
// Available static analyzer modules.
|
||||
#include "CppCheck.h"
|
||||
#include "ClangTidy.h"
|
||||
|
||||
#define KEYGROUPNAME "Linter"
|
||||
#define KEYNAMESPACE LinterKeys
|
||||
#define KEYFILE <ide/Linter/Linter.key>
|
||||
#include <CtrlLib/key_header.h>
|
||||
|
||||
#endif
|
||||
124
uppsrc/ide/Linter/Linter.iml
Normal file
124
uppsrc/ide/Linter/Linter.iml
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
PREMULTIPLIED
|
||||
IMAGE_ID(warning)
|
||||
IMAGE_ID(style)
|
||||
IMAGE_ID(performance)
|
||||
IMAGE_ID(portability)
|
||||
IMAGE_ID(unusedfunction)
|
||||
IMAGE_ID(missinginclude)
|
||||
IMAGE_ID(information)
|
||||
IMAGE_ID(error)
|
||||
|
||||
IMAGE_BEGIN_DATA
|
||||
IMAGE_DATA(120,156,229,151,7,84,148,87,218,199,41,9,74,130,88,18,140,70,143,13,93,133,181,36,198,196,253,146,88,130,38,26)
|
||||
IMAGE_DATA(137,6,197,8,34,136,130,10,40,77,5,69,116,16,41,26,176,81,68,81,17,1,165,27,16,1,5,81,16,134,94,164)
|
||||
IMAGE_DATA(13,117,128,1,198,97,20,1,5,134,34,200,252,247,222,87,103,86,93,53,100,179,238,249,190,111,159,115,158,195,204,189)
|
||||
IMAGE_DATA(239,239,62,245,62,239,192,30,33,51,66,230,93,139,172,172,140,60,219,239,115,78,236,137,191,178,233,231,63,202,187,89)
|
||||
IMAGE_DATA(170,250,180,115,92,241,184,216,9,6,63,170,152,253,17,118,184,146,252,168,218,232,249,29,3,125,237,232,123,84,6,206)
|
||||
IMAGE_DATA(229,207,90,135,127,40,55,106,176,252,101,39,181,184,142,202,83,16,63,237,132,184,79,136,199,165,39,225,186,117,220,233)
|
||||
IMAGE_DATA(193,176,234,147,21,63,107,138,255,106,0,3,79,240,228,193,41,244,61,244,39,103,180,160,46,116,214,83,181,9,67,62)
|
||||
IMAGE_DATA(251,61,62,213,119,22,71,196,11,39,120,43,202,47,45,100,244,105,23,7,237,21,65,8,63,48,137,253,54,86,107,225)
|
||||
IMAGE_DATA(40,189,214,236,157,128,248,9,68,53,27,81,22,180,144,81,81,149,62,196,253,173,16,36,153,66,243,75,37,189,215,177)
|
||||
IMAGE_DATA(138,67,100,149,56,193,159,183,244,52,103,99,160,175,9,162,106,3,148,5,46,96,180,163,66,7,79,59,179,32,226,223)
|
||||
IMAGE_DATA(65,218,145,137,247,20,21,100,148,94,229,207,238,153,26,241,184,228,24,177,211,140,222,166,83,132,215,71,109,204,178,231)
|
||||
IMAGE_DATA(252,58,116,113,245,49,208,91,7,225,29,22,172,53,149,143,188,200,78,28,163,48,181,33,106,110,191,184,191,19,253,29)
|
||||
IMAGE_DATA(108,116,215,232,51,124,55,111,11,30,230,233,160,163,252,23,116,85,173,69,175,240,20,250,69,124,228,57,169,60,25,55)
|
||||
IMAGE_DATA(82,118,170,132,143,119,159,145,219,94,113,129,228,76,136,94,193,81,116,115,245,8,191,225,31,254,151,175,69,87,229,26)
|
||||
IMAGE_DATA(136,202,181,240,180,187,18,130,148,95,113,98,237,208,56,202,106,204,85,214,188,159,98,68,106,45,34,189,18,143,174,106)
|
||||
IMAGE_DATA(93,70,59,43,137,221,10,93,194,234,146,252,233,16,126,53,68,21,171,208,93,109,196,196,88,226,189,20,127,155,32,163)
|
||||
IMAGE_DATA(153,123,78,157,223,197,79,102,120,113,255,35,162,109,207,244,233,163,103,42,93,107,125,174,45,100,189,3,15,239,70,34)
|
||||
IMAGE_DATA(72,87,182,242,164,249,248,160,250,208,89,224,93,254,43,106,3,213,80,227,63,29,213,231,167,161,202,87,21,229,222,147)
|
||||
IMAGE_DATA(80,122,108,28,10,93,71,35,223,97,36,114,246,14,67,230,78,69,176,205,21,144,106,42,15,187,69,50,65,191,215,79)
|
||||
IMAGE_DATA(191,39,169,255,137,97,240,170,200,203,202,40,230,248,45,105,206,62,182,98,32,219,99,21,174,187,78,229,141,248,80,102)
|
||||
IMAGE_DATA(236,96,249,170,48,45,84,6,111,71,79,67,14,122,249,121,200,245,209,128,179,238,164,168,193,176,247,110,206,129,136,19)
|
||||
IMAGE_DATA(138,222,134,12,60,225,231,51,218,195,189,141,44,183,31,7,6,195,246,182,178,209,219,24,134,218,40,115,136,10,131,25)
|
||||
IMAGE_DATA(165,124,138,155,102,207,96,216,167,162,88,210,204,166,232,44,180,66,209,133,245,168,141,220,141,28,207,159,49,104,182,102)
|
||||
IMAGE_DATA(19,105,228,165,232,107,59,129,166,56,3,84,157,252,230,157,177,41,30,211,255,101,54,209,237,47,232,104,74,254,195,236)
|
||||
IMAGE_DATA(71,74,239,77,162,108,67,222,85,100,135,155,252,97,187,222,22,19,208,209,144,141,62,97,49,226,89,243,192,62,251,57)
|
||||
IMAGE_DATA(106,210,45,80,232,183,2,89,206,243,222,202,74,248,39,164,167,90,34,54,227,190,239,98,164,153,168,32,98,211,104,196)
|
||||
IMAGE_DATA(237,153,249,187,44,149,245,26,163,192,241,51,64,87,97,8,90,10,195,145,122,116,249,160,89,42,186,139,63,194,70,13)
|
||||
IMAGE_DATA(21,248,153,77,99,56,7,131,25,191,13,150,253,179,114,103,48,195,64,83,83,211,216,199,199,39,197,219,219,59,229,135)
|
||||
IMAGE_DATA(31,126,48,30,204,193,19,38,76,80,27,58,116,168,178,172,172,172,220,245,235,215,155,5,2,1,238,221,187,7,63,63)
|
||||
IMAGE_DATA(191,102,186,166,160,160,160,60,102,204,24,181,215,177,7,15,30,60,159,159,159,63,112,227,198,13,225,136,17,35,198,70)
|
||||
IMAGE_DATA(69,69,9,235,234,234,80,91,91,11,127,127,127,161,178,178,242,216,115,231,206,9,131,130,130,6,140,141,141,207,191,200)
|
||||
IMAGE_DATA(110,218,180,105,127,77,77,13,90,91,91,193,229,114,65,108,139,110,223,190,45,46,47,47,7,135,195,65,116,116,180,56)
|
||||
IMAGE_DATA(48,48,80,148,151,151,7,161,80,8,98,3,139,22,45,218,47,225,13,13,13,89,108,54,91,76,207,160,207,87,85,85)
|
||||
IMAGE_DATA(49,231,72,120,250,189,164,164,4,148,207,206,206,134,173,173,173,120,222,188,121,172,23,125,48,49,49,113,165,207,146,24)
|
||||
IMAGE_DATA(144,147,147,131,155,55,111,210,184,65,236,34,45,45,13,153,153,153,72,77,77,101,108,47,91,182,204,85,194,5,4,4)
|
||||
IMAGE_DATA(20,68,70,70,242,99,99,99,219,42,43,43,81,80,80,128,91,183,110,97,235,214,173,153,227,199,143,95,74,114,186,212)
|
||||
IMAGE_DATA(202,202,42,147,248,199,156,67,247,73,174,218,236,236,236,248,196,102,1,89,27,120,240,224,1,227,43,181,123,247,238,93)
|
||||
IMAGE_DATA(4,7,7,99,210,164,73,75,37,54,166,77,155,182,244,202,149,43,72,79,79,103,252,162,190,208,188,110,223,190,125,128)
|
||||
IMAGE_DATA(228,105,160,177,177,145,137,143,174,211,243,99,98,98,48,117,234,84,41,79,63,135,133,133,49,246,169,255,119,238,220,97)
|
||||
IMAGE_DATA(158,39,121,31,112,118,118,46,56,112,224,0,159,244,74,91,97,97,33,115,6,205,129,189,189,125,38,181,75,89,234,63)
|
||||
IMAGE_DATA(141,157,198,149,152,152,8,61,61,189,54,210,95,124,82,131,2,137,13,178,230,154,145,145,193,228,136,254,205,202,202,66)
|
||||
IMAGE_DATA(68,68,4,66,67,67,153,181,228,228,100,196,199,199,51,107,95,124,241,133,171,204,11,162,165,165,197,34,49,139,203,202)
|
||||
IMAGE_DATA(202,24,150,214,169,184,184,152,201,7,61,135,250,67,215,73,172,204,30,137,91,60,103,206,28,105,253,136,47,251,169,111)
|
||||
IMAGE_DATA(180,223,66,66,66,168,239,34,23,23,23,49,205,23,141,217,204,204,76,188,109,219,54,17,221,163,113,59,58,58,210,252)
|
||||
IMAGE_DATA(236,127,209,135,85,171,86,157,183,180,180,28,208,209,209,17,146,59,48,214,198,198,70,72,109,81,251,116,237,253,247,223)
|
||||
IMAGE_DATA(31,187,114,229,74,225,138,21,43,6,212,213,213,95,234,95,137,144,30,87,147,147,147,83,38,31,229,246,236,217,211,76)
|
||||
IMAGE_DATA(253,189,118,237,26,72,124,205,116,141,238,41,42,42,190,246,254,188,42,211,167,79,55,214,208,208,72,249,246,219,111,83)
|
||||
IMAGE_DATA(72,31,189,241,254,254,211,48,160,77,40,105,124,154,68,218,80,185,185,185,76,32,36,161,98,82,96,38,49,180,9,146)
|
||||
IMAGE_DATA(146,146,232,101,195,213,171,87,97,109,109,29,74,121,90,132,71,143,218,193,107,224,131,87,223,8,30,175,17,220,26,30)
|
||||
IMAGE_DATA(57,171,132,185,96,124,126,19,106,234,26,80,67,214,232,58,151,91,135,150,150,54,166,105,41,79,19,76,185,149,187,66)
|
||||
IMAGE_DATA(25,181,118,143,193,173,59,25,98,30,143,135,230,230,102,228,228,22,34,35,51,15,236,244,92,164,178,179,73,115,100,161)
|
||||
IMAGE_DATA(178,170,134,14,9,20,21,21,61,41,45,45,165,127,153,162,211,203,74,47,78,74,74,10,211,248,180,129,168,175,180,137)
|
||||
IMAGE_DATA(168,61,111,239,83,240,244,244,66,121,5,23,190,190,190,160,44,227,59,239,153,223,117,188,6,212,82,95,107,235,165,190)
|
||||
IMAGE_DATA(86,17,125,216,210,202,216,75,78,201,64,210,109,54,202,202,171,201,57,158,76,174,40,183,110,255,85,162,49,208,57,16)
|
||||
IMAGE_DATA(3,93,214,53,232,58,196,98,253,193,56,232,57,198,51,49,85,84,214,48,246,142,31,63,14,119,119,119,112,202,170,112)
|
||||
IMAGE_DATA(244,232,81,38,207,212,38,229,76,79,164,99,187,71,38,118,120,101,195,226,84,46,172,78,231,195,218,247,46,195,151,151)
|
||||
IMAGE_DATA(115,25,123,137,73,169,72,72,188,67,252,174,0,105,88,166,201,105,110,117,89,177,216,225,153,5,11,239,28,88,250,228)
|
||||
IMAGE_DATA(193,250,76,1,118,158,45,196,238,243,197,12,47,177,119,57,59,0,235,194,181,80,76,120,7,7,7,166,166,180,46,212)
|
||||
IMAGE_DATA(87,202,89,61,231,118,17,206,198,175,4,182,254,28,134,47,229,60,179,167,17,248,13,230,159,154,143,162,226,114,144,129)
|
||||
IMAGE_DATA(196,228,152,230,136,198,73,125,245,140,170,132,103,116,213,115,173,198,222,128,114,134,151,216,139,141,75,66,76,108,18,10)
|
||||
IMAGE_DATA(139,56,216,189,123,55,226,226,226,200,96,170,151,214,254,77,202,41,171,102,236,197,92,187,137,232,152,68,220,45,228,192)
|
||||
IMAGE_DATA(194,194,2,228,165,129,198,198,123,40,43,171,64,73,105,25,10,238,22,51,125,146,70,250,36,59,167,128,228,151,12,103)
|
||||
IMAGE_DATA(162,229,229,149,196,158,13,162,8,27,21,125,131,60,87,10,83,83,83,232,235,235,31,39,151,59,159,12,180,252,125,251)
|
||||
IMAGE_DATA(246,21,121,120,120,136,105,157,201,139,7,78,78,78,98,26,243,225,35,71,224,122,248,8,46,6,4,49,28,85,129,224)
|
||||
IMAGE_DATA(62,182,108,217,242,210,219,127,245,234,213,190,94,94,94,226,212,180,116,198,63,22,139,37,38,3,68,76,106,46,38,195)
|
||||
IMAGE_DATA(129,222,23,236,216,177,3,100,136,131,188,208,64,158,175,144,176,31,124,240,129,10,97,73,93,203,152,187,64,123,143,71)
|
||||
IMAGE_DATA(250,130,12,82,177,185,185,57,29,72,116,40,228,190,229,254,203,147,120,242,105,142,73,28,144,216,91,187,118,237,219,152)
|
||||
IMAGE_DATA(193,253,50,248,47,151,225,127,134,85,219,232,158,169,121,58,255,177,100,65,203,191,232,177,250,102,247,204,65,156,59,106)
|
||||
IMAGE_DATA(198,6,247,204,93,215,31,226,107,219,223,234,36,139,139,28,163,235,246,36,181,128,238,209,103,94,7,190,167,60,86,247)
|
||||
IMAGE_DATA(23,191,138,158,157,241,205,248,218,134,178,114,227,164,155,178,114,227,190,182,143,170,163,123,63,159,41,235,145,87,26,163)
|
||||
IMAGE_DATA(251,10,174,176,194,43,175,125,95,66,11,86,95,172,235,151,145,31,242,197,63,25,32,107,116,207,246,218,3,124,239,154)
|
||||
IMAGE_DATA(213,78,153,151,182,201,153,63,249,148,246,108,143,184,143,121,102,225,47,219,39,159,191,178,10,175,163,123,63,158,44,233)
|
||||
IMAGE_DATA(145,83,252,228,85,251,210,248,167,104,186,100,110,189,36,192,60,227,80,105,252,95,90,134,215,153,134,9,65,247,222,20)
|
||||
IMAGE_DATA(255,11,50,124,226,247,135,50,23,217,177,165,249,215,112,202,124,252,156,253,51,117,253,127,41,255,7,134,1,200,196,117)
|
||||
IMAGE_DATA(196,155,191,255,111,229,233,115,18,117,196,155,191,191,73,28,49,56,125,87,254,255,89,254,191,61,254,127,23,255,159,147)
|
||||
IMAGE_DATA(119,58,12,134,140,24,171,58,249,123,99,214,2,251,56,238,130,67,41,157,11,28,111,119,206,183,137,228,142,91,100,192)
|
||||
IMAGE_DATA(122,79,121,180,234,219,88,149,153,223,105,47,62,148,208,180,61,160,8,1,41,245,136,202,224,51,122,241,22,15,70,103)
|
||||
IMAGE_DATA(178,49,219,50,164,105,216,212,191,105,191,142,253,120,230,98,109,13,215,76,209,177,107,85,72,40,104,194,133,155,245,112)
|
||||
IMAGE_DATA(141,172,128,83,120,57,60,99,171,16,153,214,128,195,81,28,204,54,10,22,13,155,248,229,75,103,40,12,255,100,202,130)
|
||||
IMAGE_DATA(253,137,2,202,198,230,54,129,69,152,125,193,197,8,75,111,68,24,187,1,123,130,138,176,247,114,49,130,110,215,194,245)
|
||||
IMAGE_DATA(74,17,102,234,158,22,200,43,142,154,34,225,39,44,217,236,96,234,87,128,184,60,33,236,131,57,228,167,113,17,108,252)
|
||||
IMAGE_DATA(11,209,213,219,207,232,78,255,60,236,188,144,135,189,129,5,8,190,195,195,6,247,68,168,168,253,228,32,225,231,219,71)
|
||||
IMAGE_DATA(113,47,222,170,135,119,44,23,182,1,228,39,186,63,249,169,238,151,135,75,41,181,8,34,186,227,108,198,51,245,77,39)
|
||||
IMAGE_DATA(49,21,227,204,205,74,168,255,120,152,43,225,191,114,76,238,190,154,115,15,246,151,138,136,157,124,152,159,203,34,207,102)
|
||||
IMAGE_DATA(128,138,152,168,217,105,54,76,79,165,18,77,131,133,47,27,145,25,60,204,214,58,218,45,225,231,216,38,116,71,103,241)
|
||||
IMAGE_DATA(153,56,169,157,237,103,210,9,147,14,78,125,27,68,61,253,216,230,145,130,173,39,147,177,133,168,153,87,50,34,50,9)
|
||||
IMAGE_DATA(191,210,77,202,171,155,7,114,253,110,113,225,246,91,25,204,125,179,96,230,195,134,137,119,42,74,121,173,132,239,131,241)
|
||||
IMAGE_DATA(209,36,24,147,152,141,220,19,96,119,33,3,222,9,37,80,95,98,47,245,127,244,252,117,14,27,61,83,16,150,86,15)
|
||||
IMAGE_DATA(243,211,25,48,243,76,67,66,94,3,158,14,136,25,255,139,106,154,177,209,53,142,104,44,206,198,115,200,191,99,81,24)
|
||||
IMAGE_DATA(173,170,33,205,159,252,7,31,77,153,185,241,180,224,80,68,33,130,110,85,99,155,103,50,140,142,221,132,161,219,13,108)
|
||||
IMAGE_DATA(116,137,133,129,115,12,244,157,175,226,120,68,1,169,107,38,102,254,176,95,32,175,160,44,173,31,21,165,113,115,181,103)
|
||||
IMAGE_DATA(174,244,21,177,66,243,112,49,169,18,123,253,216,196,223,235,216,116,56,14,187,78,39,227,76,108,49,246,94,202,192,236)
|
||||
IMAGE_DATA(101,246,162,97,42,51,94,219,131,74,159,204,209,158,189,220,189,73,199,241,26,188,111,148,33,132,205,37,90,13,143,184)
|
||||
IMAGE_DATA(18,172,177,143,196,236,37,118,77,111,98,165,177,12,25,161,170,50,117,41,139,230,103,214,242,131,157,179,150,177,58,213)
|
||||
IMAGE_DATA(151,216,112,85,84,23,178,136,207,111,189,63,255,138,188,211,97,48,121,228,48,213,125,139,230,178,202,44,117,184,205,246)
|
||||
IMAGE_DATA(134,157,247,237,12,58,11,205,214,112,109,190,158,197,154,56,252,195,183,6,163,165,54,89,155,103,163,223,212,230,108,9)
|
||||
IMAGE_DATA(81,136,23,122,227,2,24,237,12,241,196,3,150,41,56,219,126,110,90,161,250,233,107,147,249,179,218,36,237,86,251,77)
|
||||
IMAGE_DATA(162,246,51,46,232,191,29,142,222,75,238,232,118,219,193,104,111,144,27,250,110,133,161,197,235,32,170,183,173,20,45,159)
|
||||
IMAGE_DATA(60,230,165,51,38,142,80,154,82,187,107,189,224,241,25,103,134,237,114,50,102,84,34,157,14,155,209,121,96,19,158,36)
|
||||
IMAGE_DATA(134,160,249,248,126,100,233,126,39,24,175,52,84,218,76,123,23,204,113,104,57,100,254,15,246,144,17,68,142,70,82,190)
|
||||
IMAGE_DATA(221,222,16,143,237,12,241,104,143,1,122,227,131,81,107,109,0,211,153,19,165,205,92,104,162,197,165,49,246,6,254,202)
|
||||
IMAGE_DATA(112,18,123,18,161,92,219,110,125,180,88,111,64,187,183,19,90,124,221,16,183,98,158,244,50,241,173,215,117,247,94,15)
|
||||
IMAGE_DATA(132,200,197,132,225,36,246,36,66,185,135,150,122,104,54,95,143,7,86,134,104,15,59,143,12,173,175,164,151,153,103,177)
|
||||
IMAGE_DATA(166,187,39,54,0,29,142,91,165,126,82,123,125,85,165,12,79,185,251,102,186,16,154,232,64,104,110,128,246,224,179,72)
|
||||
IMAGE_DATA(213,156,43,229,217,250,223,115,31,95,60,1,209,89,23,169,159,212,94,251,5,15,116,70,135,48,92,211,214,117,16,24)
|
||||
IMAGE_DATA(253,130,135,110,44,8,61,93,17,177,80,93,234,191,197,220,105,14,245,187,55,161,39,246,178,212,79,106,79,34,148,227)
|
||||
IMAGE_DATA(111,94,139,70,67,109,116,132,95,68,241,102,45,108,156,172,34,205,31,173,69,218,186,5,130,166,95,237,208,117,245,146)
|
||||
IMAGE_DATA(212,94,171,151,27,169,249,175,12,215,96,176,134,97,107,89,86,184,178,96,154,96,204,144,247,94,26,6,75,199,127,172)
|
||||
IMAGE_DATA(157,189,246,27,17,223,197,22,162,43,129,104,57,122,16,247,76,244,193,223,182,1,205,71,88,36,103,132,61,96,133,248)
|
||||
IMAGE_DATA(197,127,17,125,251,241,135,175,237,65,141,79,71,106,39,44,255,188,137,179,101,13,132,30,36,23,1,62,104,189,232,3)
|
||||
IMAGE_DATA(193,9,103,220,53,248,9,225,255,163,218,244,205,71,175,103,37,242,169,226,251,170,134,170,163,89,97,11,166,115,111,124)
|
||||
IMAGE_DATA(55,163,243,198,162,25,157,151,230,79,230,234,77,24,201,26,51,68,254,223,62,12,254,14,78,22,173,4,0,0,0,0)
|
||||
IMAGE_END_DATA(3584, 8)
|
||||
4
uppsrc/ide/Linter/Linter.key
Normal file
4
uppsrc/ide/Linter/Linter.key
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
KEY(CHECKFILE, "Analyze source file" , 0)
|
||||
KEY(CHECKPACKAGE, "Analyze package" , 0)
|
||||
KEY(CHECKALL, "Analyze all" , 0)
|
||||
KEY(CONFIGURE, "Configure linter", 0)
|
||||
28
uppsrc/ide/Linter/Linter.upp
Normal file
28
uppsrc/ide/Linter/Linter.upp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
description "TheIDE, static analyzer modules.\377B0,0,0";
|
||||
|
||||
uses
|
||||
ide/Core,
|
||||
ide/Common;
|
||||
|
||||
file
|
||||
Linter.h,
|
||||
Linter.cpp,
|
||||
CppCheck readonly separator,
|
||||
CppCheck.h,
|
||||
CppCheck.cpp,
|
||||
CppCheckConfig.cpp,
|
||||
CppCheckConfig.lay,
|
||||
Clang-Tidy readonly separator,
|
||||
ClangTidy.h,
|
||||
ClangTidy.cpp,
|
||||
ClangTidyConfig.cpp,
|
||||
ClangTidyConfig.lay,
|
||||
Resources readonly separator,
|
||||
Linter.key,
|
||||
Linter.iml,
|
||||
Docs readonly separator,
|
||||
src.tpp,
|
||||
Info readonly separator,
|
||||
Copying,
|
||||
Todo.txt;
|
||||
|
||||
33
uppsrc/ide/Linter/Todo.txt
Normal file
33
uppsrc/ide/Linter/Todo.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
DONE
|
||||
|
||||
+ Linter package: Check file, package, project (all) commands.
|
||||
+ Linter package: TheIDE linter keyboard shortcuts for check file, package, and project commands.
|
||||
+ Linter package: Redesigned as a framework to utilize multiple command-line-driven static analysis tools.
|
||||
+ Linter package: Added initial API docs for implmenting linter modules.
|
||||
+ Linter package: Linter package is now a compile-time option, using the LINTER flag.
|
||||
+ Linter package: Footprint in TheIDE's source code is further narrowed down.
|
||||
+ Linter package: A module registration mechanism is implemented.
|
||||
+ Linter package: Added a mechanism to switch between available linter modules on-the-fly.
|
||||
|
||||
|
||||
+ CppCheck module: Ability to select severity message types.
|
||||
+ CppCheck module: Core configuration settings (language, standard, platform, etc.)
|
||||
+ CppCheck module: Added Windows cppcheck executable detection.
|
||||
+ CppCheck module: Added library file(s) support.
|
||||
+ CppCheck module: Added the ability to pass additional command line options.
|
||||
+ CppCheck module: Re-implemented as a linter module.
|
||||
+ CppCheck module: Can now show verbose messages.
|
||||
+ CppCheck module: Can now show inconclusive results.
|
||||
+ CppCheck module: Can now filter out non C/C++ files and directories (*.tpp, *.log, etc).
|
||||
+ CppCheck module: Allows per-project configuration file.
|
||||
|
||||
+ ClangTidy module: Check file, package, project (all) command.
|
||||
|
||||
WIP:
|
||||
|
||||
- Linter package: Add a clang-tidy module.
|
||||
|
||||
TODO:
|
||||
|
||||
- CppCheck module: Add configurable build dir path (to speed-up analysis).
|
||||
- CppCheck module: Add CLANG backend switch to CppCheck module.
|
||||
168
uppsrc/ide/Linter/src.tpp/Linter_en-us.tpp
Normal file
168
uppsrc/ide/Linter/src.tpp/Linter_en-us.tpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
topic "Linter";
|
||||
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
|
||||
[l288;2 $$2,2#27521748481378242620020725143825:desc]
|
||||
[0 $$3,0#96390100711032703541132217272105:end]
|
||||
[H6;0 $$4,0#05600065144404261032431302351956:begin]
|
||||
[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item]
|
||||
[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement]
|
||||
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
|
||||
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
|
||||
[b42;2 $$9,9#13035079074754324216151401829390:normal]
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[{_}
|
||||
[ {{10000@(113.42.0) [s0;%% [*@7;4 Linter]]}}&]
|
||||
[s3; &]
|
||||
[s1;:Linter: [@(0.0.255) class ][*3 Linter]&]
|
||||
[s2;%% The base class of TheIDE`'s static analyzer tools framework.
|
||||
This class provides a generic interface for integrating command`-line
|
||||
driven static analysis tools in TheIDE.&]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Enumerators]]}}&]
|
||||
[s0;%% &]
|
||||
[s0; enum_[@(0.0.255) class ][* Scope]&]
|
||||
[s2;b17;a17;%% Constants used to indicate the scope of the analysis.&]
|
||||
[s7;i1120;a17;:Ctrl`:`:CENTER:%% [%-*C@3 File]-|Denotes a single file
|
||||
analysis.&]
|
||||
[s7;i1120;a17;:Ctrl`:`:LEFT:%% [%-*C@3 Package]-|Denotes a single package
|
||||
analysis&]
|
||||
[s7;i1120;a17;:Ctrl`:`:RIGHT:%% [%-*C@3 Project]-|Denotes a complete
|
||||
(all packages `+ files) analysis.&]
|
||||
[s0;%% &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Constructor detail]]}}&]
|
||||
[s3; &]
|
||||
[s5;:Linter`:`:Linter`(const Upp`:`:String`&`): [* Linter]([@(0.0.255) const]
|
||||
String[@(0.0.255) `&] [*@3 name])&]
|
||||
[s2;%% Constructor. Deriving class must provide a valid [%-*@3 name]
|
||||
for the module (e.g. `"CppCheck`").&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:`~`(`): [* `~Linter]()&]
|
||||
[s2;%% Default destructor.&]
|
||||
[s3; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:Linter`:`:GetConfigFilePath`(`)const: [@(0.0.255) virtual] String
|
||||
[* GetConfigFilePath]() [@(0.0.255) const ]`= 0&]
|
||||
[s2;%% This method should return the path of the linter module`'s
|
||||
configuration file. .&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:LoadConfig`(`): [@(0.0.255) virtual] Value [* LoadConfig]()
|
||||
`= 0&]
|
||||
[s2;%% This method should load the linter module`'s configuration.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:SaveConfig`(const Upp`:`:Value`&`): [@(0.0.255) virtual]
|
||||
[@(0.0.255) void] [* SaveConfig]([@(0.0.255) const] Value[@(0.0.255) `&]
|
||||
[*@3 cfg])&]
|
||||
[s2;%% This method should save the linter module`'s configuration
|
||||
to file.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:Exists`(`)const: [@(0.0.255) virtual] [@(0.0.255) bool]
|
||||
[* Exists]() [@(0.0.255) const ]`= 0&]
|
||||
[s2;%% This method should return true if the linter backend (e.g.
|
||||
cppcheck, clang`-tidy) is present on the system. .&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:Settings`(`): [@(0.0.255) virtual] [@(0.0.255) void] [* Settings]()
|
||||
`= 0&]
|
||||
[s2;%% This method should open up the linter`'s configuration window.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:GetName`(`)const: String [* GetName]() [@(0.0.255) const]&]
|
||||
[s2;%% Returns the name of the linter module.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:CanCheck`(`)const: [@(0.0.255) bool] [* CanCheck]() [@(0.0.255) const]&]
|
||||
[s2;%% Returns true if TheIDE is in editing state and is not in
|
||||
debug lock mode.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:CheckFile`(`): [@(0.0.255) void] [* CheckFile]()&]
|
||||
[s2;%% Checks and analyzes the current file.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:CheckPackage`(`): [@(0.0.255) void] [* CheckPackage]()&]
|
||||
[s2;%% Checks and analyzes the current package.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:CheckProject`(`): [@(0.0.255) void] [* CheckProject]()&]
|
||||
[s2;%% Checks and analyzes the whole project.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:StdMenu`(Upp`:`:Bar`&`): [@(0.0.255) static] [@(0.0.255) void]
|
||||
[* StdMenu](Bar[@(0.0.255) `&] [*@3 menu])&]
|
||||
[s2;%% Provides a standard linter menu for TheIDE.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:FileMenu`(Upp`:`:Bar`&`): [@(0.0.255) static] [@(0.0.255) void]
|
||||
[* FileMenu](Bar[@(0.0.255) `&] [*@3 menu])&]
|
||||
[s2;%% Provides a linter menu for individual TheIDE c/c`+`+ files&]
|
||||
[s3;~~~256;%% &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:PackageMenu`(Upp`:`:Bar`&`): [@(0.0.255) static] [@(0.0.255) void]
|
||||
[* PackageMenu](Bar[@(0.0.255) `&] [*@3 menu])&]
|
||||
[s2;%% Provides a linter menu for individual TheIDE packages.&]
|
||||
[s3; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Protected Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:Linter`:`:MakeCmdLine`(Linter`:`:Scope`,Vector`&`): [@(0.0.255) virtual]
|
||||
String [* MakeCmdLine]([@(0.0.255) enum] Scope [*@3 sc], Vector<String>[@(0.0.255) `&]
|
||||
[*@3 paths]) `= 0&]
|
||||
[s2;%% The deriving module must define this function to create and
|
||||
return a [/ complete ]command line to be executed by TheIDE. [%-*@3 paths]
|
||||
contain the path of one or more files to be analyzed, depending
|
||||
on the range of the given operation (file, package, project).
|
||||
[%-*@3 sc] indicates the scope of the operation.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:OnResults`(const Upp`:`:String`&`): [@(0.0.255) virtual]
|
||||
[@(0.0.255) void] [* OnResults]([@(0.0.255) const] String[@(0.0.255) `&]
|
||||
[*@3 results]) `= 0&]
|
||||
[s2;%% This method will deliver the [%-*@3 results] of the static analysis
|
||||
to the deriving module. The content of the input data depends
|
||||
on the underlying static analysis tool.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:GetFileName`(`)const: String [* GetFileName]() [@(0.0.255) const]&]
|
||||
[s2;%% Convenience method. Returns the name of TheIDE`'s active file.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:GetFilePath`(`)const: String [* GetFilePath]() [@(0.0.255) const]&]
|
||||
[s2;%% Convenience method. Return the path of TheIDE`'s active file.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:GetPackageName`(`)const: String [* GetPackageName]()
|
||||
[@(0.0.255) const]&]
|
||||
[s2;%% Convenience method. Returns the name of TheIDE`'s active package.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Linter`:`:GetPackagePath`(`)const: String [* GetPackagePath]()
|
||||
[@(0.0.255) const]&]
|
||||
[s2;%% Convenience method. Returns the path of TheIDE`'s active package.&]
|
||||
[s3; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Function List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:RegisterLinterModule`(Linter`&`): [@(0.0.255) void] [* RegisterLinterModule](Linter[@(0.0.255) `&
|
||||
] [*@3 linter`_module])&]
|
||||
[s2;%% Registers a new [%-*@3 linter`_module] to TheIDE`'s static analyzers
|
||||
list.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:GetLinterModuleCount`(`): [@(0.0.255) int] [* GetLinterModuleCount]()&]
|
||||
[s2;%% Returns the number of registered linter modules.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:GetLinterModule`(int`): Linter[@(0.0.255) `&] [* GetLinterModule]([@(0.0.255) int]
|
||||
[*@3 i])&]
|
||||
[s2;%% Returns a reference to the linter module at index [%-*@3 i].
|
||||
&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:GetActiveLinterModulePtr`(`): Linter [@(0.0.255) `*][* GetActiveLinterModulePtr]()&]
|
||||
[s2;%% Returns a pointer to the active (selected) linter module.
|
||||
Returns [%-@(0.0.255) nullptr] if there is no registered linter
|
||||
module&]
|
||||
[s3; ]]
|
||||
|
|
@ -21,6 +21,10 @@
|
|||
#include <ide/Android/Android.h>
|
||||
#include <plugin/md/Markdown.h>
|
||||
|
||||
#ifdef flagLINTER
|
||||
#include <ide/Linter/Linter.h>
|
||||
#endif
|
||||
|
||||
#include "About.h"
|
||||
#include "MethodsCtrls.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ uses
|
|||
Report,
|
||||
Core/SSL,
|
||||
plugin/md,
|
||||
ide/clang;
|
||||
ide/clang,
|
||||
ide/Linter;
|
||||
|
||||
file
|
||||
IDE readonly separator,
|
||||
|
|
@ -136,7 +137,8 @@ mainconfig
|
|||
"" = "GUI HEAPLOG",
|
||||
"" = "GUI X11",
|
||||
"" = "GUI WAYLAND",
|
||||
"" = "GUI DEBUGCODE";
|
||||
"" = "GUI DEBUGCODE",
|
||||
"" = "GUI LINTER";
|
||||
|
||||
custom() "",
|
||||
"ASDFASDFASDF",
|
||||
|
|
|
|||
|
|
@ -859,6 +859,9 @@ void Ide::DebugMenu(Bar& menu)
|
|||
.Help("Build application & run in valgring");
|
||||
#endif
|
||||
menu.Separator();
|
||||
#ifdef flagLINTER // Experimental static analyzer tools support.
|
||||
Linter::StdMenu(menu);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(menu.IsMenuBar()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue