tools: bump cpplint.py to 1.4.4
Refs: https://github.com/cpplint/cpplint/releases/tag/1.4.4 PR-URL: https://github.com/nodejs/node/pull/27098 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
This commit is contained in:
parent
112cc7c275
commit
1302e0174a
516
tools/cpplint.py
vendored
516
tools/cpplint.py
vendored
@ -52,46 +52,38 @@ import re
|
|||||||
import sre_compile
|
import sre_compile
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
import sysconfig
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree
|
||||||
|
|
||||||
# if empty, use defaults
|
|
||||||
_header_extensions = set([])
|
|
||||||
|
|
||||||
# if empty, use defaults
|
# if empty, use defaults
|
||||||
_valid_extensions = set([])
|
_valid_extensions = set([])
|
||||||
|
|
||||||
|
__VERSION__ = '1.4.4'
|
||||||
|
|
||||||
# Files with any of these extensions are considered to be
|
try:
|
||||||
# header files (and will undergo different style checks).
|
xrange # Python 2
|
||||||
# This set can be extended by using the --headers
|
except NameError:
|
||||||
# option (also supported in CPPLINT.cfg)
|
# -- pylint: disable=redefined-builtin
|
||||||
def GetHeaderExtensions():
|
xrange = range # Python 3
|
||||||
if not _header_extensions:
|
|
||||||
return set(['h', 'hh', 'hpp', 'hxx', 'h++', 'cuh'])
|
|
||||||
return _header_extensions
|
|
||||||
|
|
||||||
# The allowed extensions for file names
|
|
||||||
# This is set by --extensions flag
|
|
||||||
def GetAllExtensions():
|
|
||||||
if not _valid_extensions:
|
|
||||||
return GetHeaderExtensions().union(set(['c', 'cc', 'cpp', 'cxx', 'c++', 'cu']))
|
|
||||||
return _valid_extensions
|
|
||||||
|
|
||||||
def GetNonHeaderExtensions():
|
|
||||||
return GetAllExtensions().difference(GetHeaderExtensions())
|
|
||||||
|
|
||||||
|
|
||||||
_USAGE = """
|
_USAGE = """
|
||||||
Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
||||||
[--filter=-x,+y,...]
|
[--filter=-x,+y,...]
|
||||||
[--counting=total|toplevel|detailed] [--repository=path]
|
[--counting=total|toplevel|detailed] [--root=subdir]
|
||||||
[--root=subdir] [--linelength=digits] [--recursive]
|
[--repository=path]
|
||||||
|
[--linelength=digits] [--headers=x,y,...]
|
||||||
|
[--recursive]
|
||||||
[--exclude=path]
|
[--exclude=path]
|
||||||
[--headers=ext1,ext2]
|
|
||||||
[--extensions=hpp,cpp,...]
|
[--extensions=hpp,cpp,...]
|
||||||
|
[--quiet]
|
||||||
|
[--version]
|
||||||
<file> [file] ...
|
<file> [file] ...
|
||||||
|
|
||||||
|
Style checker for C/C++ source files.
|
||||||
|
This is a fork of the Google style checker with minor extensions.
|
||||||
|
|
||||||
The style guidelines this tries to follow are those in
|
The style guidelines this tries to follow are those in
|
||||||
https://google.github.io/styleguide/cppguide.html
|
https://google.github.io/styleguide/cppguide.html
|
||||||
|
|
||||||
@ -111,10 +103,10 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
Flags:
|
Flags:
|
||||||
|
|
||||||
output=emacs|eclipse|vs7|junit
|
output=emacs|eclipse|vs7|junit
|
||||||
By default, the output is formatted to ease emacs parsing. Output
|
By default, the output is formatted to ease emacs parsing. Visual Studio
|
||||||
compatible with eclipse (eclipse), Visual Studio (vs7), and JUnit
|
compatible output (vs7) may also be used. Further support exists for
|
||||||
XML parsers such as those used in Jenkins and Bamboo may also be
|
eclipse (eclipse), and JUnit (junit). XML parsers such as those used
|
||||||
used. Other formats are unsupported.
|
in Jenkins and Bamboo may also be used. Other formats are unsupported.
|
||||||
|
|
||||||
verbose=#
|
verbose=#
|
||||||
Specify a number 0-5 to restrict errors to certain verbosity levels.
|
Specify a number 0-5 to restrict errors to certain verbosity levels.
|
||||||
@ -122,8 +114,7 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
likely to be false positives.
|
likely to be false positives.
|
||||||
|
|
||||||
quiet
|
quiet
|
||||||
Suppress output other than linting errors, such as information about
|
Don't print anything if no errors are found.
|
||||||
which files have been processed and excluded.
|
|
||||||
|
|
||||||
filter=-x,+y,...
|
filter=-x,+y,...
|
||||||
Specify a comma-separated list of category-filters to apply: only
|
Specify a comma-separated list of category-filters to apply: only
|
||||||
@ -172,19 +163,21 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
Bob => SRC_CHROME_BROWSER_UI_BROWSER_H_
|
Bob => SRC_CHROME_BROWSER_UI_BROWSER_H_
|
||||||
|
|
||||||
root=subdir
|
root=subdir
|
||||||
The root directory used for deriving header guard CPP variables. This
|
The root directory used for deriving header guard CPP variable.
|
||||||
directory is relative to the top level directory of the repository which
|
This directory is relative to the top level directory of the repository
|
||||||
by default is determined by searching for a directory that contains .git,
|
which by default is determined by searching for a directory that contains
|
||||||
.hg, or .svn but can also be controlled with the --repository flag. If
|
.git, .hg, or .svn but can also be controlled with the --repository flag.
|
||||||
the specified directory does not exist, this flag is ignored.
|
If the specified directory does not exist, this flag is ignored.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
Assuming that src is the top level directory of the repository, the
|
Assuming that src is the top level directory of the repository (and
|
||||||
header guard CPP variables for src/chrome/browser/ui/browser.h are:
|
cwd=top/src), the header guard CPP variables for
|
||||||
|
src/chrome/browser/ui/browser.h are:
|
||||||
|
|
||||||
No flag => CHROME_BROWSER_UI_BROWSER_H_
|
No flag => CHROME_BROWSER_UI_BROWSER_H_
|
||||||
--root=chrome => BROWSER_UI_BROWSER_H_
|
--root=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
|
linelength=digits
|
||||||
This is the allowed line length for the project. The default value is
|
This is the allowed line length for the project. The default value is
|
||||||
@ -216,13 +209,15 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
Examples:
|
Examples:
|
||||||
--extensions=%s
|
--extensions=%s
|
||||||
|
|
||||||
headers=extension,extension,...
|
headers=x,y,...
|
||||||
The allowed header extensions that cpplint will consider to be header files
|
The header extensions that cpplint will treat as .h in checks. Values are
|
||||||
(by default, only files with extensions %s
|
automatically added to --extensions list.
|
||||||
will be assumed to be headers)
|
(by default, only files with extensions %s will be assumed to be headers)
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
--headers=%s
|
--headers=%s
|
||||||
|
--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.
|
||||||
@ -233,6 +228,7 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
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
|
||||||
@ -246,13 +242,16 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
a file name. If the expression matches, the file is skipped and not run
|
a file name. If the expression matches, the file is skipped and not run
|
||||||
through the linter.
|
through the linter.
|
||||||
|
|
||||||
"linelength" specifies the allowed line length for the project.
|
"linelength" allows to specify the allowed line length for the project.
|
||||||
|
|
||||||
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). 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
|
CPPLINT.cfg has an effect on files in the same directory and all
|
||||||
subdirectories, unless overridden by a nested configuration file.
|
sub-directories, unless overridden by a nested configuration file.
|
||||||
|
|
||||||
Example file:
|
Example file:
|
||||||
filter=-build/include_order,+build/include_alpha
|
filter=-build/include_order,+build/include_alpha
|
||||||
@ -261,11 +260,8 @@ Syntax: cpplint.py [--verbose=#] [--output=emacs|eclipse|vs7|junit]
|
|||||||
The above example disables build/include_order warning and enables
|
The above example disables build/include_order warning and enables
|
||||||
build/include_alpha as well as excludes all .cc from being
|
build/include_alpha as well as excludes all .cc from being
|
||||||
processed by linter, in the current directory (where the .cfg
|
processed by linter, in the current directory (where the .cfg
|
||||||
file is located) and all subdirectories.
|
file is located) and all sub-directories.
|
||||||
""" % (list(GetAllExtensions()),
|
"""
|
||||||
','.join(list(GetAllExtensions())),
|
|
||||||
GetHeaderExtensions(),
|
|
||||||
','.join(GetHeaderExtensions()))
|
|
||||||
|
|
||||||
# We categorize each error message we print. Here are the categories.
|
# We categorize each error message we print. Here are the categories.
|
||||||
# We want an explicit list so we can list them all in cpplint --filter=.
|
# We want an explicit list so we can list them all in cpplint --filter=.
|
||||||
@ -282,10 +278,9 @@ _ERROR_CATEGORIES = [
|
|||||||
'build/forward_decl',
|
'build/forward_decl',
|
||||||
'build/header_guard',
|
'build/header_guard',
|
||||||
'build/include',
|
'build/include',
|
||||||
'build/include_alpha',
|
|
||||||
'build/include_inline',
|
|
||||||
'build/include_order',
|
|
||||||
'build/include_subdir',
|
'build/include_subdir',
|
||||||
|
'build/include_alpha',
|
||||||
|
'build/include_order',
|
||||||
'build/include_what_you_use',
|
'build/include_what_you_use',
|
||||||
'build/namespaces_literals',
|
'build/namespaces_literals',
|
||||||
'build/namespaces',
|
'build/namespaces',
|
||||||
@ -299,13 +294,11 @@ _ERROR_CATEGORIES = [
|
|||||||
'readability/constructors',
|
'readability/constructors',
|
||||||
'readability/fn_size',
|
'readability/fn_size',
|
||||||
'readability/inheritance',
|
'readability/inheritance',
|
||||||
'readability/pointer_notation',
|
|
||||||
'readability/multiline_comment',
|
'readability/multiline_comment',
|
||||||
'readability/multiline_string',
|
'readability/multiline_string',
|
||||||
'readability/namespace',
|
'readability/namespace',
|
||||||
'readability/nolint',
|
'readability/nolint',
|
||||||
'readability/nul',
|
'readability/nul',
|
||||||
'readability/null_usage',
|
|
||||||
'readability/strings',
|
'readability/strings',
|
||||||
'readability/todo',
|
'readability/todo',
|
||||||
'readability/utf8',
|
'readability/utf8',
|
||||||
@ -356,13 +349,7 @@ _LEGACY_ERROR_CATEGORIES = [
|
|||||||
# flag. By default all errors are on, so only add here categories that should be
|
# flag. By default all errors are on, so only add here categories that should be
|
||||||
# off by default (i.e., categories that must be enabled by the --filter= flags).
|
# off by default (i.e., categories that must be enabled by the --filter= flags).
|
||||||
# All entries here should start with a '-' or '+', as in the --filter= flag.
|
# All entries here should start with a '-' or '+', as in the --filter= flag.
|
||||||
_DEFAULT_FILTERS = [
|
_DEFAULT_FILTERS = ['-build/include_alpha']
|
||||||
'-build/include_alpha',
|
|
||||||
'-build/include_subdir',
|
|
||||||
'-build/include_what_you_use',
|
|
||||||
'-legal/copyright',
|
|
||||||
'-readability/nolint',
|
|
||||||
]
|
|
||||||
|
|
||||||
# The default list of categories suppressed for C (not C++) files.
|
# The default list of categories suppressed for C (not C++) files.
|
||||||
_DEFAULT_C_SUPPRESSED_CATEGORIES = [
|
_DEFAULT_C_SUPPRESSED_CATEGORIES = [
|
||||||
@ -635,12 +622,6 @@ _SEARCH_C_FILE = re.compile(r'\b(?:LINT_C_FILE|'
|
|||||||
# Match string that indicates we're working on a Linux Kernel file.
|
# Match string that indicates we're working on a Linux Kernel file.
|
||||||
_SEARCH_KERNEL_FILE = re.compile(r'\b(?:LINT_KERNEL_FILE)')
|
_SEARCH_KERNEL_FILE = re.compile(r'\b(?:LINT_KERNEL_FILE)')
|
||||||
|
|
||||||
_NULL_TOKEN_PATTERN = re.compile(r'\bNULL\b')
|
|
||||||
|
|
||||||
_RIGHT_LEANING_POINTER_PATTERN = re.compile(r'[^=|(,\s><);&?:}]'
|
|
||||||
r'(?<!(sizeof|return))'
|
|
||||||
r'\s\*[a-zA-Z_][0-9a-zA-Z_]*')
|
|
||||||
|
|
||||||
_regexp_compile_cache = {}
|
_regexp_compile_cache = {}
|
||||||
|
|
||||||
# {str, set(int)}: a map from error categories to sets of linenumbers
|
# {str, set(int)}: a map from error categories to sets of linenumbers
|
||||||
@ -650,6 +631,7 @@ _error_suppressions = {}
|
|||||||
# The root directory used for deriving header guard CPP variable.
|
# The root directory used for deriving header guard CPP variable.
|
||||||
# This is set by --root flag.
|
# This is set by --root flag.
|
||||||
_root = None
|
_root = None
|
||||||
|
_root_debug = False
|
||||||
|
|
||||||
# The top level repository directory. If set, _root is calculated relative to
|
# The top level repository directory. If set, _root is calculated relative to
|
||||||
# this directory instead of the directory containing version control artifacts.
|
# this directory instead of the directory containing version control artifacts.
|
||||||
@ -659,19 +641,13 @@ _repository = None
|
|||||||
# Files to exclude from linting. This is set by the --exclude flag.
|
# Files to exclude from linting. This is set by the --exclude flag.
|
||||||
_excludes = None
|
_excludes = None
|
||||||
|
|
||||||
# Whether to suppress PrintInfo messages
|
# Whether to supress PrintInfo messages
|
||||||
_quiet = False
|
_quiet = False
|
||||||
|
|
||||||
# The allowed line length of files.
|
# The allowed line length of files.
|
||||||
# This is set by --linelength flag.
|
# This is set by --linelength flag.
|
||||||
_line_length = 80
|
_line_length = 80
|
||||||
|
|
||||||
try:
|
|
||||||
xrange(1, 0)
|
|
||||||
except NameError:
|
|
||||||
# -- pylint: disable=redefined-builtin
|
|
||||||
xrange = range
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
unicode
|
unicode
|
||||||
except NameError:
|
except NameError:
|
||||||
@ -679,7 +655,7 @@ except NameError:
|
|||||||
basestring = unicode = str
|
basestring = unicode = str
|
||||||
|
|
||||||
try:
|
try:
|
||||||
long(2)
|
long
|
||||||
except NameError:
|
except NameError:
|
||||||
# -- pylint: disable=redefined-builtin
|
# -- pylint: disable=redefined-builtin
|
||||||
long = int
|
long = int
|
||||||
@ -700,10 +676,38 @@ def unicode_escape_decode(x):
|
|||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
# Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc.
|
||||||
|
# This is set by --headers flag.
|
||||||
|
_hpp_headers = set(['h', 'hh', 'hpp', 'hxx', 'h++', 'cuh'])
|
||||||
|
|
||||||
# {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 separated list.')
|
||||||
|
|
||||||
|
def IsHeaderExtension(file_extension):
|
||||||
|
return file_extension in _hpp_headers
|
||||||
|
|
||||||
|
def GetHeaderExtensions():
|
||||||
|
return _hpp_headers or ['h']
|
||||||
|
|
||||||
|
# The allowed extensions for file names
|
||||||
|
# This is set by --extensions flag
|
||||||
|
def GetAllExtensions():
|
||||||
|
if not _valid_extensions:
|
||||||
|
return GetHeaderExtensions().union(set(['c', 'cc', 'cpp', 'cxx', 'c++', 'cu']))
|
||||||
|
return _valid_extensions
|
||||||
|
|
||||||
|
def GetNonHeaderExtensions():
|
||||||
|
return GetAllExtensions().difference(GetHeaderExtensions())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -837,9 +841,9 @@ class _IncludeState(object):
|
|||||||
# needs to move backwards, CheckNextIncludeOrder will raise an error.
|
# needs to move backwards, CheckNextIncludeOrder will raise an error.
|
||||||
_INITIAL_SECTION = 0
|
_INITIAL_SECTION = 0
|
||||||
_MY_H_SECTION = 1
|
_MY_H_SECTION = 1
|
||||||
_OTHER_H_SECTION = 2
|
_C_SECTION = 2
|
||||||
_C_SECTION = 3
|
_CPP_SECTION = 3
|
||||||
_CPP_SECTION = 4
|
_OTHER_H_SECTION = 4
|
||||||
|
|
||||||
_TYPE_NAMES = {
|
_TYPE_NAMES = {
|
||||||
_C_SYS_HEADER: 'C system header',
|
_C_SYS_HEADER: 'C system header',
|
||||||
@ -851,9 +855,9 @@ class _IncludeState(object):
|
|||||||
_SECTION_NAMES = {
|
_SECTION_NAMES = {
|
||||||
_INITIAL_SECTION: "... nothing. (This can't be an error.)",
|
_INITIAL_SECTION: "... nothing. (This can't be an error.)",
|
||||||
_MY_H_SECTION: 'a header this file implements',
|
_MY_H_SECTION: 'a header this file implements',
|
||||||
_OTHER_H_SECTION: 'other header',
|
|
||||||
_C_SECTION: 'C system header',
|
_C_SECTION: 'C system header',
|
||||||
_CPP_SECTION: 'C++ system header',
|
_CPP_SECTION: 'C++ system header',
|
||||||
|
_OTHER_H_SECTION: 'other header',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -1000,6 +1004,7 @@ class _CppLintState(object):
|
|||||||
self._filters_backup = self.filters[:]
|
self._filters_backup = self.filters[:]
|
||||||
self.counting = 'total' # In what way are we counting errors?
|
self.counting = 'total' # In what way are we counting errors?
|
||||||
self.errors_by_category = {} # string to int dict storing error counts
|
self.errors_by_category = {} # string to int dict storing error counts
|
||||||
|
self.quiet = False # Suppress non-error messagess?
|
||||||
|
|
||||||
# output format:
|
# output format:
|
||||||
# "emacs" - format that emacs can parse (default)
|
# "emacs" - format that emacs can parse (default)
|
||||||
@ -1017,6 +1022,12 @@ class _CppLintState(object):
|
|||||||
"""Sets the output format for errors."""
|
"""Sets the output format for errors."""
|
||||||
self.output_format = output_format
|
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):
|
def SetVerboseLevel(self, level):
|
||||||
"""Sets the module's verbosity, and returns the previous setting."""
|
"""Sets the module's verbosity, and returns the previous setting."""
|
||||||
last_verbose_level = self.verbose_level
|
last_verbose_level = self.verbose_level
|
||||||
@ -1089,7 +1100,7 @@ class _CppLintState(object):
|
|||||||
|
|
||||||
def PrintInfo(self, message):
|
def PrintInfo(self, message):
|
||||||
if not _quiet and self.output_format != 'junit':
|
if not _quiet and self.output_format != 'junit':
|
||||||
sys.stderr.write(message)
|
sys.stdout.write(message)
|
||||||
|
|
||||||
def PrintError(self, message):
|
def PrintError(self, message):
|
||||||
if self.output_format == 'junit':
|
if self.output_format == 'junit':
|
||||||
@ -1157,6 +1168,14 @@ def _SetOutputFormat(output_format):
|
|||||||
"""Sets the module's output format."""
|
"""Sets the module's output format."""
|
||||||
_cpplint_state.SetOutputFormat(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():
|
def _VerboseLevel():
|
||||||
"""Returns the module's verbosity setting."""
|
"""Returns the module's verbosity setting."""
|
||||||
@ -1299,12 +1318,54 @@ class FileInfo(object):
|
|||||||
locations won't see bogus errors.
|
locations won't see bogus errors.
|
||||||
"""
|
"""
|
||||||
fullname = self.FullName()
|
fullname = self.FullName()
|
||||||
# XXX(bnoordhuis) Expects that cpplint.py lives in the tools/ directory.
|
|
||||||
toplevel = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')).replace('\\', '/')
|
if os.path.exists(fullname):
|
||||||
toplevel = unicode_escape_decode(toplevel)
|
project_dir = os.path.dirname(fullname)
|
||||||
prefix = os.path.commonprefix([fullname, toplevel])
|
|
||||||
|
# If the user specified a repository path, it exists, and the file is
|
||||||
|
# contained in it, use the specified repository path
|
||||||
|
if _repository:
|
||||||
|
repo = FileInfo(_repository).FullName()
|
||||||
|
root_dir = project_dir
|
||||||
|
while os.path.exists(root_dir):
|
||||||
|
# allow case insensitive compare on Windows
|
||||||
|
if os.path.normcase(root_dir) == os.path.normcase(repo):
|
||||||
|
return os.path.relpath(fullname, root_dir).replace('\\', '/')
|
||||||
|
one_up_dir = os.path.dirname(root_dir)
|
||||||
|
if one_up_dir == root_dir:
|
||||||
|
break
|
||||||
|
root_dir = one_up_dir
|
||||||
|
|
||||||
|
if os.path.exists(os.path.join(project_dir, ".svn")):
|
||||||
|
# If there's a .svn file in the current directory, we recursively look
|
||||||
|
# up the directory tree for the top of the SVN checkout
|
||||||
|
root_dir = project_dir
|
||||||
|
one_up_dir = os.path.dirname(root_dir)
|
||||||
|
while os.path.exists(os.path.join(one_up_dir, ".svn")):
|
||||||
|
root_dir = os.path.dirname(root_dir)
|
||||||
|
one_up_dir = os.path.dirname(one_up_dir)
|
||||||
|
|
||||||
|
prefix = os.path.commonprefix([root_dir, project_dir])
|
||||||
return fullname[len(prefix) + 1:]
|
return fullname[len(prefix) + 1:]
|
||||||
# End Node.js patch
|
|
||||||
|
# Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by
|
||||||
|
# searching up from the current path.
|
||||||
|
root_dir = current_dir = os.path.dirname(fullname)
|
||||||
|
while current_dir != os.path.dirname(current_dir):
|
||||||
|
if (os.path.exists(os.path.join(current_dir, ".git")) or
|
||||||
|
os.path.exists(os.path.join(current_dir, ".hg")) or
|
||||||
|
os.path.exists(os.path.join(current_dir, ".svn"))):
|
||||||
|
root_dir = current_dir
|
||||||
|
current_dir = os.path.dirname(current_dir)
|
||||||
|
|
||||||
|
if (os.path.exists(os.path.join(root_dir, ".git")) or
|
||||||
|
os.path.exists(os.path.join(root_dir, ".hg")) or
|
||||||
|
os.path.exists(os.path.join(root_dir, ".svn"))):
|
||||||
|
prefix = os.path.commonprefix([root_dir, project_dir])
|
||||||
|
return fullname[len(prefix) + 1:]
|
||||||
|
|
||||||
|
# Don't know what to do; header guard warnings may be wrong...
|
||||||
|
return fullname
|
||||||
|
|
||||||
def Split(self):
|
def Split(self):
|
||||||
"""Splits the file into the directory, basename, and extension.
|
"""Splits the file into the directory, basename, and extension.
|
||||||
@ -1390,8 +1451,8 @@ def Error(filename, linenum, category, confidence, message):
|
|||||||
if _ShouldPrintError(category, confidence, linenum):
|
if _ShouldPrintError(category, confidence, linenum):
|
||||||
_cpplint_state.IncrementErrorCount(category)
|
_cpplint_state.IncrementErrorCount(category)
|
||||||
if _cpplint_state.output_format == 'vs7':
|
if _cpplint_state.output_format == 'vs7':
|
||||||
_cpplint_state.PrintError('%s(%s): warning: %s [%s] [%d]\n' % (
|
_cpplint_state.PrintError('%s(%s): error cpplint: [%s] %s [%d]\n' % (
|
||||||
filename, linenum, message, category, confidence))
|
filename, linenum, category, message, confidence))
|
||||||
elif _cpplint_state.output_format == 'eclipse':
|
elif _cpplint_state.output_format == 'eclipse':
|
||||||
sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
|
sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
|
||||||
filename, linenum, message, category, confidence))
|
filename, linenum, message, category, confidence))
|
||||||
@ -1913,7 +1974,7 @@ def CheckForCopyright(filename, lines, error):
|
|||||||
|
|
||||||
# We'll say it should occur by line 10. Don't forget there's a
|
# We'll say it should occur by line 10. Don't forget there's a
|
||||||
# dummy line at the front.
|
# dummy line at the front.
|
||||||
for line in range(1, min(len(lines), 11)):
|
for line in xrange(1, min(len(lines), 11)):
|
||||||
if re.search(r'Copyright', lines[line], re.I): break
|
if re.search(r'Copyright', lines[line], re.I): break
|
||||||
else: # means no copyright line was found
|
else: # means no copyright line was found
|
||||||
error(filename, 0, 'legal/copyright', 5,
|
error(filename, 0, 'legal/copyright', 5,
|
||||||
@ -1936,6 +1997,30 @@ def GetIndentLevel(line):
|
|||||||
else:
|
else:
|
||||||
return 0
|
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):
|
def GetHeaderGuardCPPVariable(filename):
|
||||||
"""Returns the CPP variable that should be used as a header guard.
|
"""Returns the CPP variable that should be used as a header guard.
|
||||||
@ -1958,11 +2043,58 @@ def GetHeaderGuardCPPVariable(filename):
|
|||||||
|
|
||||||
fileinfo = FileInfo(filename)
|
fileinfo = FileInfo(filename)
|
||||||
file_path_from_root = fileinfo.RepositoryName()
|
file_path_from_root = fileinfo.RepositoryName()
|
||||||
if _root:
|
|
||||||
# Convert root path to unix format because file_path_from_root is also
|
def FixupPathFromRoot():
|
||||||
# in that format and they wouldn't match otherwise on Windows machines
|
if _root_debug:
|
||||||
root = os.path.normpath(_root).replace('\\', '/')
|
sys.stderr.write("\n_root fixup, _root = '%s', repository name = '%s'\n"
|
||||||
file_path_from_root = re.sub('^' + root + '/', '', file_path_from_root)
|
% (_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() + '_'
|
return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_'
|
||||||
|
|
||||||
|
|
||||||
@ -2121,21 +2253,6 @@ def CheckForBadCharacters(filename, lines, error):
|
|||||||
error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.')
|
error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.')
|
||||||
|
|
||||||
|
|
||||||
def CheckInlineHeader(filename, include_state, error):
|
|
||||||
"""Logs an error if both a header and its inline variant are included."""
|
|
||||||
|
|
||||||
all_headers = dict(item for sublist in include_state.include_list
|
|
||||||
for item in sublist)
|
|
||||||
bad_headers = set('%s.h' % name[:-6] for name in all_headers.keys()
|
|
||||||
if name.endswith('-inl.h'))
|
|
||||||
bad_headers &= set(all_headers.keys())
|
|
||||||
|
|
||||||
for name in bad_headers:
|
|
||||||
err = '%s includes both %s and %s-inl.h' % (filename, name, name)
|
|
||||||
linenum = all_headers[name]
|
|
||||||
error(filename, linenum, 'build/include_inline', 5, err)
|
|
||||||
|
|
||||||
|
|
||||||
def CheckForNewlineAtEOF(filename, lines, error):
|
def CheckForNewlineAtEOF(filename, lines, error):
|
||||||
"""Logs an error if there is no newline char at the end of the file.
|
"""Logs an error if there is no newline char at the end of the file.
|
||||||
|
|
||||||
@ -2981,7 +3098,8 @@ def CheckForNonStandardConstructs(filename, clean_lines, linenum,
|
|||||||
# Look for single-argument constructors that aren't marked explicit.
|
# Look for single-argument constructors that aren't marked explicit.
|
||||||
# Technically a valid construct, but against style.
|
# Technically a valid construct, but against style.
|
||||||
explicit_constructor_match = Match(
|
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'\(((?:[^()]|\([^()]*\))*)\)'
|
r'\(((?:[^()]|\([^()]*\))*)\)'
|
||||||
% re.escape(base_classname),
|
% re.escape(base_classname),
|
||||||
line)
|
line)
|
||||||
@ -3192,7 +3310,7 @@ def CheckForFunctionLengths(filename, clean_lines, linenum,
|
|||||||
|
|
||||||
if starting_func:
|
if starting_func:
|
||||||
body_found = False
|
body_found = False
|
||||||
for start_linenum in range(linenum, clean_lines.NumLines()):
|
for start_linenum in xrange(linenum, clean_lines.NumLines()):
|
||||||
start_line = lines[start_linenum]
|
start_line = lines[start_linenum]
|
||||||
joined_line += ' ' + start_line.lstrip()
|
joined_line += ' ' + start_line.lstrip()
|
||||||
if Search(r'(;|})', start_line): # Declarations and trivial functions
|
if Search(r'(;|})', start_line): # Declarations and trivial functions
|
||||||
@ -3277,36 +3395,6 @@ def CheckComment(line, filename, linenum, next_line_start, error):
|
|||||||
'Should have a space between // and comment')
|
'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):
|
def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
|
||||||
"""Checks for the correctness of various spacing issues in the code.
|
"""Checks for the correctness of various spacing issues in the code.
|
||||||
|
|
||||||
@ -4413,49 +4501,6 @@ def CheckAltTokens(filename, clean_lines, linenum, error):
|
|||||||
'Use operator %s instead of %s' % (
|
'Use operator %s instead of %s' % (
|
||||||
_ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))
|
_ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))
|
||||||
|
|
||||||
def CheckNullTokens(filename, clean_lines, linenum, error):
|
|
||||||
"""Check NULL usage.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filename: The name of the current file.
|
|
||||||
clean_lines: A CleansedLines instance containing the file.
|
|
||||||
linenum: The number of the line to check.
|
|
||||||
error: The function to call with any errors found.
|
|
||||||
"""
|
|
||||||
line = clean_lines.elided[linenum]
|
|
||||||
|
|
||||||
# Avoid preprocessor lines
|
|
||||||
if Match(r'^\s*#', line):
|
|
||||||
return
|
|
||||||
|
|
||||||
if line.find('/*') >= 0 or line.find('*/') >= 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
for match in _NULL_TOKEN_PATTERN.finditer(line):
|
|
||||||
error(filename, linenum, 'readability/null_usage', 2,
|
|
||||||
'Use nullptr instead of NULL')
|
|
||||||
|
|
||||||
def CheckLeftLeaningPointer(filename, clean_lines, linenum, error):
|
|
||||||
"""Check for left-leaning pointer placement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
filename: The name of the current file.
|
|
||||||
clean_lines: A CleansedLines instance containing the file.
|
|
||||||
linenum: The number of the line to check.
|
|
||||||
error: The function to call with any errors found.
|
|
||||||
"""
|
|
||||||
line = clean_lines.elided[linenum]
|
|
||||||
|
|
||||||
# Avoid preprocessor lines
|
|
||||||
if Match(r'^\s*#', line):
|
|
||||||
return
|
|
||||||
|
|
||||||
if '/*' in line or '*/' in line:
|
|
||||||
return
|
|
||||||
|
|
||||||
for match in _RIGHT_LEANING_POINTER_PATTERN.finditer(line):
|
|
||||||
error(filename, linenum, 'readability/pointer_notation', 2,
|
|
||||||
'Use left leaning pointer instead of right leaning')
|
|
||||||
|
|
||||||
def GetLineWidth(line):
|
def GetLineWidth(line):
|
||||||
"""Determines the width of the line in column positions.
|
"""Determines the width of the line in column positions.
|
||||||
@ -4473,6 +4518,16 @@ def GetLineWidth(line):
|
|||||||
if unicodedata.east_asian_width(uc) in ('W', 'F'):
|
if unicodedata.east_asian_width(uc) in ('W', 'F'):
|
||||||
width += 2
|
width += 2
|
||||||
elif not unicodedata.combining(uc):
|
elif not unicodedata.combining(uc):
|
||||||
|
# Issue 337
|
||||||
|
# https://mail.python.org/pipermail/python-list/2012-August/628809.html
|
||||||
|
if (sys.version_info.major, sys.version_info.minor) <= (3, 2):
|
||||||
|
# https://github.com/python/cpython/blob/2.7/Include/unicodeobject.h#L81
|
||||||
|
is_wide_build = sysconfig.get_config_var("Py_UNICODE_SIZE") >= 4
|
||||||
|
# https://github.com/python/cpython/blob/2.7/Objects/unicodeobject.c#L564
|
||||||
|
is_low_surrogate = 0xDC00 <= ord(uc) <= 0xDFFF
|
||||||
|
if not is_wide_build and is_low_surrogate:
|
||||||
|
width -= 1
|
||||||
|
|
||||||
width += 1
|
width += 1
|
||||||
return width
|
return width
|
||||||
else:
|
else:
|
||||||
@ -4508,10 +4563,6 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
|
|||||||
error(filename, linenum, 'whitespace/tab', 1,
|
error(filename, linenum, 'whitespace/tab', 1,
|
||||||
'Tab found; better to use spaces')
|
'Tab found; better to use spaces')
|
||||||
|
|
||||||
if line.find('template<') != -1:
|
|
||||||
error(filename, linenum, 'whitespace/template', 1,
|
|
||||||
'Leave a single space after template, as in `template <...>`')
|
|
||||||
|
|
||||||
# One or three blank spaces at the beginning of the line is weird; it's
|
# One or three blank spaces at the beginning of the line is weird; it's
|
||||||
# hard to reconcile that with 2-space indents.
|
# hard to reconcile that with 2-space indents.
|
||||||
# NOTE: here are the conditions rob pike used for his tests. Mine aren't
|
# NOTE: here are the conditions rob pike used for his tests. Mine aren't
|
||||||
@ -4550,7 +4601,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 in GetHeaderExtensions():
|
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
|
||||||
@ -4596,7 +4647,6 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
|
|||||||
CheckBraces(filename, clean_lines, linenum, error)
|
CheckBraces(filename, clean_lines, linenum, error)
|
||||||
CheckTrailingSemicolon(filename, clean_lines, linenum, error)
|
CheckTrailingSemicolon(filename, clean_lines, linenum, error)
|
||||||
CheckEmptyBlockBody(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)
|
CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
|
||||||
CheckOperatorSpacing(filename, clean_lines, linenum, error)
|
CheckOperatorSpacing(filename, clean_lines, linenum, error)
|
||||||
CheckParenthesisSpacing(filename, clean_lines, linenum, error)
|
CheckParenthesisSpacing(filename, clean_lines, linenum, error)
|
||||||
@ -4605,8 +4655,6 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
|
|||||||
CheckSpacingForFunctionCall(filename, clean_lines, linenum, error)
|
CheckSpacingForFunctionCall(filename, clean_lines, linenum, error)
|
||||||
CheckCheck(filename, clean_lines, linenum, error)
|
CheckCheck(filename, clean_lines, linenum, error)
|
||||||
CheckAltTokens(filename, clean_lines, linenum, error)
|
CheckAltTokens(filename, clean_lines, linenum, error)
|
||||||
CheckNullTokens(filename, clean_lines, linenum, error)
|
|
||||||
CheckLeftLeaningPointer(filename, clean_lines, linenum, error)
|
|
||||||
classinfo = nesting_state.InnermostClass()
|
classinfo = nesting_state.InnermostClass()
|
||||||
if classinfo:
|
if classinfo:
|
||||||
CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
|
CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
|
||||||
@ -4771,10 +4819,11 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
|
|||||||
include_state.include_list[-1].append((include, linenum))
|
include_state.include_list[-1].append((include, linenum))
|
||||||
|
|
||||||
# We want to ensure that headers appear in the right order:
|
# We want to ensure that headers appear in the right order:
|
||||||
# 1) for foo.cc, foo.h
|
# 1) for foo.cc, foo.h (preferred location)
|
||||||
# 2) other project headers
|
# 2) c system files
|
||||||
# 3) c system files
|
# 3) cpp system files
|
||||||
# 4) cpp system files
|
# 4) for foo.cc, foo.h (deprecated location)
|
||||||
|
# 5) other google headers
|
||||||
#
|
#
|
||||||
# We classify each include statement as one of those 5 types
|
# We classify each include statement as one of those 5 types
|
||||||
# using a number of techniques. The include_state object keeps
|
# using a number of techniques. The include_state object keeps
|
||||||
@ -4920,7 +4969,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 in GetHeaderExtensions():
|
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)
|
||||||
@ -5032,7 +5081,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 in GetHeaderExtensions()
|
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,
|
||||||
@ -5598,7 +5647,7 @@ _re_pattern_headers_maybe_templates = []
|
|||||||
for _header, _templates in _HEADERS_MAYBE_TEMPLATES:
|
for _header, _templates in _HEADERS_MAYBE_TEMPLATES:
|
||||||
for _template in _templates:
|
for _template in _templates:
|
||||||
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
|
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
|
||||||
# type::max().
|
# 'type::max()'.
|
||||||
_re_pattern_headers_maybe_templates.append(
|
_re_pattern_headers_maybe_templates.append(
|
||||||
(re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
|
(re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
|
||||||
_template,
|
_template,
|
||||||
@ -5648,7 +5697,7 @@ def FilesBelongToSameModule(filename_cc, filename_h):
|
|||||||
return (False, '')
|
return (False, '')
|
||||||
|
|
||||||
fileinfo_h = FileInfo(filename_h)
|
fileinfo_h = FileInfo(filename_h)
|
||||||
if not fileinfo_h.Extension().lstrip('.') in GetHeaderExtensions():
|
if not IsHeaderExtension(fileinfo_h.Extension().lstrip('.')):
|
||||||
return (False, '')
|
return (False, '')
|
||||||
|
|
||||||
filename_cc = filename_cc[:-(len(fileinfo_cc.Extension()))]
|
filename_cc = filename_cc[:-(len(fileinfo_cc.Extension()))]
|
||||||
@ -5720,7 +5769,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
|
|||||||
required = {} # A map of header name to linenumber and the template entity.
|
required = {} # A map of header name to linenumber and the template entity.
|
||||||
# Example of required: { '<functional>': (1219, 'less<>') }
|
# Example of required: { '<functional>': (1219, 'less<>') }
|
||||||
|
|
||||||
for linenum in range(clean_lines.NumLines()):
|
for linenum in xrange(clean_lines.NumLines()):
|
||||||
line = clean_lines.elided[linenum]
|
line = clean_lines.elided[linenum]
|
||||||
if not line or line[0] == '#':
|
if not line or line[0] == '#':
|
||||||
continue
|
continue
|
||||||
@ -6126,10 +6175,10 @@ 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 in GetHeaderExtensions():
|
if IsHeaderExtension(file_extension):
|
||||||
CheckForHeaderGuard(filename, clean_lines, error)
|
CheckForHeaderGuard(filename, clean_lines, error)
|
||||||
|
|
||||||
for line in range(clean_lines.NumLines()):
|
for line in xrange(clean_lines.NumLines()):
|
||||||
ProcessLine(filename, file_extension, clean_lines, line,
|
ProcessLine(filename, file_extension, clean_lines, line,
|
||||||
include_state, function_state, nesting_state, error,
|
include_state, function_state, nesting_state, error,
|
||||||
extra_check_functions)
|
extra_check_functions)
|
||||||
@ -6148,8 +6197,6 @@ def ProcessFileData(filename, file_extension, lines, error,
|
|||||||
|
|
||||||
CheckForNewlineAtEOF(filename, lines, error)
|
CheckForNewlineAtEOF(filename, lines, error)
|
||||||
|
|
||||||
CheckInlineHeader(filename, include_state, error)
|
|
||||||
|
|
||||||
def ProcessConfigOverrides(filename):
|
def ProcessConfigOverrides(filename):
|
||||||
""" Loads the configuration files and processes the config overrides.
|
""" Loads the configuration files and processes the config overrides.
|
||||||
|
|
||||||
@ -6197,8 +6244,12 @@ def ProcessConfigOverrides(filename):
|
|||||||
if base_name:
|
if base_name:
|
||||||
pattern = re.compile(val)
|
pattern = re.compile(val)
|
||||||
if pattern.match(base_name):
|
if pattern.match(base_name):
|
||||||
_cpplint_state.PrintInfo('Ignoring "%s": file excluded by '
|
if _cpplint_state.quiet:
|
||||||
'"%s". File path component "%s" matches pattern "%s"\n' %
|
# Suppress "Ignoring file" warning when using --quiet.
|
||||||
|
return False
|
||||||
|
_cpplint_state.PrintInfo('Ignoring "%s": file excluded by "%s". '
|
||||||
|
'File path component "%s" matches '
|
||||||
|
'pattern "%s"\n' %
|
||||||
(filename, cfg_file, base_name, val))
|
(filename, cfg_file, base_name, val))
|
||||||
return False
|
return False
|
||||||
elif name == 'linelength':
|
elif name == 'linelength':
|
||||||
@ -6216,18 +6267,12 @@ def ProcessConfigOverrides(filename):
|
|||||||
sys.stderr.write('Extensions should be a comma-separated list of values;'
|
sys.stderr.write('Extensions should be a comma-separated list of values;'
|
||||||
'for example: extensions=hpp,cpp\n'
|
'for example: extensions=hpp,cpp\n'
|
||||||
'This could not be parsed: "%s"' % (val,))
|
'This could not be parsed: "%s"' % (val,))
|
||||||
elif name == 'headers':
|
|
||||||
global _header_extensions
|
|
||||||
try:
|
|
||||||
extensions = [ext.strip() for ext in val.split(',')]
|
|
||||||
_header_extensions = 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"' % (val,))
|
|
||||||
elif name == 'root':
|
elif name == 'root':
|
||||||
global _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:
|
else:
|
||||||
_cpplint_state.PrintError(
|
_cpplint_state.PrintError(
|
||||||
'Invalid configuration option (%s) in file %s\n' %
|
'Invalid configuration option (%s) in file %s\n' %
|
||||||
@ -6262,6 +6307,7 @@ def ProcessFile(filename, vlevel, extra_check_functions=None):
|
|||||||
|
|
||||||
_SetVerboseLevel(vlevel)
|
_SetVerboseLevel(vlevel)
|
||||||
_BackupFilters()
|
_BackupFilters()
|
||||||
|
old_errors = _cpplint_state.error_count
|
||||||
|
|
||||||
if not ProcessConfigOverrides(filename):
|
if not ProcessConfigOverrides(filename):
|
||||||
_RestoreFilters()
|
_RestoreFilters()
|
||||||
@ -6330,6 +6376,9 @@ def ProcessFile(filename, vlevel, extra_check_functions=None):
|
|||||||
Error(filename, linenum, 'whitespace/newline', 1,
|
Error(filename, linenum, 'whitespace/newline', 1,
|
||||||
'Unexpected \\r (^M) found; better to use only \\n')
|
'Unexpected \\r (^M) found; better to use only \\n')
|
||||||
|
|
||||||
|
# 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:
|
||||||
_cpplint_state.PrintInfo('Done processing %s\n' % filename)
|
_cpplint_state.PrintInfo('Done processing %s\n' % filename)
|
||||||
_RestoreFilters()
|
_RestoreFilters()
|
||||||
|
|
||||||
@ -6340,13 +6389,21 @@ def PrintUsage(message):
|
|||||||
Args:
|
Args:
|
||||||
message: The optional error message.
|
message: The optional error message.
|
||||||
"""
|
"""
|
||||||
sys.stderr.write(_USAGE)
|
sys.stderr.write(_USAGE % (list(GetAllExtensions()),
|
||||||
|
','.join(list(GetAllExtensions())),
|
||||||
|
GetHeaderExtensions(),
|
||||||
|
','.join(GetHeaderExtensions())))
|
||||||
|
|
||||||
if message:
|
if message:
|
||||||
sys.exit('\nFATAL ERROR: ' + message)
|
sys.exit('\nFATAL ERROR: ' + message)
|
||||||
else:
|
else:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
def PrintVersion():
|
||||||
|
sys.stdout.write('Cpplint fork (https://github.com/cpplint/cpplint)\n')
|
||||||
|
sys.stdout.write('cpplint ' + __VERSION__ + '\n')
|
||||||
|
sys.stdout.write('Python ' + sys.version + '\n')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
def PrintCategories():
|
def PrintCategories():
|
||||||
"""Prints a list of all the error-categories used by error messages.
|
"""Prints a list of all the error-categories used by error messages.
|
||||||
@ -6370,6 +6427,8 @@ def ParseArguments(args):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
(opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
|
(opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
|
||||||
|
'v=',
|
||||||
|
'version',
|
||||||
'counting=',
|
'counting=',
|
||||||
'filter=',
|
'filter=',
|
||||||
'root=',
|
'root=',
|
||||||
@ -6377,27 +6436,32 @@ def ParseArguments(args):
|
|||||||
'linelength=',
|
'linelength=',
|
||||||
'extensions=',
|
'extensions=',
|
||||||
'exclude=',
|
'exclude=',
|
||||||
|
'recursive',
|
||||||
'headers=',
|
'headers=',
|
||||||
'quiet',
|
'quiet'])
|
||||||
'recursive'])
|
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
PrintUsage('Invalid arguments.')
|
PrintUsage('Invalid arguments.')
|
||||||
|
|
||||||
verbosity = _VerboseLevel()
|
verbosity = _VerboseLevel()
|
||||||
output_format = _OutputFormat()
|
output_format = _OutputFormat()
|
||||||
filters = ''
|
filters = ''
|
||||||
|
quiet = _Quiet()
|
||||||
counting_style = ''
|
counting_style = ''
|
||||||
recursive = False
|
recursive = False
|
||||||
|
|
||||||
for (opt, val) in opts:
|
for (opt, val) in opts:
|
||||||
if opt == '--help':
|
if opt == '--help':
|
||||||
PrintUsage(None)
|
PrintUsage(None)
|
||||||
|
if opt == '--version':
|
||||||
|
PrintVersion()
|
||||||
elif opt == '--output':
|
elif opt == '--output':
|
||||||
if val not in ('emacs', 'vs7', 'eclipse', 'junit'):
|
if val not in ('emacs', 'vs7', 'eclipse', 'junit'):
|
||||||
PrintUsage('The only allowed output formats are emacs, vs7, eclipse '
|
PrintUsage('The only allowed output formats are emacs, vs7, eclipse '
|
||||||
'and junit.')
|
'and junit.')
|
||||||
output_format = val
|
output_format = val
|
||||||
elif opt == '--verbose':
|
elif opt == '--quiet':
|
||||||
|
quiet = True
|
||||||
|
elif opt == '--verbose' or opt == '--v':
|
||||||
verbosity = int(val)
|
verbosity = int(val)
|
||||||
elif opt == '--filter':
|
elif opt == '--filter':
|
||||||
filters = val
|
filters = val
|
||||||
@ -6431,16 +6495,9 @@ def ParseArguments(args):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
PrintUsage('Extensions must be comma seperated list.')
|
PrintUsage('Extensions must be comma seperated list.')
|
||||||
elif opt == '--headers':
|
elif opt == '--headers':
|
||||||
global _header_extensions
|
ProcessHppHeadersOption(val)
|
||||||
try:
|
|
||||||
_header_extensions = set(val.split(','))
|
|
||||||
except ValueError:
|
|
||||||
PrintUsage('Extensions must be comma seperated list.')
|
|
||||||
elif opt == '--recursive':
|
elif opt == '--recursive':
|
||||||
recursive = True
|
recursive = True
|
||||||
elif opt == '--quiet':
|
|
||||||
global _quiet
|
|
||||||
_quiet = True
|
|
||||||
|
|
||||||
if not filenames:
|
if not filenames:
|
||||||
PrintUsage('No files were specified.')
|
PrintUsage('No files were specified.')
|
||||||
@ -6452,6 +6509,7 @@ def ParseArguments(args):
|
|||||||
filenames = _FilterExcludedFiles(filenames)
|
filenames = _FilterExcludedFiles(filenames)
|
||||||
|
|
||||||
_SetOutputFormat(output_format)
|
_SetOutputFormat(output_format)
|
||||||
|
_SetQuiet(quiet)
|
||||||
_SetVerboseLevel(verbosity)
|
_SetVerboseLevel(verbosity)
|
||||||
_SetFilters(filters)
|
_SetFilters(filters)
|
||||||
_SetCountingStyle(counting_style)
|
_SetCountingStyle(counting_style)
|
||||||
@ -6508,6 +6566,8 @@ def main():
|
|||||||
_cpplint_state.ResetErrorCounts()
|
_cpplint_state.ResetErrorCounts()
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
ProcessFile(filename, _cpplint_state.verbose_level)
|
ProcessFile(filename, _cpplint_state.verbose_level)
|
||||||
|
# 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()
|
_cpplint_state.PrintErrorCounts()
|
||||||
|
|
||||||
if _cpplint_state.output_format == 'junit':
|
if _cpplint_state.output_format == 'junit':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user