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

Commit 3cc8683

Browse files
committed
fix issues with file extensions
1 parent 9afe262 commit 3cc8683

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,...]
@@ -1074,7 +1085,7 @@ def BaseName(self):
10741085
return self.Split()[1]
10751086

10761087
def Extension(self):
1077-
"""File extension - text following the final period."""
1088+
"""File extension - text following the final period, includes that period."""
10781089
return self.Split()[2]
10791090

10801091
def NoExtension(self):
@@ -1798,28 +1809,29 @@ def CheckForHeaderGuard(filename, clean_lines, error):
17981809

17991810

18001811
def CheckHeaderFileIncluded(filename, include_state, error):
1801-
"""Logs an error if a .cc file does not include its header."""
1812+
"""Logs an error if a source file does not include its header."""
18021813

18031814
# Do not check test files
1804-
if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'):
1815+
if _IsTestFilename(filename):
18051816
return
18061817

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

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

18241836

18251837
def CheckForBadCharacters(filename, lines, error):
@@ -4460,7 +4472,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
44604472

44614473
# Check if the line is a header guard.
44624474
is_header_guard = False
4463-
if file_extension == 'h':
4475+
if file_extension in _header_extensions:
44644476
cppvar = GetHeaderGuardCPPVariable(filename)
44654477
if (line.startswith('#ifndef %s' % cppvar) or
44664478
line.startswith('#define %s' % cppvar) or
@@ -4553,8 +4565,11 @@ def _DropCommonSuffixes(filename):
45534565
Returns:
45544566
The filename with the common suffix removed.
45554567
"""
4556-
for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
4557-
'inl.h', 'impl.h', 'internal.h'):
4568+
for suffix in itertools.chain(
4569+
('%s.%s' % (test_suffix.lstrip('_'), ext)
4570+
for test_suffix, ext in itertools.product(_test_suffixes, _nonheader_extensions)),
4571+
('%s.%s' % (suffix, ext)
4572+
for suffix, ext in itertools.product(['inl', 'imp', 'internal'], _header_extensions))):
45584573
if (filename.endswith(suffix) and len(filename) > len(suffix) and
45594574
filename[-len(suffix) - 1] in ('-', '_')):
45604575
return filename[:-len(suffix) - 1]
@@ -4570,12 +4585,10 @@ def _IsTestFilename(filename):
45704585
Returns:
45714586
True if 'filename' looks like a test, False otherwise.
45724587
"""
4573-
if (filename.endswith('_test.cc') or
4574-
filename.endswith('_unittest.cc') or
4575-
filename.endswith('_regtest.cc')):
4576-
return True
4577-
else:
4578-
return False
4588+
for test_suffix, ext in itertools.product(_test_suffixes, _nonheader_extensions):
4589+
if filename.endswith(test_suffix + '.' + ext):
4590+
return True
4591+
return False
45794592

45804593

45814594
def _ClassifyInclude(fileinfo, include, is_system):
@@ -4679,11 +4692,16 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
46794692
error(filename, linenum, 'build/include', 4,
46804693
'"%s" already included at %s:%s' %
46814694
(include, filename, duplicate_line))
4682-
elif (include.endswith('.cc') and
4695+
return
4696+
4697+
for extension in _nonheader_extensions:
4698+
if (include.endswith('.' + extension) and
46834699
os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)):
4684-
error(filename, linenum, 'build/include', 4,
4685-
'Do not include .cc files from other packages')
4686-
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):
46874705
include_state.include_list[-1].append((include, linenum))
46884706

46894707
# We want to ensure that headers appear in the right order:
@@ -4833,7 +4851,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
48334851
CheckGlobalStatic(filename, clean_lines, linenum, error)
48344852
CheckPrintf(filename, clean_lines, linenum, error)
48354853

4836-
if file_extension == 'h':
4854+
if file_extension in _header_extensions:
48374855
# TODO(unknown): check that 1-arg constructors are explicit.
48384856
# How to tell it's a constructor?
48394857
# (handled in CheckForNonStandardConstructs for now)
@@ -4940,7 +4958,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
49404958
# Check for use of unnamed namespaces in header files. Registration
49414959
# macros are typically OK, so we allow use of "namespace {" on lines
49424960
# that end with backslashes.
4943-
if (file_extension == 'h'
4961+
if (file_extension in _header_extensions
49444962
and Search(r'\bnamespace\s*{', line)
49454963
and line[-1] != '\\'):
49464964
error(filename, linenum, 'build/namespaces', 4,
@@ -5573,28 +5591,32 @@ def FilesBelongToSameModule(filename_cc, filename_h):
55735591
some false positives. This should be sufficiently rare in practice.
55745592
55755593
Args:
5576-
filename_cc: is the path for the .cc file
5594+
filename_cc: is the path for the source (e.g. .cc) file
55775595
filename_h: is the path for the header path
55785596
55795597
Returns:
55805598
Tuple with a bool and a string:
55815599
bool: True if filename_cc and filename_h belong to the same module.
55825600
string: the additional prefix needed to open the header file.
55835601
"""
5602+
fileinfo_cc = FileInfo(filename_cc)
5603+
if not fileinfo_cc.Extension().lstrip('.') in _nonheader_extensions:
5604+
return (False, '')
55845605

5585-
if not filename_cc.endswith('.cc'):
5606+
fileinfo_h = FileInfo(filename_h)
5607+
if not fileinfo_h.Extension().lstrip('.') in _header_extensions:
55865608
return (False, '')
5587-
filename_cc = filename_cc[:-len('.cc')]
5588-
if filename_cc.endswith('_unittest'):
5589-
filename_cc = filename_cc[:-len('_unittest')]
5590-
elif filename_cc.endswith('_test'):
5591-
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+
55925616
filename_cc = filename_cc.replace('/public/', '/')
55935617
filename_cc = filename_cc.replace('/internal/', '/')
55945618

5595-
if not filename_h.endswith('.h'):
5596-
return (False, '')
5597-
filename_h = filename_h[:-len('.h')]
5619+
filename_h = filename_h[:-(len(fileinfo_h.Extension()))]
55985620
if filename_h.endswith('-inl'):
55995621
filename_h = filename_h[:-len('-inl')]
56005622
filename_h = filename_h.replace('/public/', '/')
@@ -5716,8 +5738,10 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
57165738
# didn't include it in the .h file.
57175739
# TODO(unknown): Do a better job of finding .h files so we are confident that
57185740
# not having the .h file means there isn't one.
5719-
if filename.endswith('.cc') and not header_found:
5720-
return
5741+
if not header_found:
5742+
for extension in _nonheader_extensions:
5743+
if filename.endswith('.' + extension):
5744+
return
57215745

57225746
# All the lines have been processed, report the errors found.
57235747
for required_header_unstripped in required:
@@ -6056,7 +6080,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60566080
RemoveMultiLineComments(filename, lines, error)
60576081
clean_lines = CleansedLines(lines)
60586082

6059-
if file_extension == 'h':
6083+
if file_extension in _header_extensions:
60606084
CheckForHeaderGuard(filename, clean_lines, error)
60616085

60626086
for line in range(clean_lines.NumLines()):
@@ -6069,7 +6093,7 @@ def ProcessFileData(filename, file_extension, lines, error,
60696093
CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
60706094

60716095
# Check that the .cc file has included its header if it exists.
6072-
if file_extension == 'cc':
6096+
if file_extension in _nonheader_extensions:
60736097
CheckHeaderFileIncluded(filename, include_state, error)
60746098

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

0 commit comments

Comments
 (0)