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

Add options to change extensions to cli arguments and the CPPLINT.cfg option file #17

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 60 additions & 21 deletions cpplint.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,23 @@
import sys
import unicodedata

# Files with any of these extensions are considered to be
# header files (and will undergo different style checks).
# This set can be extended by using the --headers
# option (also supported in CPPLINT.cfg)
_header_extensions = ['h', 'hpp', 'hxx', 'h++', 'cuh']


# The allowed extensions for file names
# This is set by --extensions flag.
_valid_extensions = set(['c', 'cc', 'cpp', 'cxx', 'c++', 'h', 'hpp', 'hxx',
'h++'])
_valid_extensions = set(['c', 'cc', 'cpp', 'cxx', 'c++', 'cu'] + _header_extensions)


_USAGE = """
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
[--counting=total|toplevel|detailed] [--root=subdir]
[--linelength=digits]
[--headers=ext1,ext2]
<file> [file] ...

The style guidelines this tries to follow are those in
Expand Down Expand Up @@ -139,6 +147,13 @@
Examples:
--extensions=hpp,cpp

headers=extension,extension,...
The allowed header extensions that cpplint will consider to be header files
(by default, only .h files will be assumed to be headers)

Examples:
--headers=h,hpp

cpplint.py supports per-directory configurations specified in CPPLINT.cfg
files. CPPLINT.cfg file can contain a number of key=value pairs.
Currently the following options are supported:
Expand Down Expand Up @@ -1804,21 +1819,22 @@ def CheckHeaderFileIncluded(filename, include_state, error):
return

fileinfo = FileInfo(filename)
headerfile = filename[0:len(filename) - 2] + 'h'
if not os.path.exists(headerfile):
return
headername = FileInfo(headerfile).RepositoryName()
first_include = 0
for section_list in include_state.include_list:
for f in section_list:
if headername in f[0] or f[0] in headername:
return
if not first_include:
first_include = f[1]
for ext in _header_extensions:
headerfile = filename[0:len(filename) - 2] + ext
if not os.path.exists(headerfile):
continue
headername = FileInfo(headerfile).RepositoryName()
first_include = None
for section_list in include_state.include_list:
for f in section_list:
if headername in f[0] or f[0] in headername:
return
if not first_include:
first_include = f[1]

error(filename, first_include, 'build/include', 5,
'%s should include its header file %s' % (fileinfo.RepositoryName(),
headername))
error(filename, first_include, 'build/include', 5,
'%s should include its header file %s' % (fileinfo.RepositoryName(),
headername))


def CheckForBadCharacters(filename, lines, error):
Expand Down Expand Up @@ -4459,7 +4475,7 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,

# Check if the line is a header guard.
is_header_guard = False
if file_extension == 'h':
if file_extension in _header_extensions:
cppvar = GetHeaderGuardCPPVariable(filename)
if (line.startswith('#ifndef %s' % cppvar) or
line.startswith('#define %s' % cppvar) or
Expand Down Expand Up @@ -4828,7 +4844,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
CheckGlobalStatic(filename, clean_lines, linenum, error)
CheckPrintf(filename, clean_lines, linenum, error)

if file_extension == 'h':
if file_extension in _header_extensions:
# TODO(unknown): check that 1-arg constructors are explicit.
# How to tell it's a constructor?
# (handled in CheckForNonStandardConstructs for now)
Expand Down Expand Up @@ -4935,7 +4951,7 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
# Check for use of unnamed namespaces in header files. Registration
# macros are typically OK, so we allow use of "namespace {" on lines
# that end with backslashes.
if (file_extension == 'h'
if (file_extension in _header_extensions
and Search(r'\bnamespace\s*{', line)
and line[-1] != '\\'):
error(filename, linenum, 'build/namespaces', 4,
Expand Down Expand Up @@ -6051,7 +6067,7 @@ def ProcessFileData(filename, file_extension, lines, error,
RemoveMultiLineComments(filename, lines, error)
clean_lines = CleansedLines(lines)

if file_extension == 'h':
if file_extension in _header_extensions:
CheckForHeaderGuard(filename, clean_lines, error)

for line in range(clean_lines.NumLines()):
Expand Down Expand Up @@ -6131,6 +6147,22 @@ def ProcessConfigOverrides(filename):
_line_length = int(val)
except ValueError:
sys.stderr.write('Line length must be numeric.')
elif name == 'extensions':
global _valid_extensions
try:
extensions = [ext.strip() for ext in val.split(',')]
_valid_extensions = _valid_extensions.union(set(extensions))
except ValueError:
sys.stderr.write('Extensions should be a comma-separated list of values;'
'for example: extensions=hpp,cpp\n'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the example, I'd write ','.join(_valid_extensions), so if (when) it's copy-pasted, it can be used as a starting point that gives the same behavior as the default behavior.

'This could not be parsed: "%s"' % (val,))
try:
extensions = [ext.strip() for ext in val.split(',')]
_valid_extensions = _valid_extensions.union(set(extensions))
except ValueError:
sys.stderr.write('Extensions should be a comma-separated list of values;'
'for example: extensions=hpp,cpp\n'
'This could not be parsed: "%s"' % (values,))
else:
sys.stderr.write(
'Invalid configuration option (%s) in file %s\n' %
Expand Down Expand Up @@ -6277,7 +6309,8 @@ def ParseArguments(args):
'filter=',
'root=',
'linelength=',
'extensions='])
'extensions=',
'headers='])
except getopt.GetoptError:
PrintUsage('Invalid arguments.')

Expand Down Expand Up @@ -6318,6 +6351,12 @@ def ParseArguments(args):
_valid_extensions = set(val.split(','))
except ValueError:
PrintUsage('Extensions must be comma seperated list.')
elif opt == '--headers':
global _header_extensions
try:
_header_extensions = set(val.split(','))
except ValueError:
PrintUsage('Extensions must be comma seperated list.')

if not filenames:
PrintUsage('No files were specified.')
Expand Down