Skip to content

Commit

Permalink
Merge branch 'danmar:main' into chr_Fix8235
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored May 11, 2024
2 parents 6cf4be9 + 1943b4d commit d2f4535
Show file tree
Hide file tree
Showing 19 changed files with 95 additions and 89 deletions.
21 changes: 17 additions & 4 deletions .github/workflows/scriptcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12']
python-version: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12']
include:
- python-version: '3.12'
python-latest: true
Expand Down Expand Up @@ -143,10 +143,23 @@ jobs:
env:
PYTHONPATH: ./addons

- name: test htmlreport
- name: test htmlreport (standalone)
run: |
htmlreport/test_htmlreport.py
cd htmlreport
test/tools/htmlreport/test_htmlreport.py
cd test/tools/htmlreport
./check.sh
# Python 3.5 and 3.6 are excluded as they are not supported by setuptools-scm package for getting
# package version
- name: test htmlreport (pip)
if: matrix.python-version != '3.5' && matrix.python-version != '3.6'
run: |
python -m venv venv
source venv/bin/activate
python -m pip install -U pip
pip install ./htmlreport/
which cppcheck-htmlreport
PIP_PACKAGE_TEST=1 test/tools/htmlreport/test_htmlreport.py
cd test/tools/htmlreport
./check.sh
- name: test reduce
Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,11 @@ compile_commands.json
/oss-fuzz/corpus
/oss-fuzz/corpus_
/oss-fuzz/samples

