Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cppcheck for openSUSE:Factory checked in at 2023-03-07 16:50:19 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cppcheck (Old) and /work/SRC/openSUSE:Factory/.cppcheck.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cppcheck" Tue Mar 7 16:50:19 2023 rev:30 rq:1069760 version:2.10.2 Changes: -------- --- /work/SRC/openSUSE:Factory/cppcheck/cppcheck.changes 2023-02-01 16:43:24.607257144 +0100 +++ /work/SRC/openSUSE:Factory/.cppcheck.new.31432/cppcheck.changes 2023-03-07 16:50:47.649729766 +0100 @@ -1,0 +2,8 @@ +Mon Feb 27 21:39:54 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 2.10.2: + * GUI: Set proper title for compliance report dialog + * GUI: Generate compliance report + * Tokenizer: tweaked simplification of function pointers + +------------------------------------------------------------------- Old: ---- cppcheck-2.10.tar.gz New: ---- cppcheck-2.10.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cppcheck.spec ++++++ --- /var/tmp/diff_new_pack.zJFWbT/_old 2023-03-07 16:50:48.141732355 +0100 +++ /var/tmp/diff_new_pack.zJFWbT/_new 2023-03-07 16:50:48.149732397 +0100 @@ -17,7 +17,7 @@ Name: cppcheck -Version: 2.10 +Version: 2.10.2 Release: 0 Summary: A tool for static C/C++ code analysis License: GPL-3.0-or-later ++++++ cppcheck-2.10.tar.gz -> cppcheck-2.10.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/cli/main.cpp new/cppcheck-2.10.2/cli/main.cpp --- old/cppcheck-2.10/cli/main.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/cli/main.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -20,7 +20,7 @@ /** * * @mainpage Cppcheck - * @version 2.10 + * @version 2.10.1 * * @section overview_sec Overview * Cppcheck is a simple tool for static analysis of C/C++ code. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/cmake/versions.cmake new/cppcheck-2.10.2/cmake/versions.cmake --- old/cppcheck-2.10/cmake/versions.cmake 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/cmake/versions.cmake 2023-02-26 18:14:21.000000000 +0100 @@ -1,9 +1,10 @@ # Version for libraries CPP -SET(VERSION "2.10") +SET(VERSION "2.10.2") STRING(REGEX MATCHALL "[0-9]+" VERSION_PARTS "${VERSION}") LIST(GET VERSION_PARTS 0 VERSION_MAJOR) LIST(GET VERSION_PARTS 1 VERSION_MINOR) -SET(SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}") +LIST(GET VERSION_PARTS 2 VERSION_PATCH) +SET(SOVERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") # Postfix of so's: SET(DLLVERSION "") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/compliancereportdialog.cpp new/cppcheck-2.10.2/gui/compliancereportdialog.cpp --- old/cppcheck-2.10/gui/compliancereportdialog.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/cppcheck-2.10.2/gui/compliancereportdialog.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -0,0 +1,169 @@ +#include "compliancereportdialog.h" +#include "ui_compliancereportdialog.h" + +#include "filelist.h" +#include "projectfile.h" + +#include <QCryptographicHash> +#include <QFile> +#include <QFileDialog> +#include <QFileInfo> +#include <QMessageBox> +#include <QProcess> +#include <QRegularExpression> +#include <QSet> +#include <QTemporaryFile> +#include <QTextStream> + +static void addHeaders(const QString& file1, QSet<QString> &allFiles) { + if (allFiles.contains(file1)) + return; + QFile file(file1); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return; + allFiles << file1; + const QRegularExpression re("^#include[ ]*\"([^\">]+)\".*"); + QTextStream in(&file); + QString line = in.readLine(); + while (!in.atEnd()) { + if (line.startsWith("#include")) { + const QRegularExpressionMatch match = re.match(line); + if (match.hasMatch()) { + QString hfile = match.captured(1); + if (file1.contains("/")) + hfile = file1.mid(0,file1.lastIndexOf("/") + 1) + hfile; + addHeaders(hfile, allFiles); + } + } + line = in.readLine(); + } +} + +static std::vector<std::string> toStdStringList(const QStringList& from) { + std::vector<std::string> ret; + std::transform(from.cbegin(), from.cend(), std::back_inserter(ret), [](const QString& e) { + return e.toStdString(); + }); + return ret; +} + +ComplianceReportDialog::ComplianceReportDialog(ProjectFile* projectFile, QString resultsFile) : + QDialog(nullptr), + mUI(new Ui::ComplianceReportDialog), + mProjectFile(projectFile), + mResultsFile(std::move(resultsFile)) +{ + mUI->setupUi(this); + mUI->mEditProjectName->setText(projectFile->getProjectName()); + connect(mUI->buttonBox, &QDialogButtonBox::clicked, this, &ComplianceReportDialog::buttonClicked); +} + +ComplianceReportDialog::~ComplianceReportDialog() +{ + delete mUI; +} + +void ComplianceReportDialog::buttonClicked(QAbstractButton* button) +{ + switch (mUI->buttonBox->standardButton(button)) { + case QDialogButtonBox::StandardButton::Save: + save(); + break; + case QDialogButtonBox::StandardButton::Close: + close(); + break; + default: + break; + }; +} + +void ComplianceReportDialog::save() +{ + const QString outFile = QFileDialog::getSaveFileName(this, + tr("Compliance report"), + QDir::homePath() + "/misra-c-2012-compliance-report.html", + tr("HTML files (*.html)")); + if (outFile.isEmpty()) + return; + + close(); + + const QString& projectName = mUI->mEditProjectName->text(); + const QString& projectVersion = mUI->mEditProjectVersion->text(); + const bool files = mUI->mCheckFiles->isChecked(); + + if (projectName != mProjectFile->getProjectName()) { + mProjectFile->setProjectName(projectName); + mProjectFile->write(); + } + + QTemporaryFile tempFiles; + if (files && tempFiles.open()) { + QTextStream out(&tempFiles); + FileList fileList; + fileList.addPathList(mProjectFile->getCheckPaths()); + if (!mProjectFile->getImportProject().isEmpty()) { + QFileInfo inf(mProjectFile->getFilename()); + + QString prjfile; + if (QFileInfo(mProjectFile->getImportProject()).isAbsolute()) + prjfile = mProjectFile->getImportProject(); + else + prjfile = inf.canonicalPath() + '/' + mProjectFile->getImportProject(); + + ImportProject p; + try { + p.import(prjfile.toStdString()); + } catch (InternalError &e) { + QMessageBox msg(QMessageBox::Critical, + tr("Save compliance report"), + tr("Failed to import '%1', can not show files in compliance report").arg(prjfile), + QMessageBox::Ok, + this); + msg.exec(); + return; + } + + p.ignorePaths(toStdStringList(mProjectFile->getExcludedPaths())); + + QDir dir(inf.absoluteDir()); + for (const ImportProject::FileSettings& fs: p.fileSettings) + fileList.addFile(dir.relativeFilePath(QString::fromStdString(fs.filename))); + } + + QSet<QString> allFiles; + for (const QString &sourcefile: fileList.getFileList()) + addHeaders(sourcefile, allFiles); + for (const QString& fileName: allFiles) { + QFile f(fileName); + if (f.open(QFile::ReadOnly)) { + QCryptographicHash hash(QCryptographicHash::Algorithm::Md5); + if (hash.addData(&f)) { + for (auto b: hash.result()) + out << QString::number((unsigned char)b,16); + out << " " << fileName << "\n"; + } + } + } + tempFiles.close(); + } + + QStringList args{"--compliant=misra-c2012-1.1", + "--compliant=misra-c2012-1.2", + "--project-name=" + projectName, + "--project-version=" + projectVersion, + "--output-file=" + outFile}; + if (files) + args << "--files=" + tempFiles.fileName(); + args << mResultsFile; + + const QString appPath = QFileInfo(QCoreApplication::applicationFilePath()).canonicalPath(); + + QProcess process; +#ifdef Q_OS_WIN + process.start(appPath + "/compliance-report.exe", args); +#else + process.start(appPath + "/compliance-report", args); +#endif + process.waitForFinished(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/compliancereportdialog.h new/cppcheck-2.10.2/gui/compliancereportdialog.h --- old/cppcheck-2.10/gui/compliancereportdialog.h 1970-01-01 01:00:00.000000000 +0100 +++ new/cppcheck-2.10.2/gui/compliancereportdialog.h 2023-02-26 18:14:21.000000000 +0100 @@ -0,0 +1,32 @@ +#ifndef COMPLIANCEREPORTDIALOG_H +#define COMPLIANCEREPORTDIALOG_H + +#include <QDialog> + +namespace Ui { + class ComplianceReportDialog; +} + +class ProjectFile; +class QAbstractButton; + +class ComplianceReportDialog final : public QDialog +{ + Q_OBJECT + +public: + explicit ComplianceReportDialog(ProjectFile* projectFile, QString resultsFile); + ~ComplianceReportDialog() final; + +private slots: + void buttonClicked(QAbstractButton* button); + +private: + void save(); + + Ui::ComplianceReportDialog *mUI; + ProjectFile* mProjectFile; + QString mResultsFile; +}; + +#endif // COMPLIANCEREPORTDIALOG_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/compliancereportdialog.ui new/cppcheck-2.10.2/gui/compliancereportdialog.ui --- old/cppcheck-2.10/gui/compliancereportdialog.ui 1970-01-01 01:00:00.000000000 +0100 +++ new/cppcheck-2.10.2/gui/compliancereportdialog.ui 2023-02-26 18:14:21.000000000 +0100 @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ComplianceReportDialog</class> + <widget class="QDialog" name="ComplianceReportDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>403</width> + <height>199</height> + </rect> + </property> + <property name="windowTitle"> + <string>Compliance Report</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Project name</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="mEditProjectName"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Project version</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="mEditProjectVersion"/> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="mCheckFiles"> + <property name="text"> + <string>List of files with md5 checksums</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close|QDialogButtonBox::Save</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/gui.pro new/cppcheck-2.10.2/gui/gui.pro --- old/cppcheck-2.10/gui/gui.pro 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/gui/gui.pro 2023-02-26 18:14:21.000000000 +0100 @@ -63,6 +63,7 @@ RESOURCES = gui.qrc FORMS = about.ui \ applicationdialog.ui \ + compliancereportdialog.ui \ fileview.ui \ helpdialog.ui \ mainwindow.ui \ @@ -122,6 +123,7 @@ codeeditstyledialog.h \ codeeditor.h \ common.h \ + compliancereportdialog.h \ csvreport.h \ erroritem.h \ filelist.h \ @@ -162,6 +164,7 @@ codeeditstyledialog.cpp \ codeeditor.cpp \ common.cpp \ + compliancereportdialog.cpp \ csvreport.cpp \ erroritem.cpp \ filelist.cpp \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/mainwindow.cpp new/cppcheck-2.10.2/gui/mainwindow.cpp --- old/cppcheck-2.10/gui/mainwindow.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/gui/mainwindow.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -25,6 +25,7 @@ #include "cppcheck.h" #include "errortypes.h" #include "filelist.h" +#include "compliancereportdialog.h" #include "fileviewdialog.h" #include "helpdialog.h" #include "importproject.h" @@ -68,6 +69,7 @@ #include <QTimer> #include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkReply> +#include <QTemporaryFile> static const QString OnlineHelpURL("https://cppcheck.sourceforge.io/manual.html"); static const QString compile_commands_json("compile_commands.json"); @@ -154,6 +156,7 @@ connect(mUI->mActionStop, &QAction::triggered, this, &MainWindow::stopAnalysis); connect(mUI->mActionSave, &QAction::triggered, this, &MainWindow::save); + connect(mUI->mActionComplianceReport, &QAction::triggered, this, &MainWindow::complianceReport); // About menu connect(mUI->mActionAbout, &QAction::triggered, this, &MainWindow::about); @@ -191,6 +194,8 @@ else formatAndSetTitle(); + mUI->mActionComplianceReport->setVisible(isCppcheckPremium()); + enableCheckButtons(true); mUI->mActionPrint->setShortcut(QKeySequence::Print); @@ -1290,6 +1295,10 @@ } mUI->mActionAnalyzeDirectory->setEnabled(enable); + + if (isCppcheckPremium()) { + mUI->mActionComplianceReport->setEnabled(enable && mProjectFile && mProjectFile->getAddons().contains("misra")); + } } void MainWindow::enableResultsButtons() @@ -1459,6 +1468,20 @@ } } +void MainWindow::complianceReport() +{ + if (isCppcheckPremium() && mProjectFile && mProjectFile->getAddons().contains("misra")) { + QTemporaryFile tempResults; + tempResults.open(); + tempResults.close(); + + mUI->mResults->save(tempResults.fileName(), Report::XMLV2); + + ComplianceReportDialog dlg(mProjectFile, tempResults.fileName()); + dlg.exec(); + } +} + void MainWindow::resultsAdded() {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/mainwindow.h new/cppcheck-2.10.2/gui/mainwindow.h --- old/cppcheck-2.10/gui/mainwindow.h 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/gui/mainwindow.h 2023-02-26 18:14:21.000000000 +0100 @@ -168,6 +168,9 @@ /** @brief Slot to save results */ void save(); + /** @brief Slot to generate compliance report */ + void complianceReport(); + /** @brief Slot to create new project file */ void newProjectFile(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/mainwindow.ui new/cppcheck-2.10.2/gui/mainwindow.ui --- old/cppcheck-2.10/gui/mainwindow.ui 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/gui/mainwindow.ui 2023-02-26 18:14:21.000000000 +0100 @@ -140,6 +140,7 @@ <addaction name="separator"/> <addaction name="mActionProjectMRU"/> <addaction name="mActionSave"/> + <addaction name="mActionComplianceReport"/> <addaction name="separator"/> <addaction name="mActionPrintPreview"/> <addaction name="mActionPrint"/> @@ -914,6 +915,11 @@ <string>C++23</string> </property> </action--> + <action name="mActionComplianceReport"> + <property name="text"> + <string>Compliance report...</string> + </property> + </action> </widget> <customwidgets> <customwidget> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/projectfile.cpp new/cppcheck-2.10.2/gui/projectfile.cpp --- old/cppcheck-2.10/gui/projectfile.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/gui/projectfile.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -61,6 +61,7 @@ mExcludedPaths.clear(); mLibraries.clear(); mPlatform.clear(); + mProjectName.clear(); mSuppressions.clear(); mAddons.clear(); mClangAnalyzer = mClangTidy = false; @@ -208,6 +209,8 @@ readStringList(mCodingStandards, xmlReader, CppcheckXml::CodingStandardElementName); if (xmlReader.name() == QString(CppcheckXml::CertIntPrecisionElementName)) mCertIntPrecision = readInt(xmlReader, 0); + if (xmlReader.name() == QString(CppcheckXml::ProjectNameElementName)) + mProjectName = readString(xmlReader); break; @@ -346,6 +349,32 @@ } while (true); } +QString ProjectFile::readString(QXmlStreamReader &reader) +{ + QString ret; + do { + const QXmlStreamReader::TokenType type = reader.readNext(); + switch (type) { + case QXmlStreamReader::Characters: + ret = reader.text().toString(); + FALLTHROUGH; + case QXmlStreamReader::EndElement: + 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 (true); +} + void ProjectFile::readIncludeDirs(QXmlStreamReader &reader) { QXmlStreamReader::TokenType type; @@ -959,6 +988,12 @@ xmlWriter.writeEndElement(); } + if (!mProjectName.isEmpty()) { + xmlWriter.writeStartElement(CppcheckXml::ProjectNameElementName); + xmlWriter.writeCharacters(mProjectName); + xmlWriter.writeEndElement(); + } + xmlWriter.writeEndDocument(); file.close(); return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/gui/projectfile.h new/cppcheck-2.10.2/gui/projectfile.h --- old/cppcheck-2.10/gui/projectfile.h 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/gui/projectfile.h 2023-02-26 18:14:21.000000000 +0100 @@ -165,6 +165,14 @@ return mPlatform; } + QString getProjectName() const { + return mProjectName; + } + + void setProjectName(QString projectName) { + mProjectName = std::move(projectName); + } + /** * @brief Get "raw" suppressions. * @return list of suppressions. @@ -420,6 +428,8 @@ static int readInt(QXmlStreamReader &reader, int defaultValue); + static QString readString(QXmlStreamReader &reader); + /** * @brief Read list of include directories from XML. * @param reader XML stream reader. @@ -581,6 +591,9 @@ */ QStringList mCodingStandards; + /** @brief Project name, used when generating compliance report */ + QString mProjectName; + int mCertIntPrecision; /** @brief Execute clang analyzer? */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/lib/checkunusedvar.cpp new/cppcheck-2.10.2/lib/checkunusedvar.cpp --- old/cppcheck-2.10/lib/checkunusedvar.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/lib/checkunusedvar.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -1181,6 +1181,8 @@ const Token * eq = tok->next(); while (Token::simpleMatch(eq, "[")) eq = eq->link()->next(); + if (Token::simpleMatch(eq, ") (") && Token::simpleMatch(eq->linkAt(1), ") =")) + eq = eq->linkAt(1)->next(); if (Token::simpleMatch(eq, "=")) { varDecl = tok; tok = eq; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/lib/importproject.h new/cppcheck-2.10.2/lib/importproject.h --- old/cppcheck-2.10/lib/importproject.h 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/lib/importproject.h 2023-02-26 18:14:21.000000000 +0100 @@ -184,6 +184,7 @@ const char CodingStandardsElementName[] = "coding-standards"; const char CodingStandardElementName[] = "coding-standard"; const char CertIntPrecisionElementName[] = "cert-c-int-precision"; + const char ProjectNameElementName[] = "project-name"; } /// @} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/lib/tokenize.cpp new/cppcheck-2.10.2/lib/tokenize.cpp --- old/cppcheck-2.10/lib/tokenize.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/lib/tokenize.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -6171,20 +6171,26 @@ endTok->deleteNext(); // ok simplify this function pointer to an ordinary pointer - Token::eraseTokens(tok->link(), endTok->next()); if (Token::simpleMatch(tok->link()->previous(), ") )")) { // Function returning function pointer // void (*dostuff(void))(void) {} + Token::eraseTokens(tok->link(), endTok->next()); tok->link()->deleteThis(); tok->deleteThis(); } else { - // Function pointer variable - // void (*p)(void) {} - tok->link()->insertToken("("); - Token *par1 = tok->link()->next(); - par1->insertToken(")"); - par1->link(par1->next()); - par1->next()->link(par1); + Token::eraseTokens(tok->link()->linkAt(1), endTok->next()); + + // remove variable names + for (Token* tok3 = tok->link()->tokAt(2); Token::Match(tok3, "%name%|*|&|[|(|::|,|<"); tok3 = tok3->next()) { + if (tok3->str() == "<" && tok3->link()) + tok3 = tok3->link(); + else if (Token::Match(tok3, "[|(")) + tok3 = tok3->link(); + if (Token::Match(tok3, "%type%|*|&|> %name% [,)[]")) + tok3->deleteNext(); + } + + // TODO Keep this info while (Token::Match(tok, "( %type% ::")) tok->deleteNext(2); } @@ -6422,8 +6428,10 @@ varName = varName->next(); } // Function pointer - if (Token::simpleMatch(varName, "( *") && Token::Match(varName->link()->previous(), "%name% ) ( ) =")) { - Token *endDecl = varName->link()->tokAt(2); + if (Token::simpleMatch(varName, "( *") && + Token::Match(varName->link()->previous(), "%name% ) (") && + Token::simpleMatch(varName->link()->linkAt(1), ") =")) { + Token *endDecl = varName->link()->linkAt(1); varName = varName->link()->previous(); endDecl->insertToken(";"); endDecl = endDecl->next(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/lib/version.h new/cppcheck-2.10.2/lib/version.h --- old/cppcheck-2.10/lib/version.h 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/lib/version.h 2023-02-26 18:14:21.000000000 +0100 @@ -4,12 +4,13 @@ #define CPPCHECK_MAJOR 2 #define CPPCHECK_MINOR 10 #define CPPCHECK_DEVMINOR 10 +#define CPPCHECK_PATCH 2 #define STRINGIFY(x) STRING(x) #define STRING(VER) #VER #if CPPCHECK_MINOR == CPPCHECK_DEVMINOR -#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR) -#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,0,0 +#define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_MINOR) "." STRINGIFY(CPPCHECK_PATCH) +#define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,CPPCHECK_PATCH,0 #else #define CPPCHECK_VERSION_STRING STRINGIFY(CPPCHECK_MAJOR) "." STRINGIFY(CPPCHECK_DEVMINOR) " dev" #define CPPCHECK_VERSION CPPCHECK_MAJOR,CPPCHECK_MINOR,99,0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/test/testsimplifytypedef.cpp new/cppcheck-2.10.2/test/testsimplifytypedef.cpp --- old/cppcheck-2.10/test/testsimplifytypedef.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/test/testsimplifytypedef.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -779,8 +779,8 @@ "void addCallback1(Callback callback, int j) { }"; const char expected[] = - "void addCallback ( bool ( * callback ) ( ) ) { } " - "void addCallback1 ( bool ( * callback ) ( ) , int j ) { }"; + "void addCallback ( bool ( * callback ) ( int ) ) { } " + "void addCallback1 ( bool ( * callback ) ( int ) , int j ) { }"; ASSERT_EQUALS(expected, tok(code, false)); } @@ -1132,7 +1132,7 @@ "class X { } ; " "int main ( ) " "{ " - "X ( * * Foo ) ( ) ; Foo = new X ( * ) ( const X & ) [ 2 ] ; " + "X ( * * Foo ) ( const X & ) ; Foo = new X ( * ) ( const X & ) [ 2 ] ; " "}"; ASSERT_EQUALS(expected, tok(code, false)); @@ -1606,7 +1606,7 @@ " localEntitiyAddFunc_t f;\n" "}"; // The expected result.. - const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean ( * f ) ( ) ; }"; + const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean ( * f ) ( struct le_s * , entity_t * ) ; }"; ASSERT_EQUALS(expected, tok(code, false)); ASSERT_EQUALS("", errout.str()); } @@ -2174,7 +2174,7 @@ "};"; const char expected[] = "class symbol_table { " "public: " - "expression_error :: error_code ( * f ) ( ) ; " + "expression_error :: error_code ( * f ) ( void * , const char * , expression_space ) ; " "} ;"; ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false)); ASSERT_EQUALS("", errout.str()); @@ -3518,14 +3518,14 @@ "type12 t12;"; // The expected result.. - const char expected[] = "int ( * t1 ) ( ) ; " - "int ( * const t2 ) ( ) ; " - "int ( * volatile t3 ) ( ) ; " - "int ( * const volatile t4 ) ( ) ; " - "int ( * t5 ) ( ) ; " - "int ( * const t6 ) ( ) ; " - "int ( * volatile t7 ) ( ) ; " - "int ( * const volatile t8 ) ( ) ; " + const char expected[] = "int ( * t1 ) ( float ) ; " + "int ( * const t2 ) ( float ) ; " + "int ( * volatile t3 ) ( float ) ; " + "int ( * const volatile t4 ) ( float ) ; " + "int ( * t5 ) ( float ) ; " + "int ( * const t6 ) ( float ) ; " + "int ( * volatile t7 ) ( float ) ; " + "int ( * const volatile t8 ) ( float ) ; " "int ( :: C :: * t9 ) ( float ) ; " "int ( :: C :: * const t10 ) ( float ) ; " "int ( :: C :: * volatile t11 ) ( float ) ; " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/test/testtokenize.cpp new/cppcheck-2.10.2/test/testtokenize.cpp --- old/cppcheck-2.10/test/testtokenize.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/test/testtokenize.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -224,6 +224,7 @@ TEST_CASE(vardecl28); TEST_CASE(vardecl29); // #9282 TEST_CASE(vardecl30); + TEST_CASE(vardecl31); // function pointer init TEST_CASE(vardecl_stl_1); TEST_CASE(vardecl_stl_2); TEST_CASE(vardecl_stl_3); @@ -2527,6 +2528,14 @@ tokenizeAndStringify(code, true, Settings::Native, "test.c")); } + void vardecl31() { + const char code1[] = "void foo() { int (*fptr)() = 0; }"; + ASSERT_EQUALS("void foo ( ) { int ( * fptr ) ( ) ; fptr = 0 ; }", tokenizeAndStringify(code1)); + + const char code2[] = "void foo() { int (*fptr)(int) = 0; }"; + ASSERT_EQUALS("void foo ( ) { int ( * fptr ) ( int ) ; fptr = 0 ; }", tokenizeAndStringify(code2)); + } + void volatile_variables() { { const char code[] = "volatile int a=0;\n" @@ -3561,7 +3570,7 @@ ASSERT_EQUALS("unsigned int ( * f ) ( ) ;", tokenizeAndStringify("unsigned int (*f)();")); ASSERT_EQUALS("unsigned int * ( * f ) ( ) ;", tokenizeAndStringify("unsigned int * (*f)();")); ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", tokenizeAndStringify("void (*f[2])();")); - TODO_ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", "void ( * f ) ( ) [ 2 ] ;", tokenizeAndStringify("typedef void func_t(void); func_t *f[2];")); + TODO_ASSERT_EQUALS("void ( * f [ 2 ] ) ( ) ;", "void ( * f ) ( void ) [ 2 ] ;", tokenizeAndStringify("typedef void func_t(void); func_t *f[2];")); } void simplifyFunctionPointers2() { @@ -3602,7 +3611,7 @@ void simplifyFunctionPointers5() { const char code[] = ";void (*fp[])(int a) = {0,0,0};"; - const char expected[] = "1: ; void ( * fp@1 [ ] ) ( ) = { 0 , 0 , 0 } ;\n"; // TODO: Array dimension + const char expected[] = "1: ; void ( * fp@1 [ ] ) ( int ) = { 0 , 0 , 0 } ;\n"; // TODO: Array dimension ASSERT_EQUALS(expected, tokenizeDebugListing(code)); } @@ -3713,7 +3722,7 @@ void functionAttributeBefore3() { // #10978 const char code[] = "void __attribute__((__noreturn__)) (*func_notret)(void);"; - const char expected[] = "void ( * func_notret ) ( ) ;"; + const char expected[] = "void ( * func_notret ) ( void ) ;"; errout.str(""); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/test/testvarid.cpp new/cppcheck-2.10.2/test/testvarid.cpp --- old/cppcheck-2.10/test/testvarid.cpp 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/test/testvarid.cpp 2023-02-26 18:14:21.000000000 +0100 @@ -190,6 +190,7 @@ TEST_CASE(varid_not); // #9689 'not x' TEST_CASE(varid_declInIfCondition); TEST_CASE(varid_globalScope); + TEST_CASE(varid_function_pointer_args); TEST_CASE(varidclass1); TEST_CASE(varidclass2); @@ -2980,6 +2981,17 @@ ASSERT_EQUALS(exp1, tokenize(code1)); } + void varid_function_pointer_args() { + const char code[] = "void foo() {\n" + " char *text;\n" + " void (*cb)(char* text);\n" + "}\n"; + ASSERT_EQUALS("1: void foo ( ) {\n" + "2: char * text@1 ;\n" + "3: void ( * cb@2 ) ( char * ) ;\n" + "4: }\n", tokenize(code)); + } + void varidclass1() { const std::string actual = tokenize( "class Fred\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cppcheck-2.10/win_installer/productInfo.wxi new/cppcheck-2.10.2/win_installer/productInfo.wxi --- old/cppcheck-2.10/win_installer/productInfo.wxi 2023-01-28 10:42:04.000000000 +0100 +++ new/cppcheck-2.10.2/win_installer/productInfo.wxi 2023-02-26 18:14:21.000000000 +0100 @@ -2,7 +2,7 @@ <Include> <?define ProductName = "Cppcheck $(var.Platform) 2.10 dev" ?> <?define ProductNameShort = "Cppcheck" ?> - <?define ProductVersion = "2.10" ?> + <?define ProductVersion = "2.10.1" ?> <?define ProductManufacturer = "The Cppcheck team" ?> <?define ProductDescription = "Cppcheck is a tool for static analysis of C/C++ code" ?>