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

Commit c15fdad

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

File tree

1 file changed

+75
-46
lines changed

1 file changed

+75
-46
lines changed

cpplint.py

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,20 @@
5252
import sys
5353
import unicodedata
5454

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

6070
_USAGE = """
6171
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
@@ -1073,7 +1083,7 @@ def BaseName(self):
10731083
return self.Split()[1]
10741084

10751085
def Extension(self):
1076-
"""File extension - text following the final period."""
1086+
"""File extension - text following the final period, includes that period."""
10771087
return self.Split()[2]
10781088

10791089
def NoExtension(self):
@@ -1800,25 +1810,26 @@ def CheckHeaderFileIncluded(filename, include_state, error):
18001810
"""Logs an error if a .cc file does not include its header."""
18011811

18021812
# Do not check test files
1803-
if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'):
1813+
if _IsTestFilename(filename):
18041814
return
18051815

18061816
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]
1817+
for ext in _header_extensions:
1818+
headerfile = filename[:filename.rfind('.') + 1] + ext
1819+
if not os.path.exists(headerfile):
1820+
continue
1821+
headername = FileInfo(headerfile).RepositoryName()
1822+
first_include = None
1823+
for section_list in include_state.include_list:
1824+
for f in section_list:
1825+
if headername in f[0] or f[0] in headername:
1826+
return
1827+
if not first_include:
1828+
first_include = f[1]
18181829

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

18231834

18241835
def CheckForBadCharacters(filename, lines, error):
@@ -4459,7 +4470,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
44594470

44604471
# Check if the line is a header guard.
44614472
is_header_guard = False
4462-
if file_extension == 'h':
4473+
if file_extension in _header_extensions:
44634474
cppvar = GetHeaderGuardCPPVariable(filename)
44644475
if (line.startswith('#ifndef %s' % cppvar) or
44654476
line.startswith('#define %s' % cppvar) or
@@ -4548,8 +4559,16 @@ def _DropCommonSuffixes(filename):
45484559
Returns:
45494560
The filename with the common suffix removed.
45504561
"""
4551-
for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
4552-
'inl.h', 'impl.h', 'internal.h'):
4562+
bad_suffixes = []
4563+
for suffix in _test_suffixes:
4564+
for extension in _nonheader_extensions:
4565+
## not sure why first _ char of suffix not considered here, maybe bug
4566+
bad_suffixes.append(suffix[1:] + '.' + extension)
4567+
for extension in _header_extensions:
4568+
bad_suffixes.append('inl.' + extension)
4569+
bad_suffixes.append('impl.' + extension)
4570+
bad_suffixes.append('internal.' + extension)
4571+
for suffix in bad_suffixes:
45534572
if (filename.endswith(suffix) and len(filename) > len(suffix) and
45544573
filename[-len(suffix) - 1] in ('-', '_')):
45554574
return filename[:-len(suffix) - 1]
@@ -4565,12 +4584,11 @@ def _IsTestFilename(filename):
45654584
Returns:
45664585
True if 'filename' looks like a test, False otherwise.
45674586
"""
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
4587+
for suffix in _test_suffixes:
4588+
for extension in _nonheader_extensions:
4589+
if filename.endswith(suffix + '.' + extension):
4590+
return True
4591+
return False
45744592

45754593

45764594
def _ClassifyInclude(fileinfo, include, is_system):
@@ -4674,11 +4692,16 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
46744692
error(filename, linenum, 'build/include', 4,
46754693
'"%s" already included at %s:%s' %
46764694
(include, filename, duplicate_line))
4677-
elif (include.endswith('.cc') and
4695+
return
4696+
4697+
for extension in _nonheader_extensions:
4698+
if (include.endswith('.' + extension) and
46784699
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):
4700+
error(filename, linenum, 'build/include', 4,
4701+
'Do not include .' + extension + ' files from other packages')
4702+
return
4703+
4704+
if not _THIRD_PARTY_HEADERS_PATTERN.match(include):
46824705
include_state.include_list[-1].append((include, linenum))
46834706

46844707
# We want to ensure that headers appear in the right order:
@@ -4828,7 +4851,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
48284851
CheckGlobalStatic(filename, clean_lines, linenum, error)
48294852
CheckPrintf(filename, clean_lines, linenum, error)
48304853

4831-
if file_extension == 'h':
4854+
if file_extension in _header_extensions:
48324855
# TODO(unknown): check that 1-arg constructors are explicit.
48334856
# How to tell it's a constructor?
48344857
# (handled in CheckForNonStandardConstructs for now)
@@ -4935,7 +4958,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
49354958
# Check for use of unnamed namespaces in header files. Registration
49364959
# macros are typically OK, so we allow use of "namespace {" on lines
49374960
# that end with backslashes.
4938-
if (file_extension == 'h'
4961+
if (file_extension in _header_extensions
49394962
and Search(r'\bnamespace\s*{', line)
49404963
and line[-1] != '\\'):
49414964
error(filename, linenum, 'build/namespaces', 4,
@@ -5576,20 +5599,24 @@ def FilesBelongToSameModule(filename_cc, filename_h):
55765599
bool: True if filename_cc and filename_h belong to the same module.
55775600
string: the additional prefix needed to open the header file.
55785601
"""
5602+
fileinfo_cc = FileInfo(filename_cc)
5603+
if not fileinfo_cc.Extension().lstrip('.') in _nonheader_extensions:
5604+
return (False, '')
55795605