# Python
/.venv/
/venv/
**/*.egg-info/

# cppcheck-htmlreport auto files
/htmlreport/cppcheck_htmlreport/run.py
6 changes: 5 additions & 1 deletion htmlreport/cppcheck-htmlreport
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ class CppCheckHandler(XmlContentHandler):
'info': attributes.get('info')
})

if __name__ == '__main__':
def main() -> None:
# Configure all the options this little utility is using.
parser = optparse.OptionParser()
parser.add_option('--title', dest='title',
Expand Down Expand Up @@ -984,3 +984,7 @@ if __name__ == '__main__':
stats_file.write(HTML_FOOTER % contentHandler.versionCppcheck)

print("\nOpen '" + options.report_dir + "/index.html' to see the results.")


if __name__ == "__main__":
main()
Empty file.
38 changes: 24 additions & 14 deletions htmlreport/setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
#!/usr/bin/env python3
import shutil
from setuptools import find_packages, setup

from setuptools import setup

with open('README.txt') as f:
with open("README.txt") as f:
readme = f.read()

shutil.copy("cppcheck-htmlreport", "cppcheck_htmlreport/run.py")

setup(
name="cppcheck",
description='Python script to parse the XML (version 2) output of ' +
'cppcheck and generate an HTML report using Pygments for syntax ' +
'highlighting.',
name="cppcheck-htmlreport",
description=(
"Python script to parse the XML (version 2) output of "
"cppcheck and generate an HTML report using Pygments for syntax "
"highlighting."
),
long_description=readme,
author='Henrik Nilsson',
url='https://github.com/danmar/cppcheck',
license='GPL',
scripts=[
"cppcheck-htmlreport",
],
install_requires=['Pygments']
author="Cppcheck Team",
url="https://github.com/danmar/cppcheck",
license="GPL",
packages=find_packages(exclude=("tests", "docs")),
use_scm_version={"root": ".."},
entry_points={
"console_scripts": [
"cppcheck-htmlreport = cppcheck_htmlreport:run.main",
]
},
install_requires=["Pygments"],
# Required by setuptools-scm 7.0 for Python 3.7+
setup_requires=["setuptools>=60", "setuptools-scm>=7.0"],
)
3 changes: 0 additions & 3 deletions htmlreport/test_suppressions.txt

This file was deleted.

12 changes: 0 additions & 12 deletions htmlreport/tox.ini

This file was deleted.

2 changes: 0 additions & 2 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,8 +1684,6 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se
return false;
} else {
const Token * ftok = tok1;
if (Token::simpleMatch(tok1->previous(), "::"))
ftok = tok1->previous();
if (!settings.library.isFunctionConst(ftok) && !ftok->isAttributeConst() && !ftok->isAttributePure())
return false;
}
Expand Down
36 changes: 1 addition & 35 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,38 +100,6 @@ static const std::unordered_set<std::string> controlFlowKeywords = {
"return"
};

// TODO: replace with Keywords::getX()?
// Another list of keywords
static const std::unordered_set<std::string> baseKeywords = {
"asm",
"auto",
"break",
"case",
"const",
"continue",
"default",
"do",
"else",
"enum",
"extern",
"for",
"goto",
"if",
"inline",
"register",
"restrict",
"return",
"sizeof",
"static",
"struct",
"switch",
"typedef",
"union",
"volatile",
"while",
"void"
};

void Token::update_property_info()
{
setFlag(fIsControlFlowKeyword, controlFlowKeywords.find(mStr) != controlFlowKeywords.end());
Expand All @@ -146,9 +114,7 @@ void Token::update_property_info()
else if (std::isalpha((unsigned char)mStr[0]) || mStr[0] == '_' || mStr[0] == '$') { // Name
if (mImpl->mVarId)
tokType(eVariable);
else if (mTokensFrontBack.list.isKeyword(mStr))
tokType(eKeyword);
else if (baseKeywords.count(mStr) > 0)
else if (mTokensFrontBack.list.isKeyword(mStr) || mStr == "asm") // TODO: not a keyword
tokType(eKeyword);
else if (mTokType != eVariable && mTokType != eFunction && mTokType != eType && mTokType != eKeyword)
tokType(eName);
Expand Down
2 changes: 2 additions & 0 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8766,6 +8766,8 @@ void Tokenizer::findGarbageCode() const
// Garbage templates..
if (isCPP()) {
for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "< >") && !(Token::Match(tok->tokAt(-1), "%name%") || (tok->tokAt(-1) && Token::Match(tok->tokAt(-2), "operator %op%"))))
syntaxError(tok);
if (!Token::simpleMatch(tok, "template <"))
continue;
if (tok->previous() && !Token::Match(tok->previous(), ":|;|{|}|)|>|\"C++\"")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
template<#p<>tu< <>tu=e
6 changes: 6 additions & 0 deletions test/testcondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5558,6 +5558,12 @@ class TestCondition : public TestFixture {
"}\n");
ASSERT_EQUALS("[test.cpp:4] -> [test.cpp:6]: (style) The if condition is the same as the previous if condition\n", errout_str());

check("void f(double d) {\n" // #12712
" if (std::isfinite(d)) {}\n"
" if (std::isfinite(d)) {}\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (style) The if condition is the same as the previous if condition\n", errout_str());

// do not crash
check("void assign(const MMA& other) {\n"
" if (mPA.cols != other.mPA.cols || mPA.rows != other.mPA.rows)\n"
Expand Down
6 changes: 3 additions & 3 deletions test/testincompletestatement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ class TestIncompleteStatement : public TestFixture {
const Settings settings = settingsBuilder().severity(Severity::warning).build();

#define check(...) check_(__FILE__, __LINE__, __VA_ARGS__)
void check_(const char* file, int line, const char code[], bool inconclusive = false) {
void check_(const char* file, int line, const char code[], bool inconclusive = false, bool cpp = true) {
const Settings settings1 = settingsBuilder(settings).certainty(Certainty::inconclusive, inconclusive).build();

std::vector<std::string> files(1, "test.cpp");
std::vector<std::string> files(1, cpp ? "test.cpp" : "test.c");
Tokenizer tokenizer(settings1, *this);
PreprocessorHelper::preprocess(code, files, tokenizer, *this);

Expand Down Expand Up @@ -743,7 +743,7 @@ class TestIncompleteStatement : public TestFixture {
check("void f() { char * const * a, * const * b; }", true);
ASSERT_EQUALS("", errout_str());

check("void f() { char * const * a = 0, * volatile restrict * b; }", true);
check("void f() { char * const * a = 0, * volatile restrict * b; }", true, /*cpp*/ false);
ASSERT_EQUALS("", errout_str());

