Skip to content
Open
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
36 changes: 24 additions & 12 deletions ament_cpplint/ament_cpplint/cpplint.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# https://github.com/cpplint/cpplint/blob/6b1d29874dc5d7c3c9201b70e760b3eb9468a60d/cpplint.py
# https://github.com/cpplint/cpplint/blob/1.6.1/cpplint.py

"""Does google-lint on c++ files.

Expand All @@ -43,6 +43,11 @@
same line, but it is far from perfect (in either direction).
"""

# cpplint predates fstrings
# pylint: disable=consider-using-f-string

# pylint: disable=invalid-name

import codecs
import copy
import getopt
Expand All @@ -61,14 +66,16 @@
# if empty, use defaults
_valid_extensions = set([])

__VERSION__ = '1.5.5'
__VERSION__ = '1.6.1'

try:
# -- pylint: disable=used-before-assignment
xrange # Python 2
except NameError:
# -- pylint: disable=redefined-builtin
xrange = range # Python 3


_USAGE = """
Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit|sed|gsed]
[--filter=-x,+y,...]
Expand Down Expand Up @@ -879,12 +886,14 @@
_include_order = "default"

try:
# -- pylint: disable=used-before-assignment
unicode
except NameError:
# -- pylint: disable=redefined-builtin
basestring = unicode = str

try:
# -- pylint: disable=used-before-assignment
long
except NameError:
# -- pylint: disable=redefined-builtin
Expand Down Expand Up @@ -1620,7 +1629,6 @@ def RepositoryName(self):
os.path.exists(os.path.join(current_dir, ".hg")) or
os.path.exists(os.path.join(current_dir, ".svn"))):
root_dir = current_dir
break
current_dir = os.path.dirname(current_dir)

if (os.path.exists(os.path.join(root_dir, ".git")) or
Expand Down Expand Up @@ -1926,6 +1934,7 @@ def __init__(self, lines):
self.raw_lines = lines
self.num_lines = len(lines)
self.lines_without_raw_strings = CleanseRawStrings(lines)
# # pylint: disable=consider-using-enumerate
for linenum in range(len(self.lines_without_raw_strings)):
self.lines.append(CleanseComments(
self.lines_without_raw_strings[linenum]))
Expand Down Expand Up @@ -2854,7 +2863,7 @@ def CheckEnd(self, filename, clean_lines, linenum, error):
# deciding what these nontrivial things are, so this check is
# triggered by namespace size only, which works most of the time.
if (linenum - self.starting_linenum < 10
and not Match(r'^\s*};*\s*(//).*\bnamespace\b', line)):
and not Match(r'^\s*};*\s*(//|/\*).*\bnamespace\b', line)):
return

# Look for matching comment at end of namespace.
Expand All @@ -2871,7 +2880,7 @@ def CheckEnd(self, filename, clean_lines, linenum, error):
# expected namespace.
if self.name:
# Named namespace
if not Match((r'^\s*};*\s*(//).*\bnamespace\s+' +
if not Match((r'^\s*};*\s*(//|/\*).*\bnamespace\s+' +
re.escape(self.name) + r'[\*/\.\\\s]*$'),
line):
error(filename, linenum, 'readability/namespace', 5,
Expand Down Expand Up @@ -5080,10 +5089,12 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
#
# We also make an exception for Lua headers, which follow google
# naming convention but not the include convention.
match = Match(r'#include\s*"([^/]+\.h)"', line)
if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)):
error(filename, linenum, 'build/include_subdir', 4,
'Include the directory when naming .h files')
match = Match(r'#include\s*"([^/]+\.(.*))"', line)
if match:
if (IsHeaderExtension(match.group(2)) and
not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1))):
error(filename, linenum, 'build/include_subdir', 4,
'Include the directory when naming header files')

# we shouldn't include a file more than once. actually, there are a
# handful of instances where doing so is okay, but in general it's
Expand Down Expand Up @@ -5872,7 +5883,8 @@ def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error):
return False

# operator++(int) and operator--(int)
if context.endswith(' operator++') or context.endswith(' operator--'):
if (context.endswith(' operator++') or context.endswith(' operator--') or
context.endswith('::operator++') or context.endswith('::operator--')):
return False

# A single unnamed argument for a function tends to look like old style cast.
Expand Down Expand Up @@ -6555,7 +6567,7 @@ def ProcessConfigOverrides(filename):
continue

try:
with open(cfg_file) as file_handle:
with codecs.open(cfg_file, 'r', 'utf8', 'replace') as file_handle:
for line in file_handle:
line, _, _ = line.partition('#') # Remove comments.
if not line.strip():
Expand Down Expand Up @@ -6930,4 +6942,4 @@ def main():


if __name__ == '__main__':
main()
main()
46 changes: 46 additions & 0 deletions ament_cpplint/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,49 @@ How to run the check from within a CMake ament package as part of the tests?

The CMake integration is provided by the package `ament_cmake_cpplint
<https://github.com/ament/ament_lint>`_.

Patches for cpplint 1.6.1. Fixes 1 and 2 have been made upstream.

1. Run with `python3` not `python`. [See](https://github.com/ament/ament_lint/pull/39/files).

```python
#!/usr/bin/env python3
```

2. Don't run `cpp` lints on `.c` files. [See](https://github.com/ament/ament_lint/pull/32).

```python
# Don't warn in C files about C-style casts
if os.path.splitext(filename)[1] in ['.c', '.h']:
return False
```

3. allow using-directive for user-defined literals namespaces. [see](https://github.com/ament/ament_lint/pull/67)

```python
# Check for 'using namespace' which pollutes namespaces.
# This is tricky. Although in general 'using namespace' is a Bad Thing,
# an exception is made for certain standard namespaces, like std::*literals
# and std::placeholders, which are intended to be used in this fashion.
# This whitelist may grow over time as needed if/when shiny new libraries
# come along that are well-behaved in a 'using namespace' context.
# For example, 'using namespace std::chrono_literals;' is allowed, but
# 'using namespace foo;' is not allowed.
# Note that headers are not permitted to use this exception.
match = Search(r'\busing namespace\s+((\w|::)+)', line)
if match:
whitelist = [
'std::chrono_literals',
'std::complex_literals',
'std::literals',
'std::literals::chrono_literals',
'std::literals::complex_literals',
'std::literals::string_literals',
'std::placeholders',
'std::string_literals',
]
if IsHeaderExtension(file_extension) or match.group(1) not in whitelist:
error(filename, linenum, 'build/namespaces', 5,
'Do not use namespace using-directives. '
'Use using-declarations instead.')
```