aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2017-11-11 03:02:09 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-11-11 03:02:09 +0000
commit2b84ffa3a1c9491fd07b07043cd69499be879d79 (patch)
treedcf6315c3d25117e7e20ecbb7ab6e8730f9a6d8a
parenta430574984119c56d424ace14b0572884ab78c95 (diff)
parentf43a5e4800d3d4a6fb5f2284682a618409ede3dc (diff)
downloadrepohooks-2b84ffa3a1c9491fd07b07043cd69499be879d79.tar.gz
cpplint: sync with latest Google version
am: f43a5e4800 Change-Id: Id8aa9151ea1f90b99c71d891980f327a6111330f
-rwxr-xr-xtools/cpplint.py216
-rwxr-xr-xtools/cpplint.py-update1
-rw-r--r--tools/pylintrc1
3 files changed, 164 insertions, 54 deletions
diff --git a/tools/cpplint.py b/tools/cpplint.py
index 796a4a4..c08cf6f 100755
--- a/tools/cpplint.py
+++ b/tools/cpplint.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# pylint: skip-file
#
# Copyright (c) 2009 Google Inc. All rights reserved.
#
@@ -56,7 +57,8 @@ import unicodedata
_USAGE = """
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
[--counting=total|toplevel|detailed] [--root=subdir]
- [--linelength=digits]
+ [--linelength=digits] [--headers=x,y,...]
+ [--quiet]
<file> [file] ...
The style guidelines this tries to follow are those in
@@ -83,6 +85,9 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
verbose=#
Specify a number 0-5 to restrict errors to certain verbosity levels.
+ quiet
+ Don't print anything if no errors are found.
+
filter=-x,+y,...
Specify a comma-separated list of category-filters to apply: only
error messages whose category names pass the filters will be printed.
@@ -114,12 +119,13 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
ignored.
Examples:
- Assuming that src/.git exists, the header guard CPP variables for
- src/chrome/browser/ui/browser.h are:
+ Assuming that top/src/.git exists (and cwd=top/src), the header guard
+ CPP variables for top/src/chrome/browser/ui/browser.h are:
No flag => CHROME_BROWSER_UI_BROWSER_H_
--root=chrome => BROWSER_UI_BROWSER_H_
--root=chrome/browser => UI_BROWSER_H_
+ --root=.. => SRC_CHROME_BROWSER_UI_BROWSER_H_
linelength=digits
This is the allowed line length for the project. The default value is
@@ -134,6 +140,14 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
Examples:
--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
files. CPPLINT.cfg file can contain a number of key=value pairs.
Currently the following options are supported:
@@ -143,6 +157,7 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
exclude_files=regex
linelength=80
root=subdir
+ headers=x,y,...
"set noparent" option prevents cpplint from traversing directory tree
upwards looking for more .cfg files in parent directories. This option
@@ -159,7 +174,10 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
"linelength" allows to specify the allowed line length for the project.
The "root" option is similar in function to the --root flag (see example
- above).
+ above). Paths are relative to the directory of the CPPLINT.cfg.
+
+ 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
sub-directories, unless overridden by a nested configuration file.
@@ -527,6 +545,7 @@ _error_suppressions = {}
# The root directory used for deriving header guard CPP variable.
# This is set by --root flag.
_root = None
+_root_debug = False
# The allowed line length of files.
# This is set by --linelength flag.
@@ -536,10 +555,25 @@ _line_length = 80
# This is set by --extensions flag.
_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
# category should be suppressed for every line.
_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):
"""Updates the global list of line error-suppressions.
@@ -832,6 +866,7 @@ class _CppLintState(object):
self._filters_backup = self.filters[:]
self.counting = 'total' # In what way are we counting errors?
self.errors_by_category = {} # string to int dict storing error counts
+ self.quiet = False # Suppress non-error messagess?
# output format:
# "emacs" - format that emacs can parse (default)
@@ -842,6 +877,12 @@ class _CppLintState(object):
"""Sets the output format for errors."""
self.output_format = output_format
+ def SetQuiet(self, quiet):
+ """Sets the module's quiet settings, and returns the previous setting."""
+ last_quiet = self.quiet
+ self.quiet = quiet
+ return last_quiet
+
def SetVerboseLevel(self, level):
"""Sets the module's verbosity, and returns the previous setting."""
last_verbose_level = self.verbose_level
@@ -909,7 +950,7 @@ class _CppLintState(object):
for category, count in self.errors_by_category.iteritems():
sys.stderr.write('Category \'%s\' errors found: %d\n' %
(category, count))
- sys.stderr.write('Total errors found: %d\n' % self.error_count)
+ sys.stdout.write('Total errors found: %d\n' % self.error_count)
_cpplint_state = _CppLintState()
@@ -923,6 +964,14 @@ def _SetOutputFormat(output_format):
"""Sets the module's output format."""
_cpplint_state.SetOutputFormat(output_format)
+def _Quiet():
+ """Return's the module's quiet setting."""
+ return _cpplint_state.quiet
+
+def _SetQuiet(quiet):
+ """Set the module's quiet status, and return previous setting."""
+ return _cpplint_state.SetQuiet(quiet)
+
def _VerboseLevel():
"""Returns the module's verbosity setting."""
@@ -1184,8 +1233,8 @@ def Error(filename, linenum, category, confidence, message):
if _ShouldPrintError(category, confidence, linenum):
_cpplint_state.IncrementErrorCount(category)
if _cpplint_state.output_format == 'vs7':
- sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
- filename, linenum, message, category, confidence))
+ sys.stderr.write('%s(%s): error cpplint: [%s] %s [%d]\n' % (
+ filename, linenum, category, message, confidence))
elif _cpplint_state.output_format == 'eclipse':
sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
filename, linenum, message, category, confidence))
@@ -1727,6 +1776,30 @@ def GetIndentLevel(line):
else:
return 0
+def PathSplitToList(path):
+ """Returns the path split into a list by the separator.
+
+ Args:
+ path: An absolute or relative path (e.g. '/a/b/c/' or '../a')
+
+ Returns:
+ A list of path components (e.g. ['a', 'b', 'c]).
+ """
+ lst = []
+ while True:
+ (head, tail) = os.path.split(path)
+ if head == path: # absolute paths end
+ lst.append(head)
+ break
+ if tail == path: # relative paths end
+ lst.append(tail)
+ break
+
+ path = head
+ lst.append(tail)
+
+ lst.reverse()
+ return lst
def GetHeaderGuardCPPVariable(filename):
"""Returns the CPP variable that should be used as a header guard.
@@ -1749,13 +1822,58 @@ def GetHeaderGuardCPPVariable(filename):
fileinfo = FileInfo(filename)
file_path_from_root = fileinfo.RepositoryName()
- if _root:
- suffix = os.sep
- # On Windows using directory separator will leave us with
- # "bogus escape error" unless we properly escape regex.
- if suffix == '\\':
- suffix += '\\'
- file_path_from_root = re.sub('^' + _root + suffix, '', file_path_from_root)
+
+ def FixupPathFromRoot():
+ if _root_debug:
+ sys.stderr.write("\n_root fixup, _root = '%s', repository name = '%s'\n"
+ %(_root, fileinfo.RepositoryName()))
+
+ # Process the file path with the --root flag if it was set.
+ if not _root:
+ if _root_debug:
+ sys.stderr.write("_root unspecified\n")
+ return file_path_from_root
+
+ def StripListPrefix(lst, prefix):
+ # f(['x', 'y'], ['w, z']) -> None (not a valid prefix)
+ if lst[:len(prefix)] != prefix:
+ return None
+ # f(['a, 'b', 'c', 'd'], ['a', 'b']) -> ['c', 'd']
+ return lst[(len(prefix)):]
+
+ # root behavior:
+ # --root=subdir , lstrips subdir from the header guard
+ maybe_path = StripListPrefix(PathSplitToList(file_path_from_root),
+ PathSplitToList(_root))
+
+ if _root_debug:
+ sys.stderr.write("_root lstrip (maybe_path=%s, file_path_from_root=%s," +
+ " _root=%s)\n" %(maybe_path, file_path_from_root, _root))
+
+ if maybe_path:
+ return os.path.join(*maybe_path)
+
+ # --root=.. , will prepend the outer directory to the header guard
+ full_path = fileinfo.FullName()
+ root_abspath = os.path.abspath(_root)
+
+ maybe_path = StripListPrefix(PathSplitToList(full_path),
+ PathSplitToList(root_abspath))
+
+ if _root_debug:
+ sys.stderr.write("_root prepend (maybe_path=%s, full_path=%s, " +
+ "root_abspath=%s)\n" %(maybe_path, full_path, root_abspath))
+
+ if maybe_path:
+ return os.path.join(*maybe_path)
+
+ if _root_debug:
+ sys.stderr.write("_root ignore, returning %s\n" %(file_path_from_root))
+
+ # --root=FAKE_DIR is ignored
+ return file_path_from_root
+
+ file_path_from_root = FixupPathFromRoot()
return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_'
@@ -2752,7 +2870,8 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
# Look for single-argument constructors that aren't marked explicit.
# Technically a valid construct, but against style.
explicit_constructor_match = Match(
- r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*'
+ r'\s+(?:(?:inline|constexpr)\s+)*(explicit\s+)?'
+ r'(?:(?:inline|constexpr)\s+)*%s\s*'
r'\(((?:[^()]|\([^()]*\))*)\)'
% re.escape(base_classname),
line)
@@ -3044,36 +3163,6 @@ def CheckComment(line, filename, linenum, next_line_start, error):
'Should have a space between // and comment')
-def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
- """Checks for improper use of DISALLOW* macros.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- nesting_state: A NestingState instance which maintains information about
- the current stack of nested blocks being parsed.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum] # get rid of comments and strings
-
- matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|'
- r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)
- if not matched:
- return
- if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):
- if nesting_state.stack[-1].access != 'private':
- error(filename, linenum, 'readability/constructors', 3,
- '%s must be in the private: section' % matched.group(1))
-
- else:
- # Found DISALLOW* macro outside a class declaration, or perhaps it
- # was used inside a function when it should have been part of the
- # class declaration. We could issue a warning here, but it
- # probably resulted in a compiler error already.
- pass
-
-
def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
"""Checks for the correctness of various spacing issues in the code.
@@ -4271,7 +4360,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 IsHeaderExtension(file_extension):
cppvar = GetHeaderGuardCPPVariable(filename)
if (line.startswith('#ifndef %s' % cppvar) or
line.startswith('#define %s' % cppvar) or
@@ -4310,7 +4399,6 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
CheckBraces(filename, clean_lines, linenum, error)
CheckTrailingSemicolon(filename, clean_lines, linenum, error)
CheckEmptyBlockBody(filename, clean_lines, linenum, error)
- CheckAccess(filename, clean_lines, linenum, nesting_state, error)
CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
CheckOperatorSpacing(filename, clean_lines, linenum, error)
CheckParenthesisSpacing(filename, clean_lines, linenum, error)
@@ -4621,7 +4709,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 IsHeaderExtension(file_extension):
# TODO(unknown): check that 1-arg constructors are explicit.
# How to tell it's a constructor?
# (handled in CheckForNonStandardConstructs for now)
@@ -4728,7 +4816,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 (IsHeaderExtension(file_extension)
and Search(r'\bnamespace\s*{', line)
and line[-1] != '\\'):
error(filename, linenum, 'build/namespaces', 4,
@@ -5818,7 +5906,7 @@ def ProcessFileData(filename, file_extension, lines, error,
RemoveMultiLineComments(filename, lines, error)
clean_lines = CleansedLines(lines)
- if file_extension == 'h':
+ if IsHeaderExtension(file_extension):
CheckForHeaderGuard(filename, clean_lines, error)
for line in xrange(clean_lines.NumLines()):
@@ -5887,6 +5975,9 @@ def ProcessConfigOverrides(filename):
if base_name:
pattern = re.compile(val)
if pattern.match(base_name):
+ if _cpplint_state.quiet:
+ # Suppress "Ignoring file" warning when using --quiet.
+ return False
sys.stderr.write('Ignoring "%s": file excluded by "%s". '
'File path component "%s" matches '
'pattern "%s"\n' %
@@ -5900,7 +5991,10 @@ def ProcessConfigOverrides(filename):
sys.stderr.write('Line length must be numeric.')
elif name == 'root':
global _root
- _root = val
+ # root directories are specified relative to CPPLINT.cfg dir.
+ _root = os.path.join(os.path.dirname(cfg_file), val)
+ elif name == 'headers':
+ ProcessHppHeadersOption(val)
else:
sys.stderr.write(
'Invalid configuration option (%s) in file %s\n' %
@@ -5935,6 +6029,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
_SetVerboseLevel(vlevel)
_BackupFilters()
+ old_errors = _cpplint_state.error_count
if not ProcessConfigOverrides(filename):
_RestoreFilters()
@@ -6003,7 +6098,10 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
Error(filename, linenum, 'whitespace/newline', 1,
'Unexpected \\r (^M) found; better to use only \\n')
- sys.stderr.write('Done processing %s\n' % filename)
+ # Suppress printing anything if --quiet was passed unless the error
+ # count has increased after processing this file.
+ if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count:
+ sys.stdout.write('Done processing %s\n' % filename)
_RestoreFilters()
@@ -6046,13 +6144,16 @@ def ParseArguments(args):
'filter=',
'root=',
'linelength=',
- 'extensions='])
+ 'extensions=',
+ 'headers=',
+ 'quiet'])
except getopt.GetoptError:
PrintUsage('Invalid arguments.')
verbosity = _VerboseLevel()
output_format = _OutputFormat()
filters = ''
+ quiet = _Quiet()
counting_style = ''
for (opt, val) in opts:
@@ -6062,6 +6163,8 @@ def ParseArguments(args):
if val not in ('emacs', 'vs7', 'eclipse'):
PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')
output_format = val
+ elif opt == '--quiet':
+ quiet = True
elif opt == '--verbose':
verbosity = int(val)
elif opt == '--filter':
@@ -6087,11 +6190,14 @@ def ParseArguments(args):
_valid_extensions = set(val.split(','))
except ValueError:
PrintUsage('Extensions must be comma seperated list.')
+ elif opt == '--headers':
+ ProcessHppHeadersOption(val)
if not filenames:
PrintUsage('No files were specified.')
_SetOutputFormat(output_format)
+ _SetQuiet(quiet)
_SetVerboseLevel(verbosity)
_SetFilters(filters)
_SetCountingStyle(counting_style)
@@ -6112,7 +6218,9 @@ def main():
_cpplint_state.ResetErrorCounts()
for filename in filenames:
ProcessFile(filename, _cpplint_state.verbose_level)
- _cpplint_state.PrintErrorCounts()
+ # If --quiet is passed, suppress printing error count unless there are errors.
+ if not _cpplint_state.quiet or _cpplint_state.error_count > 0:
+ _cpplint_state.PrintErrorCounts()
sys.exit(_cpplint_state.error_count > 0)
diff --git a/tools/cpplint.py-update b/tools/cpplint.py-update
index 1767e41..4af4389 100755
--- a/tools/cpplint.py-update
+++ b/tools/cpplint.py-update
@@ -47,6 +47,7 @@ main() {
# Download cpplint.py from upstream.
local cpplint_py="${SCRIPT_DIR}/cpplint.py"
wget "${GITHUB_URL}/cpplint/cpplint.py" -O "${cpplint_py}"
+ sed -i '2i# pylint: skip-file' "${cpplint_py}"
chmod +x "${cpplint_py}"
}
diff --git a/tools/pylintrc b/tools/pylintrc
index 599bb88..704b21b 100644
--- a/tools/pylintrc
+++ b/tools/pylintrc
@@ -79,6 +79,7 @@ confidence=
# We leave many of the style warnings to judgement/peer review.
disable=
fixme,
+ file-ignored,
invalid-name,
locally-disabled,
locally-enabled,