Merge pull request #183 from LukeCz/hpp-headers

Configurable header extensions
This commit is contained in:
Elliot Glaysher 2016-09-27 10:06:56 -07:00 committed by GitHub
commit 389efa293d
2 changed files with 48 additions and 6 deletions

44
cpplint/cpplint.py vendored
View File

@ -56,7 +56,7 @@ import unicodedata
_USAGE = """ _USAGE = """
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
[--counting=total|toplevel|detailed] [--root=subdir] [--counting=total|toplevel|detailed] [--root=subdir]
[--linelength=digits] [--linelength=digits] [--headers=x,y,...]
<file> [file] ... <file> [file] ...
The style guidelines this tries to follow are those in The style guidelines this tries to follow are those in
@ -134,6 +134,14 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
Examples: Examples:
--extensions=hpp,cpp --extensions=hpp,cpp
headers=x,y,...
The header extensions that cpplint will treat as .h in checks. Values are
automatically added to --extensions list.
Examples:
--headers=hpp,hxx
--headers=hpp
cpplint.py supports per-directory configurations specified in CPPLINT.cfg cpplint.py supports per-directory configurations specified in CPPLINT.cfg
files. CPPLINT.cfg file can contain a number of key=value pairs. files. CPPLINT.cfg file can contain a number of key=value pairs.
Currently the following options are supported: Currently the following options are supported:
@ -143,6 +151,7 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
exclude_files=regex exclude_files=regex
linelength=80 linelength=80
root=subdir root=subdir
headers=x,y,...
"set noparent" option prevents cpplint from traversing directory tree "set noparent" option prevents cpplint from traversing directory tree
upwards looking for more .cfg files in parent directories. This option upwards looking for more .cfg files in parent directories. This option
@ -160,6 +169,9 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
The "root" option is similar in function to the --root flag (see example The "root" option is similar in function to the --root flag (see example
above). above).
The "headers" option is similar in function to the --headers flag
(see example above).
CPPLINT.cfg has an effect on files in the same directory and all CPPLINT.cfg has an effect on files in the same directory and all
sub-directories, unless overridden by a nested configuration file. sub-directories, unless overridden by a nested configuration file.
@ -536,10 +548,25 @@ _line_length = 80
# This is set by --extensions flag. # This is set by --extensions flag.
_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) _valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh'])
# Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc.
# This is set by --headers flag.
_hpp_headers = set(['h'])
# {str, bool}: a map from error categories to booleans which indicate if the # {str, bool}: a map from error categories to booleans which indicate if the
# category should be suppressed for every line. # category should be suppressed for every line.
_global_error_suppressions = {} _global_error_suppressions = {}
def ProcessHppHeadersOption(val):
global _hpp_headers
try:
_hpp_headers = set(val.split(','))
# Automatically append to extensions list so it does not have to be set 2 times
_valid_extensions.update(_hpp_headers)
except ValueError:
PrintUsage('Header extensions must be comma seperated list.')
def IsHeaderExtension(file_extension):
return file_extension in _hpp_headers
def ParseNolintSuppressions(filename, raw_line, linenum, error): def ParseNolintSuppressions(filename, raw_line, linenum, error):
"""Updates the global list of line error-suppressions. """Updates the global list of line error-suppressions.
@ -4272,7 +4299,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
# Check if the line is a header guard. # Check if the line is a header guard.
is_header_guard = False is_header_guard = False
if file_extension == 'h': if IsHeaderExtension(file_extension):
cppvar = GetHeaderGuardCPPVariable(filename) cppvar = GetHeaderGuardCPPVariable(filename)
if (line.startswith('#ifndef %s' % cppvar) or if (line.startswith('#ifndef %s' % cppvar) or
line.startswith('#define %s' % cppvar) or line.startswith('#define %s' % cppvar) or
@ -4622,7 +4649,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
CheckGlobalStatic(filename, clean_lines, linenum, error) CheckGlobalStatic(filename, clean_lines, linenum, error)
CheckPrintf(filename, clean_lines, linenum, error) CheckPrintf(filename, clean_lines, linenum, error)
if file_extension == 'h': if IsHeaderExtension(file_extension):
# TODO(unknown): check that 1-arg constructors are explicit. # TODO(unknown): check that 1-arg constructors are explicit.
# How to tell it's a constructor? # How to tell it's a constructor?
# (handled in CheckForNonStandardConstructs for now) # (handled in CheckForNonStandardConstructs for now)
@ -4729,7 +4756,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
# Check for use of unnamed namespaces in header files. Registration # Check for use of unnamed namespaces in header files. Registration
# macros are typically OK, so we allow use of "namespace {" on lines # macros are typically OK, so we allow use of "namespace {" on lines
# that end with backslashes. # that end with backslashes.
if (file_extension == 'h' if (IsHeaderExtension(file_extension)
and Search(r'\bnamespace\s*{', line) and Search(r'\bnamespace\s*{', line)
and line[-1] != '\\'): and line[-1] != '\\'):
error(filename, linenum, 'build/namespaces', 4, error(filename, linenum, 'build/namespaces', 4,
@ -5819,7 +5846,7 @@ def ProcessFileData(filename, file_extension, lines, error,
RemoveMultiLineComments(filename, lines, error) RemoveMultiLineComments(filename, lines, error)
clean_lines = CleansedLines(lines) clean_lines = CleansedLines(lines)
if file_extension == 'h': if IsHeaderExtension(file_extension):
CheckForHeaderGuard(filename, clean_lines, error) CheckForHeaderGuard(filename, clean_lines, error)
for line in xrange(clean_lines.NumLines()): for line in xrange(clean_lines.NumLines()):
@ -5902,6 +5929,8 @@ def ProcessConfigOverrides(filename):
elif name == 'root': elif name == 'root':
global _root global _root
_root = val _root = val
elif name == 'headers':
ProcessHppHeadersOption(val)
else: else:
sys.stderr.write( sys.stderr.write(
'Invalid configuration option (%s) in file %s\n' % 'Invalid configuration option (%s) in file %s\n' %
@ -6047,7 +6076,8 @@ def ParseArguments(args):
'filter=', 'filter=',
'root=', 'root=',
'linelength=', 'linelength=',
'extensions=']) 'extensions=',
'headers='])
except getopt.GetoptError: except getopt.GetoptError:
PrintUsage('Invalid arguments.') PrintUsage('Invalid arguments.')
@ -6088,6 +6118,8 @@ def ParseArguments(args):
_valid_extensions = set(val.split(',')) _valid_extensions = set(val.split(','))
except ValueError: except ValueError:
PrintUsage('Extensions must be comma seperated list.') PrintUsage('Extensions must be comma seperated list.')
elif opt == '--headers':
ProcessHppHeadersOption(val)
if not filenames: if not filenames:
PrintUsage('No files were specified.') PrintUsage('No files were specified.')

View File

@ -3778,6 +3778,7 @@ class CpplintTest(CpplintTestBase):
old_error_categories = cpplint._ERROR_CATEGORIES old_error_categories = cpplint._ERROR_CATEGORIES
old_output_format = cpplint._cpplint_state.output_format old_output_format = cpplint._cpplint_state.output_format
old_verbose_level = cpplint._cpplint_state.verbose_level old_verbose_level = cpplint._cpplint_state.verbose_level
old_headers = cpplint._hpp_headers
old_filters = cpplint._cpplint_state.filters old_filters = cpplint._cpplint_state.filters
old_line_length = cpplint._line_length old_line_length = cpplint._line_length
old_valid_extensions = cpplint._valid_extensions old_valid_extensions = cpplint._valid_extensions
@ -3795,6 +3796,7 @@ class CpplintTest(CpplintTestBase):
self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo']) self.assertRaises(SystemExit, cpplint.ParseArguments, ['--filter=foo'])
self.assertRaises(SystemExit, cpplint.ParseArguments, self.assertRaises(SystemExit, cpplint.ParseArguments,
['--filter=+a,b,-c']) ['--filter=+a,b,-c'])
self.assertRaises(SystemExit, cpplint.ParseArguments, ['--headers'])
self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc'])) self.assertEquals(['foo.cc'], cpplint.ParseArguments(['foo.cc']))
self.assertEquals(old_output_format, cpplint._cpplint_state.output_format) self.assertEquals(old_output_format, cpplint._cpplint_state.output_format)
@ -3837,6 +3839,13 @@ class CpplintTest(CpplintTestBase):
self.assertEqual(['foo.h'], self.assertEqual(['foo.h'],
cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h'])) cpplint.ParseArguments(['--extensions=hpp,cpp,cpp', 'foo.h']))
self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions) self.assertEqual(set(['hpp', 'cpp']), cpplint._valid_extensions)
self.assertEqual(set(['h']), cpplint._hpp_headers) # Default value
self.assertEqual(['foo.h'],
cpplint.ParseArguments(['--extensions=cpp,cpp', '--headers=hpp,h', 'foo.h']))
self.assertEqual(set(['hpp', 'h']), cpplint._hpp_headers)
self.assertEqual(set(['hpp', 'h', 'cpp']), cpplint._valid_extensions)
finally: finally:
cpplint._USAGE = old_usage cpplint._USAGE = old_usage
cpplint._ERROR_CATEGORIES = old_error_categories cpplint._ERROR_CATEGORIES = old_error_categories
@ -3845,6 +3854,7 @@ class CpplintTest(CpplintTestBase):
cpplint._cpplint_state.filters = old_filters cpplint._cpplint_state.filters = old_filters
cpplint._line_length = old_line_length cpplint._line_length = old_line_length
cpplint._valid_extensions = old_valid_extensions cpplint._valid_extensions = old_valid_extensions
cpplint._hpp_headers = old_headers
def testLineLength(self): def testLineLength(self):
old_line_length = cpplint._line_length old_line_length = cpplint._line_length