Configurable header extensions

Fix for #50, #79 and  #113
This commit is contained in:
LukeCz 2016-09-24 13:27:35 -05:00
parent 1342002613
commit 7197a244ea

47
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
@ -161,6 +170,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,28 @@ _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 = None
# {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):
if _hpp_headers and file_extension in _hpp_headers:
return True
else:
return file_extension == 'h'
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 +4302,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 +4652,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 +4759,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 +5849,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 +5932,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 +6079,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 +6121,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.')