32 #include <QLatin1String>
33 #include <QRegularExpression>
34 #include <QXmlStreamAttributes>
35 #include <QXmlStreamReader>
36 #include <QXmlStreamWriter>
38 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
52 mFilename(std::move(filename))
96 if (!filename.isEmpty())
100 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
105 QXmlStreamReader xmlReader(&file);
106 bool insideProject =
false;
107 bool projectTagFound =
false;
108 while (!xmlReader.atEnd()) {
109 switch (xmlReader.readNext()) {
110 case QXmlStreamReader::StartElement:
112 insideProject =
true;
113 projectTagFound =
true;
229 case QXmlStreamReader::EndElement:
231 insideProject =
false;
235 case QXmlStreamReader::NoToken:
236 case QXmlStreamReader::Invalid:
237 case QXmlStreamReader::StartDocument:
238 case QXmlStreamReader::EndDocument:
239 case QXmlStreamReader::Characters:
240 case QXmlStreamReader::Comment:
241 case QXmlStreamReader::DTD:
242 case QXmlStreamReader::EntityReference:
243 case QXmlStreamReader::ProcessingInstruction:
249 return projectTagFound;
254 QXmlStreamAttributes attribs = reader.attributes();
264 const QXmlStreamReader::TokenType type = reader.readNext();
266 case QXmlStreamReader::Characters:
269 case QXmlStreamReader::EndElement:
272 case QXmlStreamReader::StartElement:
273 case QXmlStreamReader::NoToken:
274 case QXmlStreamReader::Invalid:
275 case QXmlStreamReader::StartDocument:
276 case QXmlStreamReader::EndDocument:
277 case QXmlStreamReader::Comment:
278 case QXmlStreamReader::DTD:
279 case QXmlStreamReader::EntityReference:
280 case QXmlStreamReader::ProcessingInstruction:
290 const QXmlStreamReader::TokenType type = reader.readNext();
292 case QXmlStreamReader::Characters:
295 case QXmlStreamReader::EndElement:
298 case QXmlStreamReader::StartElement:
299 case QXmlStreamReader::NoToken:
300 case QXmlStreamReader::Invalid:
301 case QXmlStreamReader::StartDocument:
302 case QXmlStreamReader::EndDocument:
303 case QXmlStreamReader::Comment:
304 case QXmlStreamReader::DTD:
305 case QXmlStreamReader::EntityReference:
306 case QXmlStreamReader::ProcessingInstruction:
316 const QXmlStreamReader::TokenType type = reader.readNext();
318 case QXmlStreamReader::Characters:
319 ret = (reader.text().toString() ==
"true");
321 case QXmlStreamReader::EndElement:
324 case QXmlStreamReader::StartElement:
325 case QXmlStreamReader::NoToken:
326 case QXmlStreamReader::Invalid:
327 case QXmlStreamReader::StartDocument:
328 case QXmlStreamReader::EndDocument:
329 case QXmlStreamReader::Comment:
330 case QXmlStreamReader::DTD:
331 case QXmlStreamReader::EntityReference:
332 case QXmlStreamReader::ProcessingInstruction:
340 int ret = defaultValue;
342 const QXmlStreamReader::TokenType type = reader.readNext();
344 case QXmlStreamReader::Characters:
345 ret = reader.text().toString().toInt();
347 case QXmlStreamReader::EndElement:
350 case QXmlStreamReader::StartElement:
351 case QXmlStreamReader::NoToken:
352 case QXmlStreamReader::Invalid:
353 case QXmlStreamReader::StartDocument:
354 case QXmlStreamReader::EndDocument:
355 case QXmlStreamReader::Comment:
356 case QXmlStreamReader::DTD:
357 case QXmlStreamReader::EntityReference:
358 case QXmlStreamReader::ProcessingInstruction:
368 const QXmlStreamReader::TokenType type = reader.readNext();
370 case QXmlStreamReader::Characters:
371 ret = reader.text().toString();
373 case QXmlStreamReader::EndElement:
376 case QXmlStreamReader::StartElement:
377 case QXmlStreamReader::NoToken:
378 case QXmlStreamReader::Invalid:
379 case QXmlStreamReader::StartDocument:
380 case QXmlStreamReader::EndDocument:
381 case QXmlStreamReader::Comment:
382 case QXmlStreamReader::DTD:
383 case QXmlStreamReader::EntityReference:
384 case QXmlStreamReader::ProcessingInstruction:
392 bool allRead =
false;
394 QXmlStreamReader::TokenType type = reader.readNext();
396 case QXmlStreamReader::StartElement:
400 QXmlStreamAttributes attribs = reader.attributes();
407 case QXmlStreamReader::EndElement:
413 case QXmlStreamReader::NoToken:
414 case QXmlStreamReader::Invalid:
415 case QXmlStreamReader::StartDocument:
416 case QXmlStreamReader::EndDocument:
417 case QXmlStreamReader::Characters:
418 case QXmlStreamReader::Comment:
419 case QXmlStreamReader::DTD:
420 case QXmlStreamReader::EntityReference:
421 case QXmlStreamReader::ProcessingInstruction:
429 bool allRead =
false;
431 QXmlStreamReader::TokenType type = reader.readNext();
433 case QXmlStreamReader::StartElement:
436 QXmlStreamAttributes attribs = reader.attributes();
443 case QXmlStreamReader::EndElement:
449 case QXmlStreamReader::NoToken:
450 case QXmlStreamReader::Invalid:
451 case QXmlStreamReader::StartDocument:
452 case QXmlStreamReader::EndDocument:
453 case QXmlStreamReader::Characters:
454 case QXmlStreamReader::Comment:
455 case QXmlStreamReader::DTD:
456 case QXmlStreamReader::EntityReference:
457 case QXmlStreamReader::ProcessingInstruction:
465 bool allRead =
false;
467 QXmlStreamReader::TokenType type = reader.readNext();
469 case QXmlStreamReader::StartElement:
473 QXmlStreamAttributes attribs = reader.attributes();
480 case QXmlStreamReader::EndElement:
486 case QXmlStreamReader::NoToken:
487 case QXmlStreamReader::Invalid:
488 case QXmlStreamReader::StartDocument:
489 case QXmlStreamReader::EndDocument:
490 case QXmlStreamReader::Characters:
491 case QXmlStreamReader::Comment:
492 case QXmlStreamReader::DTD:
493 case QXmlStreamReader::EntityReference:
494 case QXmlStreamReader::ProcessingInstruction:
502 bool allRead =
false;
504 QXmlStreamReader::TokenType type = reader.readNext();
506 case QXmlStreamReader::StartElement:
509 QXmlStreamAttributes attribs = reader.attributes();
516 QXmlStreamAttributes attribs = reader.attributes();
523 case QXmlStreamReader::EndElement:
531 case QXmlStreamReader::NoToken:
532 case QXmlStreamReader::Invalid:
533 case QXmlStreamReader::StartDocument:
534 case QXmlStreamReader::EndDocument:
535 case QXmlStreamReader::Characters:
536 case QXmlStreamReader::Comment:
537 case QXmlStreamReader::DTD:
538 case QXmlStreamReader::EntityReference:
539 case QXmlStreamReader::ProcessingInstruction:
548 QXmlStreamReader::TokenType type = reader.readNext();
550 case QXmlStreamReader::StartElement:
554 type = reader.readNext();
555 if (type == QXmlStreamReader::Characters) {
556 config = reader.text().toString();
562 case QXmlStreamReader::EndElement:
568 case QXmlStreamReader::NoToken:
569 case QXmlStreamReader::Invalid:
570 case QXmlStreamReader::StartDocument:
571 case QXmlStreamReader::EndDocument:
572 case QXmlStreamReader::Characters:
573 case QXmlStreamReader::Comment:
574 case QXmlStreamReader::DTD:
575 case QXmlStreamReader::EntityReference:
576 case QXmlStreamReader::ProcessingInstruction:
585 const QXmlStreamReader::TokenType type = reader.readNext();
587 case QXmlStreamReader::Characters:
590 case QXmlStreamReader::EndElement:
593 case QXmlStreamReader::StartElement:
594 case QXmlStreamReader::NoToken:
595 case QXmlStreamReader::Invalid:
596 case QXmlStreamReader::StartDocument:
597 case QXmlStreamReader::EndDocument:
598 case QXmlStreamReader::Comment:
599 case QXmlStreamReader::DTD:
600 case QXmlStreamReader::EntityReference:
601 case QXmlStreamReader::ProcessingInstruction:
611 QXmlStreamReader::TokenType type = reader.readNext();
613 case QXmlStreamReader::StartElement:
617 if (reader.attributes().hasAttribute(QString(),
"fileName"))
618 suppression.
fileName = reader.attributes().value(QString(),
"fileName").toString().toStdString();
619 if (reader.attributes().hasAttribute(QString(),
"lineNumber"))
620 suppression.
lineNumber = reader.attributes().value(QString(),
"lineNumber").toInt();
621 if (reader.attributes().hasAttribute(QString(),
"symbolName"))
622 suppression.
symbolName = reader.attributes().value(QString(),
"symbolName").toString().toStdString();
623 if (reader.attributes().hasAttribute(QString(),
"hash"))
624 suppression.
hash = reader.attributes().value(QString(),
"hash").toULongLong();
625 type = reader.readNext();
626 if (type == QXmlStreamReader::Characters) {
627 suppression.
errorId = reader.text().toString().toStdString();
633 case QXmlStreamReader::EndElement:
639 case QXmlStreamReader::NoToken:
640 case QXmlStreamReader::Invalid:
641 case QXmlStreamReader::StartDocument:
642 case QXmlStreamReader::EndDocument:
643 case QXmlStreamReader::Characters:
644 case QXmlStreamReader::Comment:
645 case QXmlStreamReader::DTD:
646 case QXmlStreamReader::EntityReference:
647 case QXmlStreamReader::ProcessingInstruction:
657 QXmlStreamReader::TokenType type = reader.readNext();
659 case QXmlStreamReader::StartElement:
667 case QXmlStreamReader::EndElement:
673 case QXmlStreamReader::NoToken:
674 case QXmlStreamReader::Invalid:
675 case QXmlStreamReader::StartDocument:
676 case QXmlStreamReader::EndDocument:
677 case QXmlStreamReader::Characters:
678 case QXmlStreamReader::Comment:
679 case QXmlStreamReader::DTD:
680 case QXmlStreamReader::EntityReference:
681 case QXmlStreamReader::ProcessingInstruction:
690 bool allRead =
false;
692 QXmlStreamReader::TokenType type = reader.readNext();
694 case QXmlStreamReader::StartElement:
696 if (reader.name().toString() == elementname) {
697 type = reader.readNext();
698 if (type == QXmlStreamReader::Characters) {
699 QString text = reader.text().toString();
705 case QXmlStreamReader::EndElement:
706 if (reader.name().toString() != elementname)
711 case QXmlStreamReader::NoToken:
712 case QXmlStreamReader::Invalid:
713 case QXmlStreamReader::StartDocument:
714 case QXmlStreamReader::EndDocument:
715 case QXmlStreamReader::Characters:
716 case QXmlStreamReader::Comment:
717 case QXmlStreamReader::DTD:
718 case QXmlStreamReader::EntityReference:
719 case QXmlStreamReader::ProcessingInstruction:
762 const QRegularExpression re1(
"^[a-zA-Z0-9_\\-]+/.*");
763 const QRegularExpression re2(
"^[^/]+$");
764 QList<SuppressionList::Suppression> result;
766 if (re1.match(suppression.fileName.c_str()).hasMatch() || re2.match(suppression.fileName.c_str()).hasMatch()) {
767 if (suppression.fileName[0] !=
'*')
768 suppression.fileName = QFileInfo(
mFilename).absolutePath().toStdString() +
"/" + suppression.fileName;
770 result << suppression;
816 return (it !=
mWarningTags.end()) ? it->second : QString();
821 if (!filename.isEmpty())
825 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
828 QXmlStreamWriter xmlWriter(&file);
829 xmlWriter.setAutoFormatting(
true);
830 xmlWriter.writeStartDocument(
"1.0");
837 xmlWriter.writeEndElement();
843 xmlWriter.writeEndElement();
849 xmlWriter.writeEndElement();
855 xmlWriter.writeEndElement();
860 xmlWriter.writeEndElement();
864 xmlWriter.writeCharacters(
"clang");
865 xmlWriter.writeEndElement();
870 xmlWriter.writeEndElement();
874 xmlWriter.writeEndElement();
877 xmlWriter.writeCharacters(QString::number(
mMaxCtuDepth));
878 xmlWriter.writeEndElement();
882 xmlWriter.writeEndElement();
889 xmlWriter.writeEndElement();
891 xmlWriter.writeEndElement();
896 for (
const QString& define :
mDefines) {
899 xmlWriter.writeEndElement();
901 xmlWriter.writeEndElement();
918 for (
const QString& path :
mPaths) {
921 xmlWriter.writeEndElement();
923 xmlWriter.writeEndElement();
931 xmlWriter.writeEndElement();
933 xmlWriter.writeEndElement();
945 if (!suppression.fileName.empty())
946 xmlWriter.writeAttribute(
"fileName", QString::fromStdString(suppression.fileName));
947 if (suppression.lineNumber > 0)
948 xmlWriter.writeAttribute(
"lineNumber", QString::number(suppression.lineNumber));
949 if (!suppression.symbolName.empty())
950 xmlWriter.writeAttribute(
"symbolName", QString::fromStdString(suppression.symbolName));
951 if (suppression.hash > 0)
953 if (!suppression.errorId.empty())
954 xmlWriter.writeCharacters(QString::fromStdString(suppression.errorId));
955 xmlWriter.writeEndElement();
957 xmlWriter.writeEndElement();
986 if (!tags.contains(wt.second))
987 tags.append(wt.second);
989 for (
const QString &tag: tags) {
993 if (wt.second == tag) {
996 xmlWriter.writeEndElement();
999 xmlWriter.writeEndElement();
1005 xmlWriter.writeEndElement();
1011 xmlWriter.writeEndElement();
1022 xmlWriter.writeEndElement();
1028 xmlWriter.writeEndElement();
1031 xmlWriter.writeEndDocument();
1036 void ProjectFile::writeStringList(QXmlStreamWriter &xmlWriter,
const QStringList &stringlist,
const char startelementname[],
const char stringelementname[])
1038 if (stringlist.isEmpty())
1041 xmlWriter.writeStartElement(startelementname);
1042 for (
const QString& str : stringlist) {
1043 xmlWriter.writeStartElement(stringelementname);
1044 xmlWriter.writeCharacters(str);
1045 xmlWriter.writeEndElement();
1047 xmlWriter.writeEndElement();
1053 for (
const QString &path : paths)
1054 ret << QDir::fromNativeSeparators(path);
1075 const QXmlStreamReader::TokenType type = xmlReader.readNext();
1077 case QXmlStreamReader::StartElement:
1088 case QXmlStreamReader::EndElement:
1094 case QXmlStreamReader::Characters:
1095 case QXmlStreamReader::NoToken:
1096 case QXmlStreamReader::Invalid:
1097 case QXmlStreamReader::StartDocument:
1098 case QXmlStreamReader::EndDocument:
1099 case QXmlStreamReader::Comment:
1100 case QXmlStreamReader::DTD:
1101 case QXmlStreamReader::EntityReference:
1102 case QXmlStreamReader::ProcessingInstruction:
1110 if (!classes && !externalFunctions && !internalFunctions && !externalVariables)
1115 xmlWriter.writeEndElement();
1117 if (externalFunctions) {
1119 xmlWriter.writeEndElement();
1121 if (internalFunctions) {
1123 xmlWriter.writeEndElement();
1125 if (externalVariables) {
1127 xmlWriter.writeEndElement();
1129 xmlWriter.writeEndElement();
1134 if (QFile(addon).exists())
1137 if (!filesDir.endsWith(
"/"))
1140 QStringList searchPaths;
1141 searchPaths << filesDir << (filesDir +
"addons/") << (filesDir +
"../addons/")
1143 << (QLatin1String(FILESDIR) +
"/addons/")
1147 for (
const QString& path : searchPaths) {
1148 QString f = path + addon +
".py";
1149 if (QFile(f).exists())
void loadFromXml(QXmlStreamReader &xmlReader)
void saveToXml(QXmlStreamWriter &xmlWriter) const
A class that reads and writes project files.
std::map< std::size_t, QString > mWarningTags
Warning tags.
QStringList getAddonsAndTools() const
Get list of addons and tools.
bool mClangTidy
Execute clang-tidy?
bool clangParser
Use Clang parser.
static ProjectFile * mActiveProject
QList< SuppressionList::Suppression > getCheckingSuppressions() const
Get "checking" suppressions.
void setCheckPaths(const QStringList &paths)
Set list of paths to check.
void setCheckLevel(CheckLevel checkLevel)
CheckLevel: normal/exhaustive.
void readDefines(QXmlStreamReader &reader)
Read list of defines from XML.
bool isCheckLevelExhaustive() const
ProjectFile(QObject *parent=nullptr)
QString mFilename
Filename (+path) of the project file.
QList< SuppressionList::Suppression > mSuppressions
List of suppressions.
void readBuildDir(QXmlStreamReader &reader)
QStringList mExcludedPaths
Paths excluded from the check.
QStringList mVsConfigurations
Check only a selected VS configuration.
void readSuppressions(QXmlStreamReader &reader)
Read suppressions.
void readExcludes(QXmlStreamReader &reader)
Read lists of excluded paths.
static int readInt(QXmlStreamReader &reader, int defaultValue)
bool mCheckUnusedTemplates
Check code in unused templates.
QStringList mCheckUnknownFunctionReturn
void setExcludedPaths(const QStringList &paths)
Set list of paths to exclude from the check.
int mCertIntPrecision
Cppcheck Premium: This value is passed to the Cert C checker if that is enabled.
void setVSConfigurations(const QStringList &vsConfigs)
Set list of Visual Studio configurations to be checked.
QStringList mDefines
List of defines.
QString mImportProject
Visual studio project/solution , compile database.
QString mRootPath
Root path (optional) for the project.
QStringList mCodingStandards
List of coding standards, checked by Cppcheck Premium.
void setDefines(const QStringList &defines)
Set list of defines.
void readTagWarnings(QXmlStreamReader &reader, const QString &tag)
Read tag warnings, what warnings are tagged with a specific tag.
static bool readBool(QXmlStreamReader &reader)
QString mPlatform
Platform.
QString getWarningTags(std::size_t hash) const
Get tags for a warning.
static QStringList fromNativeSeparators(const QStringList &paths)
Convert paths.
void readCheckPaths(QXmlStreamReader &reader)
Read list paths to check.
static void writeStringList(QXmlStreamWriter &xmlWriter, const QStringList &stringlist, const char startelementname[], const char stringelementname[])
Write string list.
void setUndefines(const QStringList &undefines)
Set list of undefines.
bool mAnalyzeAllVsConfigs
Should all visual studio configurations be analyzed? If this is false then only the Debug configurati...
void setIncludes(const QStringList &includes)
Set list of includes.
static void readStringList(QStringList &stringlist, QXmlStreamReader &reader, const char elementname[])
Read string list.
void readVsConfigurations(QXmlStreamReader &reader)
Read lists of Visual Studio configurations.
QStringList mAddons
List of addons.
QStringList mUndefines
List of undefines.
void setWarningTags(std::size_t hash, const QString &tags)
Set tags for a warning.
void setLibraries(const QStringList &libraries)
Set list of libraries.
static QString getAddonFilePath(QString filesDir, const QString &addon)
Get path to addon python script.
bool read(const QString &filename=QString())
Read the project file.
void readIncludeDirs(QXmlStreamReader &reader)
Read list of include directories from XML.
QStringList mPaths
List of paths to check.
int mMaxTemplateRecursion
Max template instantiation recursion.
void setAddons(const QStringList &addons)
Set list of addons.
void setPlatform(const QString &platform)
Set platform.
void addSuppression(const SuppressionList::Suppression &suppression)
Add suppression.
void readRootPath(const QXmlStreamReader &reader)
Read optional root path from XML.
QString mBuildDir
Cppcheck build dir.
QStringList mIncludeDirs
List of include directories used to search include files.
void readPlatform(QXmlStreamReader &reader)
Read platform text.
int mMaxCtuDepth
Max CTU depth.
QStringList mLibraries
List of libraries.
bool mClangAnalyzer
Execute clang analyzer?
bool write(const QString &filename=QString())
Write project file (to disk).
static QString readString(QXmlStreamReader &reader)
void readImportProject(QXmlStreamReader &reader)
Read importproject from XML.
void setSuppressions(const QList< SuppressionList::Suppression > &suppressions)
Set list of suppressions.
bool mCheckHeaders
Check code in headers.
QString mProjectName
Project name, used when generating compliance report.
CheckLevel mCheckLevel
Should Cppcheck run normal or exhaustive analysis?
This is just a container for general settings so that we don't need to pass individual values to func...
int maxCtuDepth
–max-ctu-depth
int maxTemplateRecursion
max template recursion
std::string toString(Color c)
static constexpr char RootPathName[]
static constexpr char VSConfigurationName[]
static constexpr char DirElementName[]
static constexpr char DefineName[]
static constexpr char ExcludePathNameAttrib[]
static constexpr char PathsElementName[]
static constexpr char DefinesElementName[]
static constexpr char LibrariesElementName[]
static constexpr char ToolsElementName[]
static constexpr char IncludeDirElementName[]
static constexpr char ExcludeElementName[]
static constexpr char ProjectElementName[]
static constexpr char CertIntPrecisionElementName[]
static constexpr char PlatformElementName[]
static constexpr char TagsElementName[]
static constexpr char RootPathNameAttrib[]
static constexpr char CodingStandardElementName[]
static constexpr char IgnorePathNameAttrib[]
static constexpr char CodingStandardsElementName[]
static constexpr char AddonsElementName[]
static constexpr char UndefinesElementName[]
static constexpr char ImportProjectElementName[]
static constexpr char Parser[]
static constexpr char BughuntingElementName[]
static constexpr char AddonElementName[]
static constexpr char ProjectVersionAttrib[]
static constexpr char CheckUnknownFunctionReturn[]
static constexpr char TagWarningsElementName[]
static constexpr char TagAttributeName[]
static constexpr char WarningElementName[]
static constexpr char DefineNameAttrib[]
static constexpr char AnalyzeAllVsConfigsElementName[]
static constexpr char TagElementName[]
static constexpr char ProjectNameElementName[]
static constexpr char BuildDirElementName[]
static constexpr char MaxTemplateRecursionElementName[]
static constexpr char ExcludePathName[]
static constexpr char CheckUnusedTemplatesElementName[]
static constexpr char VSConfigurationElementName[]
static constexpr char CheckLevelExhaustiveElementName[]
static constexpr char DirNameAttrib[]
static constexpr char MaxCtuDepthElementName[]
static constexpr char UndefineName[]
static constexpr char HashAttributeName[]
static constexpr char SuppressionElementName[]
static constexpr char Name[]
static constexpr char IgnoreElementName[]
static constexpr char IgnorePathName[]
static constexpr char ProjectFileVersion[]
static constexpr char ToolElementName[]
static constexpr char SuppressionsElementName[]
static constexpr char CheckHeadersElementName[]
static constexpr char PathName[]
static constexpr char PathNameAttrib[]
static constexpr char LibraryElementName[]
bool classes
Public interface of classes.
static const char XmlExternalFunctions[]
static const char XmlInternalFunctions[]
bool externalVariables
Global variables that can be modified outside the TU.
static const char XmlClasses[]
static const char XmlRootName[]
static const char XmlExternalVariables[]
bool externalFunctions
External functions.
bool internalFunctions
Experimental: assume that internal functions can be used in any way This is only available in the GUI...
static const char * bool_to_string(bool b)