Skip to content
This repository was archived by the owner on Jul 13, 2019. It is now read-only.

Commit b4a3653

Browse files
committed
fix issues with file extensions
1 parent 212f968 commit b4a3653

File tree

1 file changed

+72
-48
lines changed

1 file changed

+72
-48
lines changed

cpplint.py

Lines changed: 72 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import codecs
4545
import copy
4646
import getopt
47+
import itertools
4748
import math # for log
4849
import os
4950
import re
@@ -52,10 +53,20 @@
5253
import sys
5354
import unicodedata
5455

56+
# Files with any of these extensions are considered to be
57+
# header files (and will undergo different style checks).
58+
# This set can be extended by using the --headers
59+
# option (also supported in CPPLINT.cfg)
60+
_header_extensions = set(['h', 'hpp', 'hxx', 'h++', 'cuh'])
61+
_nonheader_extensions = set(['c', 'cc', 'cpp', 'cxx', 'c++', 'cu'])
62+
63+
5564
# The allowed extensions for file names
5665
# This is set by --extensions flag.
57-
_valid_extensions = set(['c', 'cc', 'cpp', 'cxx', 'c++', 'h', 'hpp', 'hxx',
58-
'h++'])
66+
_valid_extensions = _nonheader_extensions.union(_header_extensions)
67+
68+
# files with this suffix before the extension will be treated as test files
69+
_test_suffixes = set(['_unittest', '_test', '_regtest'])
5970

6071
_USAGE = """
6172
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
@@ -1073,7 +1084,7 @@ def BaseName(self):
10731084
return self.Split()[1]
10741085

10751086
def Extension(self):
1076-
"""File extension - text following the final period."""
1087+
"""File extension - text following the final period, includes that period."""
10771088
return self.Split()[2]
10781089

10791090
def NoExtension(self):
@@ -1797,28 +1808,29 @@ def CheckForHeaderGuard(filename, clean_lines, error):
17971808

17981809

17991810
def CheckHeaderFileIncluded(filename, include_state, error):
1800-
"""Logs an error if a .cc file does not include its header."""
1811+
"""Logs an error if a source file does not include its header."""
18011812

18021813
# Do not check test files
1803-
if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'):
1814+
if _IsTestFilename(filename):
18041815
return
18051816

18061817
fileinfo = FileInfo(filename)
1807-
headerfile = filename[0:len(filename) - 2] + 'h'
1808-
if not os.path.exists(headerfile):
1809-
return
1810-
headername = FileInfo(headerfile).RepositoryName()
1811-
first_include = 0
1812-
for section_list in include_state.include_list:
1813-
for f in section_list:
1814-
if headername in f[0] or f[0] in headername:
1815-
return
1816-
if not first_include:
1817-
first_include = f[1]
1818+
for ext in _header_extensions:
1819+
headerfile = filename[:filename.rfind('.') + 1] + ext
1820+
if not os.path.exists(headerfile):
1821+
continue
1822+
headername = FileInfo(headerfile).RepositoryName()
1823+
first_include = None
1824+
for section_list in include_state.include_list:
1825+
for f in section_list:
1826+
if headername in f[0] or f[0] in headername:
1827+
return
1828+
if not first_include:
1829+
first_include = f[1]
18181830

1819-
error(filename, first_include, 'build/include', 5,
1820-
'%s should include its header file %s' % (fileinfo.RepositoryName(),
1821-
headername))
1831+
error(filename, first_include, 'build/include', 5,
1832+
'%s should include its header file %s' % (fileinfo.RepositoryName(),
1833+
headername))
18221834

18231835

18241836
def CheckForBadCharacters(filename, lines, error):
@@ -4459,7 +4471,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
44594471

44604472
# Check if the line is a header guard.
44614473
is_header_guard = False
4462-
if file_extension == 'h':
4474+
if file_extension in _header_extensions:
44634475
cppvar = GetHeaderGuardCPPVariable(filename)
44644476
if (line.startswith('#ifndef %s' % cppvar) or
44654477
line.startswith('#define %s' % cppvar) or
@@ -4548,8 +4560,11 @@ def _DropCommonSuffixes(filename):
45484560
Returns:
45494561
The filename with the common suffix removed.
45504562
"""
4551-
for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
4552-
'inl.h', 'impl.h', 'internal.h'):
4563+
for suffix in itertools.chain(
4564+
('%s.%s' % (test_suffix.lstrip('_'), ext)
4565+
for test_suffix, ext in itertools.product(_test_suffixes, _nonheader_extensions)),
4566+
('%s.%s' % (suffix, ext)
4567+
for suffix, ext in itertools.product(['inl', 'imp', 'internal'], _header_extensions))):
45534568
if (filename.endswith(suffix) and len(filename) > len(suffix) and
45544569
filename[-len(suffix) - 1] in ('-', '_')):
45554570
return filename[:-len(suffix) - 1]
@@ -4565,12 +4580,10 @@ def _IsTestFilename(filename):
45654580
Returns:
45664581
True if 'filename' looks like a test, False otherwise.
45674582
"""
4568-
if (filename.endswith('_test.cc') or
4569-
filename.endswith('_unittest.cc') or
4570-
filename.endswith('_regtest.cc')):
4571-
return True
4572-
else:
4573-
return False
4583+
for test_suffix, ext in itertools.product(_test_suffixes, _nonheader_extensions):
4584+
if filename.endswith(test_suffix + '.' + ext):
4585+
return True
4586+
return False
45744587

45754588

45764589
def _ClassifyInclude(fileinfo, include, is_system):
@@ -4674,11 +4687,16 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
46744687
error(filename, linenum, 'build/include', 4,
46754688
'"%s" already included at %s:%s' %
46764689
(include, filename, duplicate_line))
4677-
elif (include.endswith('.cc') and
4690+
return
4691+
4692+
for extension in _nonheader_extensions:
4693+
if (include.endswith('.' + extension) and
46784694
os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)):
4679-
error(filename, linenum, 'build/include', 4,
4680-
'Do not include .cc files from other packages')
4681-
elif not _THIRD_PARTY_HEADERS_PATTERN.match(include):
4695+
error(filename, linenum, 'build/include', 4,
4696+
'Do not include .' + extension + ' files from other packages')
4697+
return
4698+
4699+
if not _THIRD_PARTY_HEADERS_PATTERN.match(include):
46824700
include_state.include_list[-1].append((include, linenum))
46834701

46844702
# We want to ensure that headers appear in the right order:
@@ -4828,7 +4846,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
48284846
CheckGlobalStatic(filename, clean_lines, linenum, error)
48294847
CheckPrintf(filename, clean_lines, linenum, error)
48304848

4831-
if file_extension == 'h':
4849+
if file_extension in _header_extensions:
48324850
# TODO(unknown): check that 1-arg constructors are explicit.
48334851
# How to tell it's a constructor?
48344852
# (handled in CheckForNonStandardConstructs for now)
@@ -4935,7 +4953,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
49354953
# Check for use of unnamed namespaces in header files. Registration
49364954
# macros are typically OK, so we allow use of "namespace {" on lines
49374955
# that end with backslashes.
4938-
if (file_extension == 'h'
4956+
if (file_extension in _header_extensions
49394957
and Search(r'\bnamespace\s*{', line)
49404958
and line[-1] != '\\'):
49414959
error(filename, linenum, 'build/namespaces', 4,
@@ -5568,28 +5586,32 @@ def FilesBelongToSameModule(filename_cc, filename_h):
55685586
some false positives. This should be sufficiently rare in practice.
55695587
55705588
Args:
5571-
filename_cc: is the path for the .cc file
5589+
filename_cc: is the path for the source (e.g. .cc) file
55725590
filename_h: is the path for the header path
55735591
55745592
Returns:
55755593
Tuple with a bool and a string:
55765594
bool: True if filename_cc and filename_h belong to the same module.
55775595
string: the additional prefix needed to open the header file.
55785596
"""
5597+
fileinfo_cc = FileInfo(filename_cc)
5598+
if not fileinfo_cc.Extension().lstrip('.') in _nonheader_extensions:
5599+
return (False, '')
55795600

