GUI: add setting for 'checkHeaders', 'checkUnusedTemplates' and 'maxCtuDepth' to project

This commit is contained in:
Daniel Marjamäki 2019-04-10 16:49:24 +02:00
parent 466caabbf2
commit f6b410b469
9 changed files with 165 additions and 33 deletions

View File

@ -158,16 +158,6 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
else if (std::strcmp(argv[i], "--dump") == 0)
mSettings->dump = true;
// TODO: These options are about removing code. Instead of having lots of different options
// can we create one option that is customizable somehow.
// --check-headers=no
else if (std::strcmp(argv[i], "--check-headers=no") == 0)
mSettings->checkHeaders = false;
else if (std::strcmp(argv[i], "--remove-unused-templates") == 0)
mSettings->removeUnusedTemplates = true;
else if (std::strcmp(argv[i], "--remove-unused-included-templates") == 0)
mSettings->removeUnusedIncludedTemplates = true;
// max ctu depth
else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0)
mSettings->maxCtuDepth = std::atoi(argv[i] + 16);
@ -931,8 +921,6 @@ void CmdLineParser::printHelp()
" incremental analysis, distributed analysis.\n"
" --check-config Check cppcheck configuration. The normal code\n"
" analysis is disabled by this flag.\n"
" --check-headers=no Turn off checking of included files, to make the\n"
" analysis faster.\n"
" --check-library Show information messages when library files have\n"
" incomplete info.\n"
" --config-exclude=<dir>\n"
@ -1088,10 +1076,6 @@ void CmdLineParser::printHelp()
" using e.g. ~ for home folder does not work. It is\n"
" currently only possible to apply the base paths to\n"
" files that are on a lower level in the directory tree.\n"
" --remove-unused-templates\n"
" Remove unused templates.\n"
" --remove-unused-included-templates\n"
" Remove unused templates in included files.\n"
" --report-progress Report progress messages while checking a file.\n"
#ifdef HAVE_RULES
" --rule=<rule> Match regular expression.\n"

View File

@ -892,6 +892,10 @@ Settings MainWindow::getCppcheckSettings()
}
}
}
result.maxCtuDepth = mProjectFile->getMaxCtuDepth();
result.checkHeaders = mProjectFile->getCheckHeaders();
result.checkUnusedTemplates = mProjectFile->getCheckUnusedTemplates();
}
// Include directories (and files) are searched in listed order.

View File

