Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[report-converter][cmd] Parse cpplint Output #3248

Merged
merged 4 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ The following tools are supported:
| | [Smatch](/tools/report-converter/README.md#smatch) |
| | [Kernel-Doc](/tools/report-converter/README.md#kernel-doc) |
| | [Sparse](/tools/report-converter/README.md#sparse) |
| | [cpplint](/tools/report-converter/README.md#cpplint) |
| **Java** | [SpotBugs](/tools/report-converter/README.md#spotbugs) |
| | [Facebook Infer](/tools/report-converter/README.md#fbinfer) |
| **Python** | [Pylint](/tools/report-converter/README.md#pylint) |
Expand Down
1 change: 1 addition & 0 deletions docs/supported_code_analyzers.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ CodeChecker result directory which can be stored to a CodeChecker server.
| | [Smatch](/tools/report-converter/README.md#smatch) | ✓ |
| | [Kernel-Doc](/tools/report-converter/README.md#kernel-doc) | ✓ |
| | [Sparse](/tools/report-converter/README.md#sparse) | ✓ |
| | [cpplint](/tools/report-converter/README.md#cpplint) | ✓ |
| **Java** | [FindBugs](http://findbugs.sourceforge.net/) | ✗ |
| | [SpotBugs](/tools/report-converter/README.md#spotbugs) | ✓ |
| | [Facebook Infer](/tools/report-converter/README.md#fbinfer) | ✓ |
Expand Down
42 changes: 35 additions & 7 deletions tools/report-converter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ a CodeChecker server.
* [Kernel-Doc](#kernel-doc)
* [Sphinx](#sphinx)
* [Sparse](#sparse)
* [cpplint](#cpplint)
* [License](#license)

## Install guide
Expand Down Expand Up @@ -60,9 +61,10 @@ optional arguments:
report directory files.
-t TYPE, --type TYPE Specify the format of the code analyzer output.
Currently supported output types are: asan, clang-
tidy, coccinelle, cppcheck, eslint, fbinfer, golint,
kernel-doc, msan, pyflakes, pylint, smatch, sparse,
spotbugs, sphinx, tsan, tslint, ubsan.
tidy, coccinelle, cppcheck, cpplint, eslint,
fbinfer, golint, kernel-doc, mdl, msan, pyflakes,
pylint, smatch, sparse, sphinx, spotbugs, tsan,
tslint, ubsan.
--meta [META [META ...]]
Metadata information which will be stored alongside
the run when the created report directory will be
Expand Down Expand Up @@ -90,6 +92,7 @@ Supported analyzers:
clang-tidy - Clang Tidy, https://clang.llvm.org/extra/clang-tidy
coccinelle - Coccinelle, https://github.com/coccinelle/coccinelle
cppcheck - Cppcheck, http://cppcheck.sourceforge.net
cpplint - cpplint, https://github.com/cpplint/cpplint
eslint - ESLint, https://eslint.org/
fbinfer - Facebook Infer, https://fbinfer.com
golint - Golint, https://github.com/golang/lint
Expand All @@ -98,10 +101,10 @@ Supported analyzers:
msan - MemorySanitizer, https://clang.llvm.org/docs/MemorySanitizer.html
pyflakes - Pyflakes, https://github.com/PyCQA/pyflakes
pylint - Pylint, https://www.pylint.org
smatch - smatch, https://repo.or.cz/w/smatch.git
sparse - sparse, https://git.kernel.org/pub/scm/devel/sparse/sparse.git
smatch - Smatch, https://repo.or.cz/w/smatch.git
sparse - Sparse, https://git.kernel.org/pub/scm/devel/sparse/sparse.git
sphinx - Sphinx, https://github.com/sphinx-doc/sphinx
spotbugs - spotbugs, https://spotbugs.github.io
sphinx - sphinx, https://github.com/sphinx-doc/sphinx
tsan - ThreadSanitizer, https://clang.llvm.org/docs/ThreadSanitizer.html
tslint - TSLint, https://palantir.github.io/tslint
ubsan - UndefinedBehaviorSanitizer, https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
Expand Down Expand Up @@ -532,7 +535,32 @@ report-converter -t sparse -o ./codechecker_sparse_reports ./sparse.out
CodeChecker store ./codechecker_sparse_reports -n sparse
```

## [cpplint](https://github.com/cpplint/cpplint)
[cpplint](https://github.com/cpplint/cpplint) is a lint-like tool which checks
C++ code against [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).

The recommended way of running cpplint is to redirect the output to a file and
give this file to the report converter tool.

The following example shows you how to run cpplint and store the results
found by cpplint to the CodeChecker database.

```sh
# Change Directory to your project
cd path/to/your/project

# Run cpplint
cpplint sample.cpp > ./sample.out 2>&1

# Use 'report-converter' to create a CodeChecker report directory from the
# analyzer result of cpplint
report-converter -t cpplint -o ./codechecker_cpplint_reports ./sample.out

# Store the cpplint reports with CodeChecker.
CodeChecker store ./codechecker_cpplint_reports -n cpplint
```

## License

The project is licensed under Apache License v2.0 with LLVM Exceptions.
See LICENSE.TXT for details.
See LICENSE.TXT for details.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
SphinxAnalyzerResult # noqa
from codechecker_report_converter.sparse.analyzer_result import \
SparseAnalyzerResult # noqa
from codechecker_report_converter.cpplint.analyzer_result import \
CpplintAnalyzerResult # noqa


LOG = logging.getLogger('ReportConverter')
Expand Down Expand Up @@ -101,7 +103,8 @@ class RawDescriptionDefaultHelpFormatter(
SmatchAnalyzerResult.TOOL_NAME: SmatchAnalyzerResult,
KernelDocAnalyzerResult.TOOL_NAME: KernelDocAnalyzerResult,
SphinxAnalyzerResult.TOOL_NAME: SphinxAnalyzerResult,
SparseAnalyzerResult.TOOL_NAME: SparseAnalyzerResult
SparseAnalyzerResult.TOOL_NAME: SparseAnalyzerResult,
CpplintAnalyzerResult.TOOL_NAME: CpplintAnalyzerResult,
}

supported_metadata_keys = ["analyzer_command", "analyzer_version"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

from codechecker_report_converter.analyzer_result import AnalyzerResult

from .output_parser import CpplintParser
from ..plist_converter import PlistConverter


class CpplintAnalyzerResult(AnalyzerResult):
""" Transform analyzer result of cpplint. """

TOOL_NAME = 'cpplint'
NAME = 'cpplint'
URL = 'https://github.com/cpplint/cpplint'
uhziel marked this conversation as resolved.
Show resolved Hide resolved

def parse(self, analyzer_result):
""" Creates plist files from the given analyzer result to the given
output directory.
"""
parser = CpplintParser(analyzer_result)

content = self._get_analyzer_result_file_content(analyzer_result)
if not content:
return

messages = parser.parse_messages(content)

plist_converter = PlistConverter(self.TOOL_NAME)
plist_converter.add_messages(messages)
return plist_converter.get_plist_results()
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------

import logging
import os
import re

from ..output_parser import BaseParser, Message
LOG = logging.getLogger('ReportConverter')


class CpplintParser(BaseParser):
"""
Parser for cpplint Output
"""

def __init__(self, analyzer_result):
super(CpplintParser, self).__init__()

self.analyzer_result = analyzer_result

self.message_line_re = re.compile(
# File path followed by a ':'.
r'^(?P<path>[\S ]+?):'
# Line number followed by a ': '.
r'(?P<line>\d+?): '
# Message followed by a ' ['.
r'(?P<message>[\S \t]+) \['
# Checker name followed by a whitespace
r'(?P<checker_name>\S+)\]\s')

def parse_message(self, it, line):
"""
Actual Parsing function for the given line
"""
match = self.message_line_re.match(line)

if match is None:
return None, next(it)

file_path = os.path.normpath(
os.path.join(os.path.dirname(self.analyzer_result),
match.group('path')))

column = 0

message = Message(
file_path,
int(match.group('line')),
column,
match.group('message').strip(),
match.group('checker_name'))

try:
return message, next(it)
except StopIteration:
return message, ''
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
cpplint files/sample.cpp > ./sample.out 2>&1 ; true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef Foobar
#define Foobar

class Foobar {

};

#endif // Foobar
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>diagnostics</key>
<array>
<dict>
<key>category</key>
<string>unknown</string>
<key>check_name</key>
<string>legal/copyright</string>
<key>description</key>
<string>No copyright message found. You should have a line: "Copyright [year] &lt;Copyright Owner&gt;"</string>
<key>issue_hash_content_of_line_in_context</key>
<string>7efc30b7a1c38d3d76ba2c2b9578ac14</string>
<key>location</key>
<dict>
<key>col</key>
<integer>0</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>0</integer>
</dict>
<key>path</key>
<array>
<dict>
<key>depth</key>
<integer>0</integer>
<key>kind</key>
<string>event</string>
<key>location</key>
<dict>
<key>col</key>
<integer>0</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>0</integer>
</dict>
<key>message</key>
<string>No copyright message found. You should have a line: "Copyright [year] &lt;Copyright Owner&gt;"</string>
</dict>
</array>
<key>type</key>
<string>cpplint</string>
</dict>
<dict>
<key>category</key>
<string>unknown</string>
<key>check_name</key>
<string>whitespace/blank_line</string>
<key>description</key>
<string>Redundant blank line at the start of a code block should be deleted.</string>
<key>issue_hash_content_of_line_in_context</key>
<string>a61ce7c9d089e76475c5de1d542fd068</string>
<key>location</key>
<dict>
<key>col</key>
<integer>0</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>5</integer>
</dict>
<key>path</key>
<array>
<dict>
<key>depth</key>
<integer>0</integer>
<key>kind</key>
<string>event</string>
<key>location</key>
<dict>
<key>col</key>
<integer>0</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>5</integer>
</dict>
<key>message</key>
<string>Redundant blank line at the start of a code block should be deleted.</string>
</dict>
</array>
<key>type</key>
<string>cpplint</string>
</dict>
<dict>
<key>category</key>
<string>unknown</string>
<key>check_name</key>
<string>whitespace/blank_line</string>
<key>description</key>
<string>Redundant blank line at the end of a code block should be deleted.</string>
<key>issue_hash_content_of_line_in_context</key>
<string>68bac0e265a5b36e8ef42ba50d00a890</string>
<key>location</key>
<dict>
<key>col</key>
<integer>0</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>5</integer>
</dict>
<key>path</key>
<array>
<dict>
<key>depth</key>
<integer>0</integer>
<key>kind</key>
<string>event</string>
<key>location</key>
<dict>
<key>col</key>
<integer>0</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>5</integer>
</dict>
<key>message</key>
<string>Redundant blank line at the end of a code block should be deleted.</string>
</dict>
</array>
<key>type</key>
<string>cpplint</string>
</dict>
</array>
<key>files</key>
<array>
<string>files/sample.cpp</string>
</array>
<key>metadata</key>
<dict>
<key>analyzer</key>
<dict>
<key>name</key>
<string>cpplint</string>
</dict>
<key>generated_by</key>
<dict>
<key>name</key>
<string>report-converter</string>
<key>version</key>
<string>x.y.z</string>
</dict>
</dict>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
files/sample.cpp:0: No copyright message found. You should have a line: "Copyright [year] <Copyright Owner>" [legal/copyright] [5]
files/sample.cpp:5: Redundant blank line at the start of a code block should be deleted. [whitespace/blank_line] [2]
files/sample.cpp:5: Redundant blank line at the end of a code block should be deleted. [whitespace/blank_line] [3]
Done processing files/sample.cpp
Total errors found: 3
Loading