misra: the user must provide the rule texts in text file.

This commit is contained in:
Daniel Marjamäki 2018-03-24 13:28:40 +01:00
parent e65a5529ad
commit 588ec80122
5 changed files with 74 additions and 41 deletions

View File

@ -5,7 +5,6 @@
# Example usage of this addon (scan a sourcefile main.cpp)
# cppcheck --dump main.cpp
# python misra.py --rule-texts=<path-to-rule-texts> main.cpp.dump
# python misra.py --misra-pdf=<path-to-misra.pdf> main.cpp.dump
#
# Limitations: This addon is released as open source. Rule texts can't be freely
# distributed. https://www.misra.org.uk/forum/viewtopic.php?f=56&t=1189
@ -36,8 +35,10 @@ def reportError(location, num1, num2):
id = 'misra-c2012-' + str(num1) + '.' + str(num2)
if num in ruleTexts:
errmsg = ruleTexts[num] + ' [' + id + ']'
elif len(ruleTexts) == 0:
errmsg = 'misra violation (use --rule-texts=<file> to get proper output) [' + id + ']'
else:
errmsg = 'misra violation (use --misra-pdf=<file> or --rule-texts=<file> to get proper output) [' + id + ']'
return
sys.stderr.write('[' + location.file + ':' + str(location.linenr) + '] (style): ' + errmsg + '\n')
@ -1106,24 +1107,6 @@ def loadRuleTexts(filename):
ruleTexts[num] = ruleTexts[num] + ' ' + line
continue
def loadRuleTextsFromPdf(filename):
if not os.path.isfile(filename):
print('Fatal error: PDF file is not found: ' + filename)
sys.exit(1)
f = tempfile.NamedTemporaryFile(delete=False)
f.close()
#print('tempfile:' + f.name)
try:
subprocess.call(['pdftotext', filename, f.name])
except OSError as err:
print('Fatal error: Failed to execute pdftotext: ' + str(err))
sys.exit(1)
loadRuleTexts(f.name)
try:
os.remove(f.name)
except OSError as err:
print('Failed to remove temporary file ' + f.name)
if len(sys.argv) == 1:
print("""
Syntax: misra.py [OPTIONS] <dumpfiles>
@ -1132,33 +1115,25 @@ OPTIONS:
--rule-texts=<file> Load rule texts from plain text file.
If you have the tool 'pdftotext' you can generate
this textfile with such command:
If you have the tool 'pdftotext' you might be able
to generate this textfile with such command:
$ pdftotext MISRA_C_2012.pdf MISRA_C_2012.txt
Otherwise you can more or less copy/paste the chapter
Appendix A Summary of guidelines
from the MISRA pdf.
from the MISRA pdf. You can buy the MISRA pdf from
http://www.misra.org.uk/
Format:
<..arbitrary text..>
Appendix A Summary of guidelines
Dir 1.1
Rule 1.1
Rule text for 1.1
Dir 1.2
Rule 1.2
Rule text for 1.2
<...>
--misra-pdf=<file> Misra PDF file that rule texts will be extracted from.
The tool 'pdftotext' from xpdf is used and must be installed.
Debian: sudo apt-get install xpdf
Windows: http://gnuwin32.sourceforge.net/packages/xpdf.htm
If you don't have 'pdftotext' and don't want to install it then
you can use --rule-texts=<file>.
""")
sys.exit(1)
@ -1171,8 +1146,6 @@ for arg in sys.argv[1:]:
print('Fatal error: file is not found: ' + filename)
sys.exit(1)
loadRuleTexts(filename)
elif arg.startswith('--misra-pdf='):
loadRuleTextsFromPdf(arg[12:])
elif ".dump" in arg:
continue
else:

View File