@ -61,6 +61,9 @@ static const char ToolElementName[] = "tool";
static const char ToolsElementName[] = "tools";
static const char TagsElementName[] = "tags";
static const char TagElementName[] = "tag";
static constexpr char CheckHeadersElementName[] = "check-headers";
static constexpr char CheckUnusedTemplatesElementName[] = "check-unused-templates";
static constexpr char MaxCtuDepthElementName[] = "max-ctu-depth";
ProjectFile::ProjectFile(QObject *parent) :
QObject(parent)
@ -92,6 +95,10 @@ void ProjectFile::clear()
mSuppressions.clear();
mAddons.clear();
mClangAnalyzer = mClangTidy = false;
mAnalyzeAllVsConfigs = false;
mCheckHeaders = true;
mCheckUnusedTemplates = false;
mMaxCtuDepth = 10;
}
bool ProjectFile::read(const QString &filename)
@ -131,7 +138,13 @@ bool ProjectFile::read(const QString &filename)
readImportProject(xmlReader);
if (insideProject && xmlReader.name() == AnalyzeAllVsConfigsElementName)
readAnalyzeAllVsConfigs(xmlReader);
mAnalyzeAllVsConfigs = readBool(xmlReader);
if (insideProject && xmlReader.name() == CheckHeadersElementName)
mCheckHeaders = readBool(xmlReader);
if (insideProject && xmlReader.name() == CheckUnusedTemplatesElementName)
mCheckUnusedTemplates = readBool(xmlReader);
// Find include directory from inside project element
if (insideProject && xmlReader.name() == IncludeDirElementName)
@ -180,6 +193,9 @@ bool ProjectFile::read(const QString &filename)
if (insideProject && xmlReader.name() == TagsElementName)
readStringList(mTags, xmlReader, TagElementName);
if (insideProject && xmlReader.name() == MaxCtuDepthElementName)
mMaxCtuDepth = readInt(xmlReader, mMaxCtuDepth);
break;
case QXmlStreamReader::EndElement:
@ -263,15 +279,41 @@ void ProjectFile::readImportProject(QXmlStreamReader &reader)
} while (1);
}
void ProjectFile::readAnalyzeAllVsConfigs(QXmlStreamReader &reader)
bool ProjectFile::readBool(QXmlStreamReader &reader)
{
bool ret = false;
do {
const QXmlStreamReader::TokenType type = reader.readNext();
switch (type) {
case QXmlStreamReader::Characters:
mAnalyzeAllVsConfigs = (reader.text().toString() == "true");
ret = (reader.text().toString() == "true");
case QXmlStreamReader::EndElement:
return;
return ret;
// Not handled
case QXmlStreamReader::StartElement:
case QXmlStreamReader::NoToken:
case QXmlStreamReader::Invalid:
case QXmlStreamReader::StartDocument:
case QXmlStreamReader::EndDocument:
case QXmlStreamReader::Comment:
case QXmlStreamReader::DTD:
case QXmlStreamReader::EntityReference:
case QXmlStreamReader::ProcessingInstruction:
break;
}
} while (1);
}
int ProjectFile::readInt(QXmlStreamReader &reader, int defaultValue)
{
int ret = defaultValue;
do {
const QXmlStreamReader::TokenType type = reader.readNext();
switch (type) {
case QXmlStreamReader::Characters:
ret = reader.text().toString().toInt();
case QXmlStreamReader::EndElement:
return ret;
// Not handled
case QXmlStreamReader::StartElement:
case QXmlStreamReader::NoToken:
@ -642,6 +684,18 @@ bool ProjectFile::write(const QString &filename)
xmlWriter.writeCharacters(mAnalyzeAllVsConfigs ? "true" : "false");
xmlWriter.writeEndElement();
xmlWriter.writeStartElement(CheckHeadersElementName);
xmlWriter.writeCharacters(mCheckHeaders ? "true" : "false");
xmlWriter.writeEndElement();
xmlWriter.writeStartElement(CheckUnusedTemplatesElementName);
xmlWriter.writeCharacters(mCheckUnusedTemplates ? "true" : "false");
xmlWriter.writeEndElement();
xmlWriter.writeStartElement(MaxCtuDepthElementName);
xmlWriter.writeCharacters(QString::number(mMaxCtuDepth));
xmlWriter.writeEndElement();
if (!mIncludeDirs.isEmpty()) {
xmlWriter.writeStartElement(IncludeDirElementName);
foreach (QString incdir, mIncludeDirs) {

View File

@ -68,6 +68,22 @@ public:
return mAnalyzeAllVsConfigs;
}
bool getCheckHeaders() const {
return mCheckHeaders;
}
void setCheckHeaders(bool b) {
mCheckHeaders = b;
}
bool getCheckUnusedTemplates() const {
return mCheckUnusedTemplates;
}
void setCheckUnusedTemplates(bool b) {
mCheckUnusedTemplates = b;
}
/**
* @brief Get list of include directories.
* @return list of directories.
@ -166,6 +182,14 @@ public:
return mTags;
}
int getMaxCtuDepth() const {
return mMaxCtuDepth;
}
void setMaxCtuDepth(int maxCtuDepth) {
mMaxCtuDepth = maxCtuDepth;
}
/**
* @brief Get filename for the project file.
* @return file name.
@ -286,7 +310,9 @@ protected:
*/
void readImportProject(QXmlStreamReader &reader);
void readAnalyzeAllVsConfigs(QXmlStreamReader &reader);
bool readBool(QXmlStreamReader &reader);
int readInt(QXmlStreamReader &reader, int defaultValue);
/**
* @brief Read list of include directories from XML.
@ -376,6 +402,12 @@ private:
*/
bool mAnalyzeAllVsConfigs;
/** Check code in headers */
bool mCheckHeaders;
/** Check code in unused templates */
bool mCheckUnusedTemplates;
/**
* @brief List of include directories used to search include files.
*/
@ -431,6 +463,9 @@ private:
* @brief Warning tags
*/
QStringList mTags;
/** Max CTU depth */
int mMaxCtuDepth;
};
/// @}
#endif // PROJECT_FILE_H

View File

@ -240,6 +240,9 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
setCheckPaths(projectFile->getCheckPaths());
setImportProject(projectFile->getImportProject());
mUI.mChkAllVsConfigs->setChecked(projectFile->getAnalyzeAllVsConfigs());
mUI.mCheckHeaders->setChecked(projectFile->getCheckHeaders());
mUI.mCheckUnusedTemplates->setChecked(projectFile->getCheckUnusedTemplates());
mUI.mMaxCtuDepth->setValue(projectFile->getMaxCtuDepth());
setExcludedPaths(projectFile->getExcludedPaths());
setLibraries(projectFile->getLibraries());
const QString platform = projectFile->getPlatform();
@ -304,6 +307,9 @@ void ProjectFileDialog::saveToProjectFile(ProjectFile *projectFile) const
projectFile->setBuildDir(getBuildDir());
projectFile->setImportProject(getImportProject());
projectFile->setAnalyzeAllVsConfigs(mUI.mChkAllVsConfigs->isChecked());
projectFile->setCheckHeaders(mUI.mCheckHeaders->isChecked());
projectFile->setCheckUnusedTemplates(mUI.mCheckUnusedTemplates->isChecked());
projectFile->setMaxCtuDepth(mUI.mMaxCtuDepth->value());
projectFile->setIncludes(getIncludePaths());
projectFile->setDefines(getDefines());
projectFile->setUndefines(getUndefines());

View File

@ -325,6 +325,59 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>Analysis</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QCheckBox" name="mCheckHeaders">
<property name="text">
<string>Check code in headers (slower analysis, more results)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="mCheckUnusedTemplates">
<property name="text">
<string>Check code in unused templates (slower and less accurate analysis)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Max CTU depth</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="mMaxCtuDepth"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">

View File

@ -51,8 +51,7 @@ Settings::Settings()
checkConfiguration(false),
checkLibrary(false),
checkHeaders(true),
removeUnusedTemplates(false),
removeUnusedIncludedTemplates(false)
checkUnusedTemplates(false)
{
}

View File

@ -290,11 +290,8 @@ public:
* be turned off to save CPU */
bool checkHeaders;
/** Remove unused templates in all files */
bool removeUnusedTemplates;
/** Remove unused included templates */
bool removeUnusedIncludedTemplates;
/** Check unused templates */
bool checkUnusedTemplates;
/** Struct contains standards settings */
Standards standards;

View File

@ -4767,15 +4767,15 @@ void Tokenizer::simplifyHeaders()
// TODO : can we remove anything in headers here? Like unused declarations.
// Maybe if --dump is used we want to have _everything_.
if (mSettings->checkHeaders && !mSettings->removeUnusedTemplates && !mSettings->removeUnusedIncludedTemplates)
if (mSettings->checkHeaders && mSettings->checkUnusedTemplates)
// Default=full analysis. All information in the headers are kept.
return;
const bool checkHeaders = mSettings->checkHeaders;
const bool removeUnusedIncludedFunctions = mSettings->checkHeaders;
const bool removeUnusedIncludedClasses = mSettings->checkHeaders;
const bool removeUnusedTemplates = mSettings->removeUnusedTemplates;
const bool removeUnusedIncludedTemplates = mSettings->checkHeaders || mSettings->removeUnusedIncludedTemplates;
const bool removeUnusedIncludedFunctions = !mSettings->checkHeaders;
const bool removeUnusedIncludedClasses = !mSettings->checkHeaders;
const bool removeUnusedIncludedTemplates = !mSettings->checkUnusedTemplates || !mSettings->checkHeaders;
const bool removeUnusedTemplates = !mSettings->checkUnusedTemplates;
// We want to remove selected stuff from the headers but not *everything*.
// The intention here is to not damage the analysis of the source file.