check("void f() { char * const * a = 0, * volatile const * b; }", true);
Expand Down
3 changes: 3 additions & 0 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7151,6 +7151,9 @@ class TestTokenizer : public TestFixture {

ASSERT_NO_THROW(tokenizeAndStringify("typedef struct { typedef int T; } S;")); // #12700

ASSERT_NO_THROW(tokenizeAndStringify("class A { bool restrict() const; };\n"
"bool A::restrict() const { return true; }")); // #12718

ignore_errout();
}

Expand Down
21 changes: 12 additions & 9 deletions htmlreport/check.sh → test/tools/htmlreport/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,49 +26,52 @@ if [ -z "$PYTHON" ]; then
PYTHON=python
fi

SCRIPT_DIR="$(dirname ${BASH_SOURCE[0]})"
ABSOLUTE_SCRIPT_DIR="$(cd -- ${SCRIPT_DIR} ; pwd -P)"
PROJECT_ROOT_DIR="$(cd -- ${SCRIPT_DIR}/../../../ ; pwd -P)"
REPORT_DIR=$(mktemp -d -t htmlreport-XXXXXXXXXX)
INDEX_HTML="$REPORT_DIR/index.html"
STATS_HTML="$REPORT_DIR/stats.html"
GUI_TEST_XML="$REPORT_DIR/gui_test.xml"
ERRORLIST_XML="$REPORT_DIR/errorlist.xml"
UNMATCHEDSUPPR_XML="$REPORT_DIR/unmatchedSuppr.xml"

$PYTHON cppcheck-htmlreport --file ../gui/test/data/xmlfiles/xmlreport_v2.xml --title "xml2 test" --report-dir "$REPORT_DIR" --source-dir ../test/
$PYTHON ${PROJECT_ROOT_DIR}/htmlreport/cppcheck-htmlreport --file ${PROJECT_ROOT_DIR}/gui/test/data/xmlfiles/xmlreport_v2.xml --title "xml2 test" --report-dir "$REPORT_DIR" --source-dir ${PROJECT_ROOT_DIR}/test/
echo -e "\n"
# Check HTML syntax
validate_html "$INDEX_HTML"
validate_html "$STATS_HTML"


../cppcheck ../samples --enable=all --inconclusive --xml-version=2 2> "$GUI_TEST_XML"
${PROJECT_ROOT_DIR}/cppcheck ${PROJECT_ROOT_DIR}/samples --enable=all --inconclusive --xml-version=2 2> "$GUI_TEST_XML"
xmllint --noout "$GUI_TEST_XML"
$PYTHON cppcheck-htmlreport --file "$GUI_TEST_XML" --title "xml2 + inconclusive test" --report-dir "$REPORT_DIR"
$PYTHON ${PROJECT_ROOT_DIR}/htmlreport/cppcheck-htmlreport --file "$GUI_TEST_XML" --title "xml2 + inconclusive test" --report-dir "$REPORT_DIR"
echo ""
# Check HTML syntax
validate_html "$INDEX_HTML"
validate_html "$STATS_HTML"


../cppcheck ../samples --enable=all --inconclusive --verbose --xml-version=2 2> "$GUI_TEST_XML"
${PROJECT_ROOT_DIR}/cppcheck ${PROJECT_ROOT_DIR}/samples --enable=all --inconclusive --verbose --xml-version=2 2> "$GUI_TEST_XML"
xmllint --noout "$GUI_TEST_XML"
$PYTHON cppcheck-htmlreport --file "$GUI_TEST_XML" --title "xml2 + inconclusive + verbose test" --report-dir "$REPORT_DIR"
$PYTHON ${PROJECT_ROOT_DIR}/htmlreport/cppcheck-htmlreport --file "$GUI_TEST_XML" --title "xml2 + inconclusive + verbose test" --report-dir "$REPORT_DIR"
echo -e "\n"
# Check HTML syntax
validate_html "$INDEX_HTML"
validate_html "$STATS_HTML"