@ -152,6 +152,7 @@ ProjectFileDialog::ProjectFileDialog(ProjectFile *projectFile, QWidget *parent)
connect(mUI.mBtnIncludeDown, &QPushButton::clicked, this, &ProjectFileDialog::moveIncludePathDown);
connect(mUI.mBtnAddSuppression, &QPushButton::clicked, this, &ProjectFileDialog::addSuppression);
connect(mUI.mBtnRemoveSuppression, &QPushButton::clicked, this, &ProjectFileDialog::removeSuppression);
connect(mUI.mBtnBrowseMisraFile, &QPushButton::clicked, this, &ProjectFileDialog::browseMisraFile);
loadFromProjectFile(projectFile);
}
@ -177,7 +178,8 @@ void ProjectFileDialog::saveSettings() const
static void updateAddonCheckBox(QCheckBox *cb, const ProjectFile *projectFile, const QString &dataDir, const QString &addon)
{
cb->setChecked(projectFile->getAddons().contains(addon));
if (projectFile)
cb->setChecked(projectFile->getAddons().contains(addon));
if (CheckThread::getAddonFilePath(dataDir, addon + ".py").isEmpty()) {
cb->setEnabled(false);
cb->setText(cb->text() + QObject::tr(" (Not found)"));
@ -231,6 +233,16 @@ void ProjectFileDialog::loadFromProjectFile(const ProjectFile *projectFile)
updateAddonCheckBox(mUI.mAddonCert, projectFile, dataDir, "cert");
updateAddonCheckBox(mUI.mAddonMisra, projectFile, dataDir, "misra");
const QString &misraFile = settings.value(SETTINGS_MISRA_FILE, QString()).toString();
mUI.mEditMisraFile->setText(misraFile);
if (!mUI.mAddonMisra->isEnabled()) {
mUI.mEditMisraFile->setEnabled(false);
mUI.mBtnBrowseMisraFile->setEnabled(false);
} else if (misraFile.isEmpty()) {
mUI.mAddonMisra->setEnabled(false);
mUI.mAddonMisra->setText(mUI.mAddonMisra->text() + ' ' + tr("(no rule texts file)"));
}
mUI.mToolClangAnalyzer->setChecked(projectFile->getClangAnalyzer());
mUI.mToolClangTidy->setChecked(projectFile->getClangTidy());
if (CheckThread::clangTidyCmd().isEmpty()) {
@ -658,3 +670,17 @@ void ProjectFileDialog::removeSuppression()
QListWidgetItem *item = mUI.mListSuppressions->takeItem(row);
delete item;
}
void ProjectFileDialog::browseMisraFile()
{
const QString fileName = QFileDialog::getOpenFileName(this, tr("Select MISRA rule texts file"), QDir::homePath(), tr("Misra rule texts file (%1)").arg("*.txt"));
if (!fileName.isEmpty()) {
QSettings settings;
mUI.mEditMisraFile->setText(fileName);
settings.setValue(SETTINGS_MISRA_FILE, fileName);
mUI.mAddonMisra->setText("MISRA C 2012");
mUI.mAddonMisra->setEnabled(true);
updateAddonCheckBox(mUI.mAddonMisra, nullptr, settings.value("DATADIR", QString()).toString(), "misra");
}
}

View File

@ -230,6 +230,11 @@ protected slots:
*/
void removeSuppression();
/**
* @brief Browse for misra file
*/
void browseMisraFile();
protected:
/**

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>642</width>
<height>507</height>
<height>549</height>
</rect>
</property>
<property name="windowTitle">
@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<widget class="QWidget" name="mTabPathsAndDefines">
<attribute name="title">
@ -524,6 +524,31 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Misra rule texts</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mEditMisraFile">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Copy/paste the text from Appendix A &amp;quot;Summary of guidelines&amp;quot; from the MISRA C 2012 pdf to a text file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mBtnBrowseMisraFile">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@ -317,12 +317,16 @@
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Misra PDF/Text file</string>
<string>Misra rule texts file</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="mEditMisraFile"/>
<widget class="QLineEdit" name="mEditMisraFile">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Copy/paste the text from Appendix A &amp;quot;Summary of guidelines&amp;quot; from the MISRA C 2012 pdf to a text file.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mBtnBrowseMisraFile">