5580-
if not filename_cc.endswith('.cc'):
5606+
fileinfo_h = FileInfo(filename_h)
5607+
if not fileinfo_h.Extension().lstrip('.') in _header_extensions:
55815608
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')]
5609+
5610+
filename_cc = filename_cc[:-(len(fileinfo_cc.Extension()))]
5611+
for suffix in _test_suffixes:
5612+
if filename_cc.endswith(suffix):
5613+
filename_cc = filename_cc[:-len(suffix)]
5614+
break
5615+
55875616
filename_cc = filename_cc.replace('/public/', '/')
55885617
filename_cc = filename_cc.replace('/internal/', '/')
55895618

5590-
if not filename_h.endswith('.h'):
5591-
return (False, '')
5592-
filename_h = filename_h[:-len('.h')]
5619+
filename_h = filename_h[:-(len(fileinfo_h.Extension()))]
55935620
if filename_h.endswith('-inl'):
55945621
filename_h = filename_h[:-len('-inl')]
55955622
filename_h = filename_h.replace('/public/', '/')
@@ -5711,8 +5738,10 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
57115738
# didn't include it in the .h file.
57125739
# TODO(unknown): Do a better job of finding .h files so we are confident that
57135740
# not having the .h file means there isn't one.
5714-
if filename.endswith('.cc') and not header_found:
5715-
return
5741+
if not header_found:
5742+
for extension in _nonheader_extensions:
5743+
if filename.endswith('.' + extension):
5744+
return
57165745

57175746
# All the lines have been processed, report the errors found.
57185747
for required_header_unstripped in required:
@@ -6051,7 +6080,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60516080
RemoveMultiLineComments(filename, lines, error)
60526081
clean_lines = CleansedLines(lines)
60536082

6054-
if file_extension == 'h':
6083+
if file_extension in _header_extensions:
60556084
CheckForHeaderGuard(filename, clean_lines, error)
60566085

60576086
for line in range(clean_lines.NumLines()):
@@ -6064,7 +6093,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60646093
CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
60656094

60666095
# Check that the .cc file has included its header if it exists.
6067-
if file_extension == 'cc':
6096+
if file_extension in _nonheader_extensions:
60686097
CheckHeaderFileIncluded(filename, include_state, error)
60696098

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

0 commit comments

Comments
 (0)