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) else if (std::strcmp(argv[i], "--dump") == 0)
mSettings->dump = true; 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 // max ctu depth
else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0) else if (std::strncmp(argv[i], "--max-ctu-depth=", 16) == 0)
mSettings->maxCtuDepth = std::atoi(argv[i] + 16); mSettings->maxCtuDepth = std::atoi(argv[i] + 16);
@ -931,8 +921,6 @@ void CmdLineParser::printHelp()
" incremental analysis, distributed analysis.\n" " incremental analysis, distributed analysis.\n"
" --check-config Check cppcheck configuration. The normal code\n" " --check-config Check cppcheck configuration. The normal code\n"
" analysis is disabled by this flag.\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" " --check-library Show information messages when library files have\n"
" incomplete info.\n" " incomplete info.\n"
" --config-exclude=<dir>\n" " --config-exclude=<dir>\n"
@ -1088,10 +1076,6 @@ void CmdLineParser::printHelp()
" using e.g. ~ for home folder does not work. It is\n" " using e.g. ~ for home folder does not work. It is\n"
" currently only possible to apply the base paths to\n" " currently only possible to apply the base paths to\n"
" files that are on a lower level in the directory tree.\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" " --report-progress Report progress messages while checking a file.\n"
#ifdef HAVE_RULES #ifdef HAVE_RULES
" --rule=<rule> Match regular expression.\n" " --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. // 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 ToolsElementName[] = "tools";
static const char TagsElementName[] = "tags"; static const char TagsElementName[] = "tags";
static const char TagElementName[] = "tag"; 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) : ProjectFile::ProjectFile(QObject *parent) :
QObject(parent) QObject(parent)
@ -92,6 +95,10 @@ void ProjectFile::clear()
mSuppressions.clear(); mSuppressions.clear();
mAddons.clear(); mAddons.clear();
mClangAnalyzer = mClangTidy = false; mClangAnalyzer = mClangTidy = false;
mAnalyzeAllVsConfigs = false;
mCheckHeaders = true;
mCheckUnusedTemplates = false;
mMaxCtuDepth = 10;
} }
bool ProjectFile::read(const QString &filename) bool ProjectFile::read(const QString &filename)
@ -131,7 +138,13 @@ bool ProjectFile::read(const QString &filename)
readImportProject(xmlReader); readImportProject(xmlReader);
if (insideProject && xmlReader.name() == AnalyzeAllVsConfigsElementName) 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 // Find include directory from inside project element
if (insideProject && xmlReader.name() == IncludeDirElementName) if (insideProject && xmlReader.name() == IncludeDirElementName)
@ -180,6 +193,9 @@ bool ProjectFile::read(const QString &filename)
if (insideProject && xmlReader.name() == TagsElementName) if (insideProject && xmlReader.name() == TagsElementName)
readStringList(mTags, xmlReader, TagElementName); readStringList(mTags, xmlReader, TagElementName);
if (insideProject && xmlReader.name() == MaxCtuDepthElementName)
mMaxCtuDepth = readInt(xmlReader, mMaxCtuDepth);
break; break;
case QXmlStreamReader::EndElement: case QXmlStreamReader::EndElement:
@ -263,15 +279,41 @@ void ProjectFile::readImportProject(QXmlStreamReader &reader)
} while (1); } while (1);
} }
void ProjectFile::readAnalyzeAllVsConfigs(QXmlStreamReader &reader) bool ProjectFile::readBool(QXmlStreamReader &reader)
{ {
bool ret = false;
do { do {
const QXmlStreamReader::TokenType type = reader.readNext(); const QXmlStreamReader::TokenType type = reader.readNext();
switch (type) { switch (type) {
case QXmlStreamReader::Characters: case QXmlStreamReader::Characters:
mAnalyzeAllVsConfigs = (reader.text().toString() == "true"); ret = (reader.text().toString() == "true");
case QXmlStreamReader::EndElement: 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 // Not handled
case QXmlStreamReader::StartElement: case QXmlStreamReader::StartElement:
case QXmlStreamReader::NoToken: case QXmlStreamReader::NoToken:
@ -642,6 +684,18 @@ bool ProjectFile::write(const QString &filename)
xmlWriter.writeCharacters(mAnalyzeAllVsConfigs ? "true" : "false"); xmlWriter.writeCharacters(mAnalyzeAllVsConfigs ? "true" : "false");
xmlWriter.writeEndElement(); 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()) { if (!mIncludeDirs.isEmpty()) {
xmlWriter.writeStartElement(IncludeDirElementName); xmlWriter.writeStartElement(IncludeDirElementName);
foreach (QString incdir, mIncludeDirs) { foreach (QString incdir, mIncludeDirs) {

View File

@ -68,6 +68,22 @@ public:
return mAnalyzeAllVsConfigs; 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. * @brief Get list of include directories.
* @return list of directories. * @return list of directories.
@ -166,6 +182,14 @@ public:
return mTags; return mTags;
} }
int getMaxCtuDepth() const {
return mMaxCtuDepth;
}
void setMaxCtuDepth(int maxCtuDepth) {
mMaxCtuDepth = maxCtuDepth;
}
/** /**
* @brief Get filename for the project file. * @brief Get filename for the project file.
* @return file name. * @return file name.
@ -286,7 +310,9 @@ protected:
*/ */
void readImportProject(QXmlStreamReader &reader); 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. * @brief Read list of include directories from XML.
@ -376,6 +402,12 @@ private:
*/ */
bool mAnalyzeAllVsConfigs; 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. * @brief List of include directories used to search include files.
*/ */
@ -431,6 +463,9 @@ private:
* @brief Warning tags * @brief Warning tags
*/ */
QStringList mTags; QStringList mTags;
/** Max CTU depth */
int mMaxCtuDepth;
}; };
/// @} /// @}
#endif // PROJECT_FILE_H #endif // PROJECT_FILE_H

View File

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

View File

@ -325,6 +325,59 @@
</layout> </layout>
</widget> </widget>
</item> </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> <item>
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">

View File

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

View File

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

View File

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