5580-
if not filename_cc.endswith('.cc'):
5601+
fileinfo_h = FileInfo(filename_h)
5602+
if not fileinfo_h.Extension().lstrip('.') in _header_extensions:
55815603
return (False, '')
5582-
filename_cc = filename_cc[:-len('.cc')]
5583-
if filename_cc.endswith('_unittest'):
5584-
filename_cc = filename_cc[:-len('_unittest')]
5585-
elif filename_cc.endswith('_test'):
5586-
filename_cc = filename_cc[:-len('_test')]
5604+
5605+
filename_cc = filename_cc[:-(len(fileinfo_cc.Extension()))]
5606+
for suffix in _test_suffixes:
5607+
if filename_cc.endswith(suffix):
5608+
filename_cc = filename_cc[:-len(suffix)]
5609+
break
5610+
55875611
filename_cc = filename_cc.replace('/public/', '/')
55885612
filename_cc = filename_cc.replace('/internal/', '/')
55895613

5590-
if not filename_h.endswith('.h'):
5591-
return (False, '')
5592-
filename_h = filename_h[:-len('.h')]
5614+
filename_h = filename_h[:-(len(fileinfo_h.Extension()))]
55935615
if filename_h.endswith('-inl'):
55945616
filename_h = filename_h[:-len('-inl')]
55955617
filename_h = filename_h.replace('/public/', '/')
@@ -5711,8 +5733,10 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
57115733
# didn't include it in the .h file.
57125734
# TODO(unknown): Do a better job of finding .h files so we are confident that
57135735
# not having the .h file means there isn't one.
5714-
if filename.endswith('.cc') and not header_found:
5715-
return
5736+
if not header_found:
5737+
for extension in _nonheader_extensions:
5738+
if filename.endswith('.' + extension):
5739+
return
57165740

57175741
# All the lines have been processed, report the errors found.
57185742
for required_header_unstripped in required:
@@ -6051,7 +6075,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60516075
RemoveMultiLineComments(filename, lines, error)
60526076
clean_lines = CleansedLines(lines)
60536077

6054-
if file_extension == 'h':
6078+
if file_extension in _header_extensions:
60556079
CheckForHeaderGuard(filename, clean_lines, error)
60566080

60576081
for line in range(clean_lines.NumLines()):
@@ -6064,7 +6088,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60646088
CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
60656089

60666090
# Check that the .cc file has included its header if it exists.
6067-
if file_extension == 'cc':
6091+
if file_extension in _nonheader_extensions:
60686092
CheckHeaderFileIncluded(filename, include_state, error)
60696093

60706094
# We check here rather than inside ProcessLine so that we see raw

0 commit comments

Comments
 (0)