Check specific Visual Studio configurations (#2503)
This commit is contained in:
parent
589b497ead
commit
074d08e39e
|
@ -65,6 +65,7 @@ void ProjectFile::clear()
|
|||
mMaxCtuDepth = 10;
|
||||
mCheckUnknownFunctionReturn.clear();
|
||||
mSafeChecks.clear();
|
||||
mVsConfigurations.clear();
|
||||
}
|
||||
|
||||
bool ProjectFile::read(const QString &filename)
|
||||
|
@ -174,6 +175,9 @@ bool ProjectFile::read(const QString &filename)
|
|||
if (xmlReader.name() == CppcheckXml::MaxCtuDepthElementName)
|
||||
mMaxCtuDepth = readInt(xmlReader, mMaxCtuDepth);
|
||||
|
||||
// VSConfiguration
|
||||
if (xmlReader.name() == CppcheckXml::VSConfigurationElementName)
|
||||
readVsConfigurations(xmlReader);
|
||||
break;
|
||||
|
||||
case QXmlStreamReader::EndElement:
|
||||
|
@ -466,6 +470,44 @@ void ProjectFile::readExcludes(QXmlStreamReader &reader)
|
|||
} while (!allRead);
|
||||
}
|
||||
|
||||
void ProjectFile::readVsConfigurations(QXmlStreamReader &reader)
|
||||
{
|
||||
QXmlStreamReader::TokenType type;
|
||||
do {
|
||||
type = reader.readNext();
|
||||
switch (type) {
|
||||
case QXmlStreamReader::StartElement:
|
||||
// Read library-elements
|
||||
if (reader.name().toString() == CppcheckXml::VSConfigurationName) {
|
||||
QString config;
|
||||
type = reader.readNext();
|
||||
if (type == QXmlStreamReader::Characters) {
|
||||
config = reader.text().toString();
|
||||
}
|
||||
mVsConfigurations << config;
|
||||
}
|
||||
break;
|
||||
|
||||
case QXmlStreamReader::EndElement:
|
||||
if (reader.name().toString() != CppcheckXml::VSConfigurationName)
|
||||
return;
|
||||
break;
|
||||
|
||||
// Not handled
|
||||
case QXmlStreamReader::NoToken:
|
||||
case QXmlStreamReader::Invalid:
|
||||
case QXmlStreamReader::StartDocument:
|
||||
case QXmlStreamReader::EndDocument:
|
||||
case QXmlStreamReader::Characters:
|
||||
case QXmlStreamReader::Comment:
|
||||
case QXmlStreamReader::DTD:
|
||||
case QXmlStreamReader::EntityReference:
|
||||
case QXmlStreamReader::ProcessingInstruction:
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void ProjectFile::readPlatform(QXmlStreamReader &reader)
|
||||
{
|
||||
do {
|
||||
|
@ -619,6 +661,11 @@ void ProjectFile::setAddons(const QStringList &addons)
|
|||
mAddons = addons;
|
||||
}
|
||||
|
||||
void ProjectFile::setVSConfigurations(const QStringList &vsConfigs)
|
||||
{
|
||||
mVsConfigurations = vsConfigs;
|
||||
}
|
||||
|
||||
bool ProjectFile::write(const QString &filename)
|
||||
{
|
||||
if (!filename.isEmpty())
|
||||
|
@ -694,6 +741,13 @@ bool ProjectFile::write(const QString &filename)
|
|||
xmlWriter.writeEndElement();
|
||||
}
|
||||
|
||||
if (!mVsConfigurations.isEmpty()) {
|
||||
writeStringList(xmlWriter,
|
||||
mVsConfigurations,
|
||||
CppcheckXml::VSConfigurationElementName,
|
||||
CppcheckXml::VSConfigurationName);
|
||||
}
|
||||
|
||||
writeStringList(xmlWriter,
|
||||
mUndefines,
|
||||
CppcheckXml::UndefinesElementName,
|
||||
|
|
|
@ -124,6 +124,14 @@ public:
|
|||
return ProjectFile::fromNativeSeparators(mExcludedPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get list of paths to exclude from the check.
|
||||
* @return list of paths.
|
||||
*/
|
||||
QStringList getVsConfigurations() const {
|
||||
return mVsConfigurations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get list libraries.
|
||||
* @return list of libraries.
|
||||
|
@ -272,6 +280,11 @@ public:
|
|||
*/
|
||||
void setAddons(const QStringList &addons);
|
||||
|
||||
/** @brief Set list of Visual Studio configurations to be checked
|
||||
* @param vsConfigs List of configurations
|
||||
*/
|
||||
void setVSConfigurations(const QStringList &vsConfigs);
|
||||
|
||||
/**
|
||||
* @brief Set tags.
|
||||
* @param tags tag list
|
||||
|
@ -394,6 +407,12 @@ protected:
|
|||
*/
|
||||
void readExcludes(QXmlStreamReader &reader);
|
||||
|
||||
/**
|
||||
* @brief Read lists of Visual Studio configurations
|
||||
* @param reader XML stream reader.
|
||||
*/
|
||||
void readVsConfigurations(QXmlStreamReader &reader);
|
||||
|
||||
/**
|
||||
* @brief Read platform text.
|
||||
* @param reader XML stream reader.
|
||||
|
@ -458,6 +477,9 @@ private:
|
|||
*/
|
||||
bool mAnalyzeAllVsConfigs;
|
||||
|
||||
/** Check only a selected VS configuration */
|
||||
QStringList mVsConfigurations;
|
||||
|
||||
/** Check code in headers */
|
||||
bool mCheckHeaders;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QProcess>
|
||||
#include <QListView>
|
||||
#include "common.h"
|
||||
#include "newsuppressiondialog.h"
|
||||
#include "projectfiledialog.h"
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "projectfile.h"
|
||||
#include "library.h"
|
||||
#include "platforms.h"
|
||||
#include "importproject.h"
|
||||
|
||||
/** Return paths from QListWidget */
|
||||
static QStringList getPaths(const QListWidget *list)
|
||||
|
@ -58,6 +60,16 @@ static const cppcheck::Platform::PlatformType builtinPlatforms[] = {
|
|||
|
||||
static const int numberOfBuiltinPlatforms = sizeof(builtinPlatforms) / sizeof(builtinPlatforms[0]);
|
||||
|
||||
QStringList ProjectFileDialog::getProjectConfigs(const QString &fileName) {
|
||||
QStringList ret;
|
||||
ImportProject importer;
|
||||
Settings projSettings;
|
||||
importer.import(fileName.toStdString(), &projSettings);
|
||||
for (const std::string &cfg : importer.getVSConfigs())
|
||||
ret << QString::fromStdString(cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, mProjectFile(projectFile)
|
||||
|
@ -194,7 +206,7 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent)
|
|||
connect(mUI.mBtnRemoveSuppression, &QPushButton::clicked, this, &ProjectFileDialog::removeSuppression);
|
||||
connect(mUI.mListSuppressions, &QListWidget::doubleClicked, this, &ProjectFileDialog::editSuppression);
|
||||
connect(mUI.mBtnBrowseMisraFile, &QPushButton::clicked, this, &ProjectFileDialog::browseMisraFile);
|
||||
|
||||
connect(mUI.mChkAllVsConfigs, &QCheckBox::clicked, this, &ProjectFileDialog::checkAllVSConfigs);
|
||||
loadFromProjectFile(projectFile);
|
||||
}
|
||||
|
||||
|
@ -227,6 +239,13 @@ static void updateAddonCheckBox(QCheckBox *cb, const ProjectFile *projectFile, c
|
|||
}
|
||||
}
|
||||
|
||||
void ProjectFileDialog::checkAllVSConfigs()
|
||||
{
|
||||
if(mUI.mChkAllVsConfigs->isChecked())
|
||||
mUI.mListVsConfigs->selectAll();
|
||||
mUI.mListVsConfigs->setEnabled(!mUI.mChkAllVsConfigs->isChecked());
|
||||
}
|
||||
|
||||
void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
|
||||
{
|
||||
setRootPath(projectFile->getRootPath());
|
||||
|
@ -313,6 +332,16 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
|
|||
}
|
||||
mUI.mEditTags->setText(projectFile->getTags().join(';'));
|
||||
updatePathsAndDefines();
|
||||
if(mUI.mEditImportProject->text().endsWith(".sln") || mUI.mEditImportProject->text().endsWith(".vcxproj")) {
|
||||
setVsConfigurations(getProjectConfigs(mUI.mEditImportProject->text()));
|
||||
foreach(const QString &cfg, projectFile->getVsConfigurations()) {
|
||||
QList<QListWidgetItem*> items = mUI.mListVsConfigs->findItems(cfg, Qt::MatchFlag::MatchExactly);
|
||||
items[0]->setSelected(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
mUI.mListVsConfigs->setEnabled(false);
|
||||
|
||||
}
|
||||
|
||||
void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
|
||||
|
@ -370,6 +399,7 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
|
|||
projectFile->setClangAnalyzer(mUI.mToolClangAnalyzer->isChecked());
|
||||
projectFile->setClangTidy(mUI.mToolClangTidy->isChecked());
|
||||
projectFile->setTags(mUI.mEditTags->text().split(";", QString::SkipEmptyParts));
|
||||
projectFile->setVSConfigurations(getVsConfigurations());
|
||||
}
|
||||
|
||||
void ProjectFileDialog::ok()
|
||||
|
@ -429,6 +459,7 @@ void ProjectFileDialog::updatePathsAndDefines()
|
|||
mUI.mBtnIncludeUp->setEnabled(!importProject);
|
||||
mUI.mBtnIncludeDown->setEnabled(!importProject);
|
||||
mUI.mChkAllVsConfigs->setEnabled(fileName.endsWith(".sln") || fileName.endsWith(".vcxproj"));
|
||||
mUI.mListVsConfigs->setEnabled(fileName.endsWith(".sln") || fileName.endsWith(".vcxproj"));
|
||||
}
|
||||
|
||||
void ProjectFileDialog::clearImportProject()
|
||||
|
@ -451,9 +482,26 @@ void ProjectFileDialog::browseImportProject()
|
|||
if (!fileName.isEmpty()) {
|
||||
mUI.mEditImportProject->setText(dir.relativeFilePath(fileName));
|
||||
updatePathsAndDefines();
|
||||
setVsConfigurations(getProjectConfigs(fileName));
|
||||
mUI.mListVsConfigs->selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ProjectFileDialog::getVsConfigurations() const
|
||||
{
|
||||
QStringList configs;
|
||||
foreach(QListWidgetItem *item, mUI.mListVsConfigs->selectedItems())
|
||||
configs << item->text();
|
||||
|
||||
return configs;
|
||||
}
|
||||
|
||||
void ProjectFileDialog::setVsConfigurations(const QStringList &configs)
|
||||
{
|
||||
mUI.mListVsConfigs->clear();
|
||||
mUI.mListVsConfigs->addItems(configs);
|
||||
}
|
||||
|
||||
QString ProjectFileDialog::getImportProject() const
|
||||
{
|
||||
return mUI.mEditImportProject->text();
|
||||
|
|
|
@ -58,6 +58,9 @@ private:
|
|||
*/
|
||||
QString getRootPath() const;
|
||||
|
||||
QStringList getVsConfigurations() const;
|
||||
void setVsConfigurations(const QStringList &configs);
|
||||
|
||||
QString getImportProject() const;
|
||||
|
||||
/** Get Cppcheck build dir */
|
||||
|
@ -256,6 +259,11 @@ protected slots:
|
|||
*/
|
||||
void browseMisraFile();
|
||||
|
||||
/**
|
||||
* @brief Check for all VS configurations
|
||||
*/
|
||||
void checkAllVSConfigs();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -295,6 +303,8 @@ protected:
|
|||
int getSuppressionIndex(const QString &shortText) const;
|
||||
|
||||
private:
|
||||
QStringList getProjectConfigs(const QString &fileName);
|
||||
|
||||
Ui::ProjectFile mUI;
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>888</width>
|
||||
<height>585</height>
|
||||
<height>573</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -64,14 +64,45 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mChkAllVsConfigs">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Analyze all Visual Studio configurations</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mChkAllVsConfigs">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Analyze all Visual Studio configurations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mLabelVSConfig">
|
||||
<property name="text">
|
||||
<string>Selected VS Configurations</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="mListVsConfigs">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -621,8 +621,10 @@ void ImportProject::importVcxproj(const std::string &filename, std::map<std::str
|
|||
for (const tinyxml2::XMLElement *cfg = node->FirstChildElement(); cfg; cfg = cfg->NextSiblingElement()) {
|
||||
if (std::strcmp(cfg->Name(), "ProjectConfiguration") == 0) {
|
||||
const ProjectConfiguration p(cfg);
|
||||
if (p.platform != ProjectConfiguration::Unknown)
|
||||
if (p.platform != ProjectConfiguration::Unknown) {
|
||||
projectConfigurationList.emplace_back(cfg);
|
||||
mAllVSConfigs.insert(p.configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -654,6 +656,18 @@ void ImportProject::importVcxproj(const std::string &filename, std::map<std::str
|
|||
|
||||
for (const std::string &c : compileList) {
|
||||
for (const ProjectConfiguration &p : projectConfigurationList) {
|
||||
|
||||
if (!guiProject.checkVsConfigs.empty()) {
|
||||
bool doChecking = false;
|
||||
for (std::string config : guiProject.checkVsConfigs)
|
||||
if (config == p.configuration) {
|
||||
doChecking = true;
|
||||
break;
|
||||
}
|
||||
if(!doChecking)
|
||||
continue;
|
||||
}
|
||||
|
||||
FileSettings fs;
|
||||
fs.filename = Path::simplifyPath(Path::isAbsolute(c) ? c : Path::getPathFromFilename(filename) + c);
|
||||
fs.cfg = p.name;
|
||||
|
@ -975,6 +989,7 @@ static std::string istream_to_string(std::istream &istr)
|
|||
return std::string(std::istreambuf_iterator<char>(istr), eos);
|
||||
}
|
||||
|
||||
|
||||
bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *settings)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
|
@ -1018,6 +1033,8 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
guiProject.libraries = readXmlStringList(node, "", CppcheckXml::LibraryElementName, nullptr);
|
||||
else if (strcmp(node->Name(), CppcheckXml::SuppressionsElementName) == 0)
|
||||
suppressions = readXmlStringList(node, "", CppcheckXml::SuppressionElementName, nullptr);
|
||||
else if (strcmp(node->Name(), CppcheckXml::VSConfigurationElementName) == 0)
|
||||
guiProject.checkVsConfigs = readXmlStringList(node, "", CppcheckXml::VSConfigurationName, nullptr);
|
||||
else if (strcmp(node->Name(), CppcheckXml::PlatformElementName) == 0)
|
||||
guiProject.platform = node->GetText();
|
||||
else if (strcmp(node->Name(), CppcheckXml::AnalyzeAllVsConfigsElementName) == 0)
|
||||
|
@ -1064,6 +1081,7 @@ bool ImportProject::importCppcheckGuiProject(std::istream &istr, Settings *setti
|
|||
settings->userUndefs = temp.userUndefs;
|
||||
settings->addons = temp.addons;
|
||||
settings->clangTidy = temp.clangTidy;
|
||||
|
||||
for (const std::string &p : paths)
|
||||
guiProject.pathNames.push_back(p);
|
||||
for (const std::string &supp : suppressions)
|
||||
|
@ -1103,3 +1121,8 @@ void ImportProject::selectOneVsConfig(Settings::PlatformType platform)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::string> ImportProject::getVSConfigs()
|
||||
{
|
||||
return std::list<std::string> (mAllVSConfigs.begin(), mAllVSConfigs.end());
|
||||
}
|
|
@ -84,12 +84,15 @@ public:
|
|||
|
||||
void selectOneVsConfig(cppcheck::Platform::PlatformType platform);
|
||||
|
||||
std::list<std::string> getVSConfigs();
|
||||
|
||||
// Cppcheck GUI output
|
||||
struct {
|
||||
std::string analyzeAllVsConfigs;
|
||||
std::vector<std::string> pathNames;
|
||||
std::list<std::string> libraries;
|
||||
std::list<std::string> excludedPaths;
|
||||
std::list<std::string> checkVsConfigs;
|
||||
std::string projectFile;
|
||||
std::string platform;
|
||||
} guiProject;
|
||||
|
@ -108,6 +111,7 @@ private:
|
|||
void importBcb6Prj(const std::string &projectFilename);
|
||||
|
||||
std::string mPath;
|
||||
std::set<std::string> mAllVSConfigs;
|
||||
};
|
||||
|
||||
|
||||
|
@ -154,6 +158,8 @@ namespace CppcheckXml {
|
|||
const char CheckUnknownFunctionReturn[] = "check-unknown-function-return-values";
|
||||
const char ClangTidy[] = "clang-tidy";
|
||||
const char Name[] = "name";
|
||||
const char VSConfigurationElementName[] = "vs-configurations";
|
||||
const char VSConfigurationName[] = "config";
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -153,6 +153,9 @@ public:
|
|||
for finding include files inside source files. (-I) */
|
||||
std::list<std::string> includePaths;
|
||||
|
||||
/** @brief List of selected Visual Studio configurations that should be checks */
|
||||
std::list<std::string> checkVsConfigs;
|
||||
|
||||
/** @brief Inconclusive checks */
|
||||
bool inconclusive;
|
||||
|
||||
|
|
Loading…
Reference in New Issue