../cppcheck --errorlist --inconclusive --xml-version=2 > "$ERRORLIST_XML"
${PROJECT_ROOT_DIR}/cppcheck --errorlist --inconclusive --xml-version=2 > "$ERRORLIST_XML"
xmllint --noout "$ERRORLIST_XML"
$PYTHON cppcheck-htmlreport --file "$ERRORLIST_XML" --title "errorlist" --report-dir "$REPORT_DIR"
$PYTHON ${PROJECT_ROOT_DIR}/htmlreport/cppcheck-htmlreport --file "$ERRORLIST_XML" --title "errorlist" --report-dir "$REPORT_DIR"
# Check HTML syntax
validate_html "$INDEX_HTML"
validate_html "$STATS_HTML"


../cppcheck ../samples/memleak/good.c ../samples/resourceLeak/good.c --xml-version=2 --enable=information --suppressions-list=test_suppressions.txt --xml 2> "$UNMATCHEDSUPPR_XML"
${PROJECT_ROOT_DIR}/cppcheck ${PROJECT_ROOT_DIR}/samples/memleak/good.c ${PROJECT_ROOT_DIR}/samples/resourceLeak/good.c --xml-version=2 --enable=information --suppressions-list="${ABSOLUTE_SCRIPT_DIR}/test_suppressions.txt" --xml 2> "$UNMATCHEDSUPPR_XML"
xmllint --noout "$UNMATCHEDSUPPR_XML"
$PYTHON cppcheck-htmlreport --file "$UNMATCHEDSUPPR_XML" --title "unmatched Suppressions" --report-dir="$REPORT_DIR"
$PYTHON ${PROJECT_ROOT_DIR}/htmlreport/cppcheck-htmlreport --file "$UNMATCHEDSUPPR_XML" --title "unmatched Suppressions" --report-dir="$REPORT_DIR"
grep "unmatchedSuppression<.*>information<.*>Unmatched suppression: variableScope*<" "$INDEX_HTML"
grep ">unmatchedSuppression</.*>information<.*>Unmatched suppression: uninitstring<" "$INDEX_HTML"
grep "notexisting" "$INDEX_HTML"
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
else:
import unittest

ROOT_DIR = os.path.split(os.path.abspath(os.path.dirname(__file__)))[0]
TEST_TOOLS_DIR = os.path.abspath(os.path.dirname(__file__))
ROOT_DIR = os.path.split(os.path.dirname(os.path.dirname(TEST_TOOLS_DIR)))[0]
HTMLREPORT_DIR = os.path.join(ROOT_DIR, 'htmlreport')
CPPCHECK_BIN = os.path.join(ROOT_DIR, 'cppcheck')

HTML_REPORT_BIN = os.path.join(os.path.abspath(os.path.dirname(__file__)),
'cppcheck-htmlreport')
if os.getenv("PIP_PACKAGE_TEST") is not None:
HTML_REPORT_BIN = ['cppcheck-htmlreport']
else:
HTML_REPORT_BIN = [sys.executable, os.path.join(HTMLREPORT_DIR, 'cppcheck-htmlreport')]


class TestHTMLReport(unittest.TestCase):
Expand Down Expand Up @@ -65,7 +69,7 @@ def checkReportNoError(self, xml_version):

def testMissingInclude(self):
with runCheck(
xml_filename=os.path.join(ROOT_DIR, 'htmlreport', 'example.xml'),
xml_filename=os.path.join(TEST_TOOLS_DIR, 'example.xml'),
) as (report, output_directory):
self.assertIn('<html', report)

Expand Down Expand Up @@ -98,10 +102,10 @@ def runCheck(source_filename=None, xml_version='1', xml_filename=None):
assert os.path.exists(xml_filename)

subprocess.check_call(
[sys.executable, HTML_REPORT_BIN,
[*HTML_REPORT_BIN,
'--file=' + os.path.realpath(xml_filename),
'--report-dir=' + os.path.realpath(output_directory)],
cwd=os.path.join(ROOT_DIR, 'htmlreport'))
cwd=TEST_TOOLS_DIR)

with open(os.path.join(output_directory, 'index.html')) as index_file:
index_contents = index_file.read()
Expand Down
3 changes: 3 additions & 0 deletions test/tools/htmlreport/test_suppressions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
variableScope:*/samples/memleak/good.c
*:*/samples/resourceLeak/notexisting.c*
uninitstring:*

0 comments on commit d2f4535

Please sign in to comment.