3
# Copyright (c) 2009 Google Inc. All rights reserved.
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions are
9
# * Redistributions of source code must retain the above copyright
10
# notice, this list of conditions and the following disclaimer.
11
# * Redistributions in binary form must reproduce the above
12
# copyright notice, this list of conditions and the following disclaimer
13
# in the documentation and/or other materials provided with the
15
# * Neither the name of Google Inc. nor the names of its
16
# contributors may be used to endorse or promote products derived from
17
# this software without specific prior written permission.
19
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
# Here are some issues that I've had people identify in my code during reviews,
32
# that I think are possible to flag automatically in a lint tool. If these were
33
# caught by lint, it would save time both for myself and that of my reviewers.
34
# Most likely, some of these are beyond the scope of the current lint framework,
35
# but I think it is valuable to retain these wish-list items even if they cannot
36
# be immediately implemented.
40
# - Check for no 'explicit' for multi-arg ctor
41
# - Check for boolean assign RHS in parens
42
# - Check for ctor initializer-list colon position and spacing
43
# - Check that if there's a ctor, there should be a dtor
44
# - Check accessors that return non-pointer member variables are
46
# - Check accessors that return non-const pointer member vars are
47
# *not* declared const
48
# - Check for using public includes for testing
49
# - Check for spaces between brackets in one-line inline method
50
# - Check for no assert()
51
# - Check for spaces surrounding operators
52
# - Check for 0 in pointer context (should be NULL)
53
# - Check for 0 in char context (should be '\0')
54
# - Check for camel-case method name conventions for methods
55
# that are not simple inline getters and setters
56
# - Check that base classes have virtual destructors
57
# put " // namespace" after } that closes a namespace, with
58
# namespace's name after 'namespace' if it is named.
59
# - Do not indent namespace contents
60
# - Avoid inlining non-trivial constructors in header files
61
# include base/basictypes.h if DISALLOW_EVIL_CONSTRUCTORS is used
62
# - Check for old-school (void) cast for call-sites of functions
63
# ignored return value
64
# - Check gUnit usage of anonymous namespace
65
# - Check for class declaration order (typedefs, consts, enums,
66
# ctor(s?), dtor, friend declarations, methods, member vars)
69
"""Does google-lint on c++ files.
71
The goal of this script is to identify places in the code that *may*
72
be in non-compliance with google style. It does not attempt to fix
73
up these problems -- the point is to educate. It does also not
74
attempt to find all problems, or to ensure that everything it does
75
find is legitimately a problem.
77
In particular, we can get very confused by /* and // inside strings!
78
We do a small hack, which is to ignore //'s with "'s after them on the
79
same line, but it is far from perfect (in either direction).
94
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
95
[--counting=total|toplevel|detailed]
98
The style guidelines this tries to follow are those in
99
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
101
Every problem is given a confidence score from 1-5, with 5 meaning we are
102
certain of the problem, and 1 meaning it could be a legitimate construct.
103
This will miss some errors, and is not a substitute for a code review.
105
To suppress false-positive errors of a certain category, add a
106
'NOLINT(category)' comment to the line. NOLINT or NOLINT(*)
107
suppresses errors of all categories on that line.
109
The files passed in will be linted; at least one file must be provided.
110
Linted extensions are .cc, .cpp, .h and .hh. Other file types will be ignored.
115
By default, the output is formatted to ease emacs parsing. Visual Studio
116
compatible output (vs7) may also be used. Other formats are unsupported.
119
Specify a number 0-5 to restrict errors to certain verbosity levels.
122
Specify a comma-separated list of category-filters to apply: only
123
error messages whose category names pass the filters will be printed.
124
(Category names are printed with the message and look like
125
"[whitespace/indent]".) Filters are evaluated left to right.
126
"-FOO" and "FOO" means "do not print categories that start with FOO".
127
"+FOO" means "do print categories that start with FOO".
129
Examples: --filter=-whitespace,+whitespace/braces
130
--filter=whitespace,runtime/printf,+runtime/printf_format
131
--filter=-,+build/include_what_you_use
133
To see a list of all the categories used in cpplint, pass no arg:
136
counting=total|toplevel|detailed
137
The total number of errors found is always printed. If
138
'toplevel' is provided, then the count of errors in each of
139
the top-level categories like 'build' and 'whitespace' will
140
also be printed. If 'detailed' is provided, then a count
141
is provided for each category like 'build/class'.
144
# We categorize each error message we print. Here are the categories.
145
# We want an explicit list so we can list them all in cpplint --filter=.
146
# If you add a new error message with a new category, add it to the list
147
# here! cpplint_unittest.py should tell you if you forget to do this.
148
# \ used for clearer layout -- pylint: disable-msg=C6013
149
_ERROR_CATEGORIES = [
152
'build/endif_comment',
153
'build/forward_decl',
154
'build/header_guard',
156
'build/include_alpha',
157
'build/include_order',
158
'build/include_what_you_use',
160
'build/printf_format',
161
'build/storage_class',
163
'readability/braces',
164
'readability/casting',
166
'readability/constructors',
167
'readability/fn_size',
168
'readability/function',
169
'readability/multiline_comment',
170
'readability/multiline_string',
171
'readability/nolint',
172
'readability/streams',
180
'runtime/invalid_increment',
181
'runtime/member_string_references',
185
'runtime/printf_format',
186
'runtime/references',
190
'runtime/threadsafe_fn',
192
'whitespace/blank_line',
195
'whitespace/comments',
196
'whitespace/end_of_line',
197
'whitespace/ending_newline',
200
'whitespace/line_length',
201
'whitespace/newline',
202
'whitespace/operators',
204
'whitespace/semicolon',
209
# The default state of the category filter. This is overrided by the --filter=
210
# flag. By default all errors are on, so only add here categories that should be
211
# off by default (i.e., categories that must be enabled by the --filter= flags).
212
# All entries here should start with a '-' or '+', as in the --filter= flag.
213
_DEFAULT_FILTERS = [ '-build/include_alpha' ]
215
# We used to check for high-bit characters, but after much discussion we
216
# decided those were OK, as long as they were in UTF-8 and didn't represent
217
# hard-coded international strings, which belong in a seperate i18n file.
219
# Headers that we consider STL headers.
220
_STL_HEADERS = frozenset([
221
'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
222
'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
223
'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'new',
224
'pair.h', 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
225
'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
226
'utility', 'vector', 'vector.h',
230
# Non-STL C++ system headers.
231
_CPP_HEADERS = frozenset([
232
'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
233
'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
234
'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
235
'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
236
'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
237
'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
238
'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h',
239
'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
240
'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h',
241
'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h',
242
'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
243
'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
244
'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
248
# Assertion macros. These are defined in base/logging.h and
249
# testing/base/gunit.h. Note that the _M versions need to come first
250
# for substring matching to work.
253
'EXPECT_TRUE_M', 'EXPECT_TRUE',
254
'ASSERT_TRUE_M', 'ASSERT_TRUE',
255
'EXPECT_FALSE_M', 'EXPECT_FALSE',
256
'ASSERT_FALSE_M', 'ASSERT_FALSE',
259
# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
260
_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
262
for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
263
('>=', 'GE'), ('>', 'GT'),
264
('<=', 'LE'), ('<', 'LT')]:
265
_CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
266
_CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
267
_CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
268
_CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
269
_CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
270
_CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
272
for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
273
('>=', 'LT'), ('>', 'LE'),
274
('<=', 'GT'), ('<', 'GE')]:
275
_CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
276
_CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
277
_CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
278
_CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
281
# These constants define types of headers for use with
282
# _IncludeState.CheckNextIncludeOrder().
285
_LIKELY_MY_HEADER = 3
286
_POSSIBLE_MY_HEADER = 4
290
_regexp_compile_cache = {}
292
# Finds occurrences of NOLINT or NOLINT(...).
293
_RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?')
295
# {str, set(int)}: a map from error categories to sets of linenumbers
296
# on which those errors are expected and should be suppressed.
297
_error_suppressions = {}
299
def ParseNolintSuppressions(filename, raw_line, linenum, error):
300
"""Updates the global list of error-suppressions.
302
Parses any NOLINT comments on the current line, updating the global
303
error_suppressions store. Reports an error if the NOLINT comment
307
filename: str, the name of the input file.
308
raw_line: str, the line of input text, with comments.
309
linenum: int, the number of the current line.
310
error: function, an error handler.
312
# FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*).
313
m = _RE_SUPPRESSION.search(raw_line)
315
category = m.group(1)
316
if category in (None, '(*)'): # => "suppress all"
317
_error_suppressions.setdefault(None, set()).add(linenum)
319
if category.startswith('(') and category.endswith(')'):
320
category = category[1:-1]
321
if category in _ERROR_CATEGORIES:
322
_error_suppressions.setdefault(category, set()).add(linenum)
324
error(filename, linenum, 'readability/nolint', 5,
325
'Unknown NOLINT error category: %s' % category)
328
def ResetNolintSuppressions():
329
"Resets the set of NOLINT suppressions to empty."
330
_error_suppressions.clear()
333
def IsErrorSuppressedByNolint(category, linenum):
334
"""Returns true if the specified error category is suppressed on this line.
336
Consults the global error_suppressions map populated by
337
ParseNolintSuppressions/ResetNolintSuppressions.
340
category: str, the category of the error.
341
linenum: int, the current line number.
343
bool, True iff the error should be suppressed due to a NOLINT comment.
345
return (linenum in _error_suppressions.get(category, set()) or
346
linenum in _error_suppressions.get(None, set()))
348
def Match(pattern, s):
349
"""Matches the string with the pattern, caching the compiled regexp."""
350
# The regexp compilation caching is inlined in both Match and Search for
351
# performance reasons; factoring it out into a separate function turns out
352
# to be noticeably expensive.
353
if not pattern in _regexp_compile_cache:
354
_regexp_compile_cache[pattern] = sre_compile.compile(pattern)
355
return _regexp_compile_cache[pattern].match(s)
358
def Search(pattern, s):
359
"""Searches the string for the pattern, caching the compiled regexp."""
360
if not pattern in _regexp_compile_cache:
361
_regexp_compile_cache[pattern] = sre_compile.compile(pattern)
362
return _regexp_compile_cache[pattern].search(s)
365
class _IncludeState(dict):
366
"""Tracks line numbers for includes, and the order in which includes appear.
368
As a dict, an _IncludeState object serves as a mapping between include
369
filename and line number on which that file was included.
371
Call CheckNextIncludeOrder() once for each header in the file, passing
372
in the type constants defined above. Calls in an illegal order will
373
raise an _IncludeError with an appropriate error message.
376
# self._section will move monotonically through this set. If it ever
377
# needs to move backwards, CheckNextIncludeOrder will raise an error.
385
_C_SYS_HEADER: 'C system header',
386
_CPP_SYS_HEADER: 'C++ system header',
387
_LIKELY_MY_HEADER: 'header this file implements',
388
_POSSIBLE_MY_HEADER: 'header this file may implement',
389
_OTHER_HEADER: 'other header',
392
_INITIAL_SECTION: "... nothing. (This can't be an error.)",
393
_MY_H_SECTION: 'a header this file implements',
394
_C_SECTION: 'C system header',
395
_CPP_SECTION: 'C++ system header',
396
_OTHER_H_SECTION: 'other header',
401
# The name of the current section.
402
self._section = self._INITIAL_SECTION
403
# The path of last found header.
404
self._last_header = ''
406
def CanonicalizeAlphabeticalOrder(self, header_path):
407
"""Returns a path canonicalized for alphabetical comparisson.
409
- replaces "-" with "_" so they both cmp the same.
410
- removes '-inl' since we don't require them to be after the main header.
411
- lowercase everything, just in case.
414
header_path: Path to be canonicalized.
419
return header_path.replace('-inl.hh', '.hh').replace('-', '_').lower()
421
def IsInAlphabeticalOrder(self, header_path):
422
"""Check if a header is in alphabetical order with the previous header.
425
header_path: Header to be checked.
428
Returns true if the header is in alphabetical order.
430
canonical_header = self.CanonicalizeAlphabeticalOrder(header_path)
431
if self._last_header > canonical_header:
433
self._last_header = canonical_header
436
def CheckNextIncludeOrder(self, header_type):
437
"""Returns a non-empty error message if the next header is out of order.
439
This function also updates the internal state to be ready to check
443
header_type: One of the _XXX_HEADER constants defined above.
446
The empty string if the header is in the right order, or an
447
error message describing what's wrong.
450
error_message = ('Found %s after %s' %
451
(self._TYPE_NAMES[header_type],
452
self._SECTION_NAMES[self._section]))
454
last_section = self._section
456
if header_type == _C_SYS_HEADER:
457
if self._section <= self._C_SECTION:
458
self._section = self._C_SECTION
460
self._last_header = ''
462
elif header_type == _CPP_SYS_HEADER:
463
if self._section <= self._CPP_SECTION:
464
self._section = self._CPP_SECTION
466
self._last_header = ''
468
elif header_type == _LIKELY_MY_HEADER:
469
if self._section <= self._MY_H_SECTION:
470
self._section = self._MY_H_SECTION
472
self._section = self._OTHER_H_SECTION
473
elif header_type == _POSSIBLE_MY_HEADER:
474
if self._section <= self._MY_H_SECTION:
475
self._section = self._MY_H_SECTION
477
# This will always be the fallback because we're not sure
478
# enough that the header is associated with this file.
479
self._section = self._OTHER_H_SECTION
481
assert header_type == _OTHER_HEADER
482
self._section = self._OTHER_H_SECTION
484
if last_section != self._section:
485
self._last_header = ''
490
class _CppLintState(object):
491
"""Maintains module-wide state.."""
494
self.verbose_level = 1 # global setting.
495
self.error_count = 0 # global count of reported errors
496
# filters to apply when emitting error messages
497
self.filters = _DEFAULT_FILTERS[:]
498
self.counting = 'total' # In what way are we counting errors?
499
self.errors_by_category = {} # string to int dict storing error counts
500
self.output_handle = sys.stderr # io object for writing errors
503
# "emacs" - format that emacs can parse (default)
504
# "vs7" - format that Microsoft Visual Studio 7 can parse
505
self.output_format = 'emacs'
507
def SetOutputFormat(self, output_format):
508
"""Sets the output format for errors."""
509
self.output_format = output_format
511
def SetVerboseLevel(self, level):
512
"""Sets the module's verbosity, and returns the previous setting."""
513
last_verbose_level = self.verbose_level
514
self.verbose_level = level
515
return last_verbose_level
517
def SetCountingStyle(self, counting_style):
518
"""Sets the module's counting options."""
519
self.counting = counting_style
521
def SetOutputHandler(self, file_handle):
522
"""Sets the module's handler for error messages"""
523
self.output_handle = file_handle
525
def SetFilters(self, filters):
526
"""Sets the error-message filters.
528
These filters are applied when deciding whether to emit a given
532
filters: A string of comma-separated filters (eg "+whitespace/indent").
533
Each filter should start with + or -; else we die.
536
ValueError: The comma-separated filters did not all start with '+' or '-'.
537
E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
539
# Default filters always have less priority than the flag ones.
540
self.filters = _DEFAULT_FILTERS[:]
541
for filt in filters.split(','):
542
clean_filt = filt.strip()
544
self.filters.append(clean_filt)
545
for filt in self.filters:
546
if not (filt.startswith('+') or filt.startswith('-')):
547
raise ValueError('Every filter in --filters must start with + or -'
548
' (%s does not)' % filt)
550
def ResetErrorCounts(self):
551
"""Sets the module's error statistic back to zero."""
553
self.errors_by_category = {}
555
def IncrementErrorCount(self, category):
556
"""Bumps the module's error statistic."""
557
self.error_count += 1
558
if self.counting in ('toplevel', 'detailed'):
559
if self.counting != 'detailed':
560
category = category.split('/')[0]
561
if category not in self.errors_by_category:
562
self.errors_by_category[category] = 0
563
self.errors_by_category[category] += 1
565
def PrintErrorCounts(self):
566
"""Print a summary of errors by category, and the total."""
567
for category, count in self.errors_by_category.iteritems():
568
_cpplint_state.output_handle.write('Category \'%s\' errors found: %d\n' %
570
_cpplint_state.output_handle.write('Total errors found: %d\n' % self.error_count)
572
_cpplint_state = _CppLintState()
576
"""Gets the module's output format."""
577
return _cpplint_state.output_format
580
def _SetOutputFormat(output_format):
581
"""Sets the module's output format."""
582
_cpplint_state.SetOutputFormat(output_format)
586
"""Returns the module's verbosity setting."""
587
return _cpplint_state.verbose_level
590
def _SetVerboseLevel(level):
591
"""Sets the module's verbosity, and returns the previous setting."""
592
return _cpplint_state.SetVerboseLevel(level)
595
def _SetCountingStyle(level):
596
"""Sets the module's counting options."""
597
_cpplint_state.SetCountingStyle(level)
601
"""Returns the module's list of output filters, as a list."""
602
return _cpplint_state.filters
605
def _SetFilters(filters):
606
"""Sets the module's error-message filters.
608
These filters are applied when deciding whether to emit a given
612
filters: A string of comma-separated filters (eg "whitespace/indent").
613
Each filter should start with + or -; else we die.
615
_cpplint_state.SetFilters(filters)
618
class _FunctionState(object):
619
"""Tracks current function name and the number of lines in its body."""
621
_NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc.
622
_TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER.
625
self.in_a_function = False
626
self.lines_in_function = 0
627
self.current_function = ''
629
def Begin(self, function_name):
630
"""Start analyzing function body.
633
function_name: The name of the function being tracked.
635
self.in_a_function = True
636
self.lines_in_function = 0
637
self.current_function = function_name
640
"""Count line in current function body."""
641
if self.in_a_function:
642
self.lines_in_function += 1
644
def Check(self, error, filename, linenum):
645
"""Report if too many lines in function body.
648
error: The function to call with any errors found.
649
filename: The name of the current file.
650
linenum: The number of the line to check.
652
if Match(r'T(EST|est)', self.current_function):
653
base_trigger = self._TEST_TRIGGER
655
base_trigger = self._NORMAL_TRIGGER
656
trigger = base_trigger * 2**_VerboseLevel()
658
if self.lines_in_function > trigger:
659
error_level = int(math.log(self.lines_in_function / base_trigger, 2))
660
# 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
663
error(filename, linenum, 'readability/fn_size', error_level,
664
'Small and focused functions are preferred:'
665
' %s has %d non-comment lines'
666
' (error triggered by exceeding %d lines).' % (
667
self.current_function, self.lines_in_function, trigger))
670
"""Stop analizing function body."""
671
self.in_a_function = False
674
class _IncludeError(Exception):
675
"""Indicates a problem with the include order in a file."""
680
"""Provides utility functions for filenames.
682
FileInfo provides easy access to the components of a file's path
683
relative to the project root.
686
def __init__(self, filename):
687
self._filename = filename
690
"""Make Windows paths like Unix."""
691
return os.path.abspath(self._filename).replace('\\', '/')
693
def RepositoryName(self):
694
"""FullName after removing the local path to the repository.
696
If we have a real absolute path name here we can try to do something smart:
697
detecting the root of the checkout and truncating /path/to/checkout from
698
the name so that we get header guards that don't include things like
699
"C:\Documents and Settings\..." or "/home/username/..." in them and thus
700
people on different computers who have checked the source out to different
701
locations won't see bogus errors.
703
fullname = self.FullName()
705
if os.path.exists(fullname):
706
project_dir = os.path.dirname(fullname)
708
if os.path.exists(os.path.join(project_dir, ".svn")):
709
# If there's a .svn file in the current directory, we recursively look
710
# up the directory tree for the top of the SVN checkout
711
root_dir = project_dir
712
one_up_dir = os.path.dirname(root_dir)
713
while os.path.exists(os.path.join(one_up_dir, ".svn")):
714
root_dir = os.path.dirname(root_dir)
715
one_up_dir = os.path.dirname(one_up_dir)
717
prefix = os.path.commonprefix([root_dir, project_dir])
718
return fullname[len(prefix) + 1:]
720
# Not SVN? Try to find a git or hg top level directory by searching up
721
# from the current path.
722
root_dir = os.path.dirname(fullname)
723
while (root_dir != os.path.dirname(root_dir) and
724
not os.path.exists(os.path.join(root_dir, ".git")) and
725
not os.path.exists(os.path.join(root_dir, ".hg"))):
726
root_dir = os.path.dirname(root_dir)
728
if (os.path.exists(os.path.join(root_dir, ".git")) or
729
os.path.exists(os.path.join(root_dir, ".hg"))):
730
prefix = os.path.commonprefix([root_dir, project_dir])
731
return fullname[len(prefix) + 1:]
733
# Don't know what to do; header guard warnings may be wrong...
737
"""Splits the file into the directory, basename, and extension.
739
For 'chrome/browser/browser.cc', Split() would
740
return ('chrome/browser', 'browser', '.cc')
743
A tuple of (directory, basename, extension).
746
googlename = self.RepositoryName()
747
project, rest = os.path.split(googlename)
748
return (project,) + os.path.splitext(rest)
751
"""File base name - text after the final slash, before the final period."""
752
return self.Split()[1]
755
"""File extension - text following the final period."""
756
return self.Split()[2]
758
def NoExtension(self):
759
"""File has no source file extension."""
760
return '/'.join(self.Split()[0:2])
763
"""File has a source file extension."""
764
return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
767
def _ShouldPrintError(category, confidence, linenum):
768
"""Returns true iff confidence >= verbose, category passes
769
filter and is not NOLINT-suppressed."""
771
# There are three ways we might decide not to print an error message:
772
# a "NOLINT(category)" comment appears in the source,
773
# the verbosity level isn't high enough, or the filters filter it out.
774
if IsErrorSuppressedByNolint(category, linenum):
776
if confidence < _cpplint_state.verbose_level:
780
for one_filter in _Filters():
781
if one_filter.startswith('-'):
782
if category.startswith(one_filter[1:]):
784
elif one_filter.startswith('+'):
785
if category.startswith(one_filter[1:]):
788
assert False # should have been checked for in SetFilter.
795
def Error(filename, linenum, category, confidence, message):
796
"""Logs the fact we've found a lint error.
798
We log where the error was found, and also our confidence in the error,
799
that is, how certain we are this is a legitimate style regression, and
800
not a misidentification or a use that's sometimes justified.
802
False positives can be suppressed by the use of
803
"cpplint(category)" comments on the offending line. These are
804
parsed into _error_suppressions.
807
filename: The name of the file containing the error.
808
linenum: The number of the line containing the error.
809
category: A string used to describe the "category" this bug
810
falls under: "whitespace", say, or "runtime". Categories
811
may have a hierarchy separated by slashes: "whitespace/indent".
812
confidence: A number from 1-5 representing a confidence score for
813
the error, with 5 meaning that we are certain of the problem,
814
and 1 meaning that it could be a legitimate construct.
815
message: The error message.
817
if _ShouldPrintError(category, confidence, linenum):
818
_cpplint_state.IncrementErrorCount(category)
819
if _cpplint_state.output_format == 'vs7':
820
_cpplint_state.output_handle.write('%s(%s): %s [%s] [%d]\n' % (
821
filename, linenum, message, category, confidence))
823
_cpplint_state.output_handle.write('%s:%s: %s [%s] [%d]\n' % (
824
filename, linenum, message, category, confidence))
827
# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
828
_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
829
r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
830
# Matches strings. Escape codes should already be removed by ESCAPES.
831
_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
832
# Matches characters. Escape codes should already be removed by ESCAPES.
833
_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
834
# Matches multi-line C++ comments.
835
# This RE is a little bit more complicated than one might expect, because we
836
# have to take care of space removals tools so we can handle comments inside
838
# The current rule is: We only clear spaces from both sides when we're at the
839
# end of the line. Otherwise, we try to remove spaces from the right side,
840
# if this doesn't work we try on left side but only if there's a non-character
842
_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
843
r"""(\s*/\*.*\*/\s*$|
846
/\*.*\*/)""", re.VERBOSE)
849
def IsCppString(line):
850
"""Does line terminate so, that the next symbol is in string constant.
852
This function does not consider single-line nor multi-line comments.
855
line: is a partial line of code starting from the 0..n.
858
True, if next character appended to 'line' is inside a
862
line = line.replace(r'\\', 'XX') # after this, \\" does not match to \"
863
return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
866
def FindNextMultiLineCommentStart(lines, lineix):
867
"""Find the beginning marker for a multiline comment."""
868
while lineix < len(lines):
869
if lines[lineix].strip().startswith('/*'):
870
# Only return this marker if the comment goes beyond this line
871
if lines[lineix].strip().find('*/', 2) < 0:
877
def FindNextMultiLineCommentEnd(lines, lineix):
878
"""We are inside a comment, find the end marker."""
879
while lineix < len(lines):
880
if lines[lineix].strip().endswith('*/'):
886
def RemoveMultiLineCommentsFromRange(lines, begin, end):
887
"""Clears a range of lines for multi-line comments."""
888
# Having // dummy comments makes the lines non-empty, so we will not get
889
# unnecessary blank line warnings later in the code.
890
for i in range(begin, end):
891
lines[i] = '// dummy'
894
def RemoveMultiLineComments(filename, lines, error):
895
"""Removes multiline (c-style) comments from lines."""
897
while lineix < len(lines):
898
lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
899
if lineix_begin >= len(lines):
901
lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
902
if lineix_end >= len(lines):
903
error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
904
'Could not find end of multi-line comment')
906
RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
907
lineix = lineix_end + 1
910
def CleanseComments(line):
911
"""Removes //-comments and single-line C-style /* */ comments.
914
line: A line of C++ source.
917
The line with single-line comments removed.
919
commentpos = line.find('//')
920
if commentpos != -1 and not IsCppString(line[:commentpos]):
921
line = line[:commentpos]
922
# get rid of /* ... */
923
return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
926
class CleansedLines(object):
927
"""Holds 3 copies of all lines with different preprocessing applied to them.
929
1) elided member contains lines without strings and comments,
930
2) lines member contains lines without comments, and
931
3) raw member contains all the lines without processing.
932
All these three members are of <type 'list'>, and of the same length.
935
def __init__(self, lines):
938
self.raw_lines = lines
939
self.num_lines = len(lines)
940
for linenum in range(len(lines)):
941
self.lines.append(CleanseComments(lines[linenum]))
942
elided = self._CollapseStrings(lines[linenum])
943
self.elided.append(CleanseComments(elided))
946
"""Returns the number of lines represented."""
947
return self.num_lines
950
def _CollapseStrings(elided):
951
"""Collapses strings and chars on a line to simple "" or '' blocks.
953
We nix strings first so we're not fooled by text like '"http://"'
956
elided: The line being processed.
959
The line with collapsed strings.
961
if not _RE_PATTERN_INCLUDE.match(elided):
962
# Remove escaped characters first to make quote/single quote collapsing
963
# basic. Things that look like escaped characters shouldn't occur
964
# outside of strings and chars.
965
elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
966
elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
967
elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
971
def CloseExpression(clean_lines, linenum, pos):
972
"""If input points to ( or { or [, finds the position that closes it.
974
If lines[linenum][pos] points to a '(' or '{' or '[', finds the the
975
linenum/pos that correspond to the closing of the expression.
978
clean_lines: A CleansedLines instance containing the file.
979
linenum: The number of the line to check.
980
pos: A position on the line.
983
A tuple (line, linenum, pos) pointer *past* the closing brace, or
984
(line, len(lines), -1) if we never find a close. Note we ignore
985
strings and comments when matching; and the line we return is the
986
'cleansed' line at linenum.
989
line = clean_lines.elided[linenum]
990
startchar = line[pos]
991
if startchar not in '({[':
992
return (line, clean_lines.NumLines(), -1)
993
if startchar == '(': endchar = ')'
994
if startchar == '[': endchar = ']'
995
if startchar == '{': endchar = '}'
997
num_open = line.count(startchar) - line.count(endchar)
998
while linenum < clean_lines.NumLines() and num_open > 0:
1000
line = clean_lines.elided[linenum]
1001
num_open += line.count(startchar) - line.count(endchar)
1002
# OK, now find the endchar that actually got us back to even
1004
while num_open >= 0:
1005
endpos = line.rfind(')', 0, endpos)
1006
num_open -= 1 # chopped off another )
1007
return (line, linenum, endpos + 1)
1010
def CheckForCopyright(filename, lines, error):
1011
"""Logs an error if no Copyright message appears at the top of the file."""
1013
# We'll say it should occur by line 10. Don't forget there's a
1014
# dummy line at the front.
1015
for line in xrange(1, min(len(lines), 11)):
1016
if re.search(r'Copyright', lines[line], re.I): break
1017
else: # means no copyright line was found
1018
error(filename, 0, 'legal/copyright', 5,
1019
'No copyright message found. '
1020
'You should have a line: "Copyright [year] <Copyright Owner>"')
1023
def GetHeaderGuardCPPVariable(filename):
1024
"""Returns the CPP variable that should be used as a header guard.
1027
filename: The name of a C++ header file.
1030
The CPP variable that should be used as a header guard in the
1035
# Restores original filename in case that cpplint is invoked from Emacs's
1037
filename = re.sub(r'_flymake\.hh$', '.hh', filename)
1039
fileinfo = FileInfo(filename)
1040
return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_'
1043
def CheckForHeaderGuard(filename, lines, error):
1044
"""Checks that the file contains a header guard.
1046
Logs an error if no #ifndef header guard is present. For other
1047
headers, checks that the full pathname is used.
1050
filename: The name of the C++ header file.
1051
lines: An array of strings, each representing a line of the file.
1052
error: The function to call with any errors found.
1055
cppvar = GetHeaderGuardCPPVariable(filename)
1062
for linenum, line in enumerate(lines):
1063
linesplit = line.split()
1064
if len(linesplit) >= 2:
1065
# find the first occurrence of #ifndef and #define, save arg
1066
if not ifndef and linesplit[0] == '#ifndef':
1067
# set ifndef to the header guard presented on the #ifndef line.
1068
ifndef = linesplit[1]
1069
ifndef_linenum = linenum
1070
if not define and linesplit[0] == '#define':
1071
define = linesplit[1]
1072
# find the last occurrence of #endif, save entire line
1073
if line.startswith('#endif'):
1075
endif_linenum = linenum
1077
if not ifndef or not define or ifndef != define:
1078
error(filename, 0, 'build/header_guard', 5,
1079
'No #ifndef header guard found, suggested CPP variable is: %s' %
1083
# The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
1084
# for backward compatibility.
1085
if ifndef != cppvar:
1087
if ifndef != cppvar + '_':
1090
ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum,
1092
error(filename, ifndef_linenum, 'build/header_guard', error_level,
1093
'#ifndef header guard has wrong style, please use: %s' % cppvar)
1095
if endif != ('#endif // %s' % cppvar):
1097
if endif != ('#endif // %s' % (cppvar + '_')):
1100
ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum,
1102
error(filename, endif_linenum, 'build/header_guard', error_level,
1103
'#endif line should be "#endif // %s"' % cppvar)
1106
def CheckForUnicodeReplacementCharacters(filename, lines, error):
1107
"""Logs an error for each line containing Unicode replacement characters.
1109
These indicate that either the file contained invalid UTF-8 (likely)
1110
or Unicode replacement characters (which it shouldn't). Note that
1111
it's possible for this to throw off line numbering if the invalid
1112
UTF-8 occurred adjacent to a newline.
1115
filename: The name of the current file.
1116
lines: An array of strings, each representing a line of the file.
1117
error: The function to call with any errors found.
1119
for linenum, line in enumerate(lines):
1120
if u'\ufffd' in line:
1121
error(filename, linenum, 'readability/utf8', 5,
1122
'Line contains invalid UTF-8 (or Unicode replacement character).')
1125
def CheckForNewlineAtEOF(filename, lines, error):
1126
"""Logs an error if there is no newline char at the end of the file.
1129
filename: The name of the current file.
1130
lines: An array of strings, each representing a line of the file.
1131
error: The function to call with any errors found.
1134
# The array lines() was created by adding two newlines to the
1135
# original file (go figure), then splitting on \n.
1136
# To verify that the file ends in \n, we just have to make sure the
1137
# last-but-two element of lines() exists and is empty.
1138
if len(lines) < 3 or lines[-2]:
1139
error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
1140
'Could not find a newline character at the end of the file.')
1143
def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
1144
"""Logs an error if we see /* ... */ or "..." that extend past one line.
1146
/* ... */ comments are legit inside macros, for one line.
1147
Otherwise, we prefer // comments, so it's ok to warn about the
1148
other. Likewise, it's ok for strings to extend across multiple
1149
lines, as long as a line continuation character (backslash)
1150
terminates each line. Although not currently prohibited by the C++
1151
style guide, it's ugly and unnecessary. We don't do well with either
1152
in this lint program, so we warn about both.
1155
filename: The name of the current file.
1156
clean_lines: A CleansedLines instance containing the file.
1157
linenum: The number of the line to check.
1158
error: The function to call with any errors found.
1160
line = clean_lines.elided[linenum]
1162
# Remove all \\ (escaped backslashes) from the line. They are OK, and the
1163
# second (escaped) slash may trigger later \" detection erroneously.
1164
line = line.replace('\\\\', '')
1166
if line.count('/*') > line.count('*/'):
1167
error(filename, linenum, 'readability/multiline_comment', 5,
1168
'Complex multi-line /*...*/-style comment found. '
1169
'Lint may give bogus warnings. '
1170
'Consider replacing these with //-style comments, '
1171
'with #if 0...#endif, '
1172
'or with more clearly structured multi-line comments.')
1174
if (line.count('"') - line.count('\\"')) % 2:
1175
error(filename, linenum, 'readability/multiline_string', 5,
1176
'Multi-line string ("...") found. This lint script doesn\'t '
1177
'do well with such strings, and may give bogus warnings. They\'re '
1178
'ugly and unnecessary, and you should use concatenation instead".')
1182
('asctime(', 'asctime_r('),
1183
('ctime(', 'ctime_r('),
1184
('getgrgid(', 'getgrgid_r('),
1185
('getgrnam(', 'getgrnam_r('),
1186
('getlogin(', 'getlogin_r('),
1187
('getpwnam(', 'getpwnam_r('),
1188
('getpwuid(', 'getpwuid_r('),
1189
('gmtime(', 'gmtime_r('),
1190
('localtime(', 'localtime_r('),
1191
('rand(', 'rand_r('),
1192
('readdir(', 'readdir_r('),
1193
('strtok(', 'strtok_r('),
1194
('ttyname(', 'ttyname_r('),
1198
def CheckPosixThreading(filename, clean_lines, linenum, error):
1199
"""Checks for calls to thread-unsafe functions.
1201
Much code has been originally written without consideration of
1202
multi-threading. Also, engineers are relying on their old experience;
1203
they have learned posix before threading extensions were added. These
1204
tests guide the engineers to use thread-safe functions (when using
1208
filename: The name of the current file.
1209
clean_lines: A CleansedLines instance containing the file.
1210
linenum: The number of the line to check.
1211
error: The function to call with any errors found.
1213
line = clean_lines.elided[linenum]
1214
for single_thread_function, multithread_safe_function in threading_list:
1215
ix = line.find(single_thread_function)
1216
# Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1217
if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
1218
line[ix - 1] not in ('_', '.', '>'))):
1219
error(filename, linenum, 'runtime/threadsafe_fn', 2,
1220
'Consider using ' + multithread_safe_function +
1221
'...) instead of ' + single_thread_function +
1222
'...) for improved thread safety.')
1225
# Matches invalid increment: *count++, which moves pointer instead of
1226
# incrementing a value.
1227
_RE_PATTERN_INVALID_INCREMENT = re.compile(
1228
r'^\s*\*\w+(\+\+|--);')
1231
def CheckInvalidIncrement(filename, clean_lines, linenum, error):
1232
"""Checks for invalid increment *count++.
1234
For example following function:
1235
void increment_counter(int* count) {
1238
is invalid, because it effectively does count++, moving pointer, and should
1239
be replaced with ++*count, (*count)++ or *count += 1.
1242
filename: The name of the current file.
1243
clean_lines: A CleansedLines instance containing the file.
1244
linenum: The number of the line to check.
1245
error: The function to call with any errors found.
1247
line = clean_lines.elided[linenum]
1248
if _RE_PATTERN_INVALID_INCREMENT.match(line):
1249
error(filename, linenum, 'runtime/invalid_increment', 5,
1250
'Changing pointer instead of value (or unused value of operator*).')
1253
class _ClassInfo(object):
1254
"""Stores information about a class."""
1256
def __init__(self, name, linenum):
1258
self.linenum = linenum
1259
self.seen_open_brace = False
1260
self.is_derived = False
1261
self.virtual_method_linenumber = None
1262
self.has_virtual_destructor = False
1263
self.brace_depth = 0
1266
class _ClassState(object):
1267
"""Holds the current state of the parse relating to class declarations.
1269
It maintains a stack of _ClassInfos representing the parser's guess
1270
as to the current nesting of class declarations. The innermost class
1271
is at the top (back) of the stack. Typically, the stack will either
1272
be empty or have exactly one entry.
1276
self.classinfo_stack = []
1278
def CheckFinished(self, filename, error):
1279
"""Checks that all classes have been completely parsed.
1281
Call this when all lines in a file have been processed.
1283
filename: The name of the current file.
1284
error: The function to call with any errors found.
1286
if self.classinfo_stack:
1287
# Note: This test can result in false positives if #ifdef constructs
1288
# get in the way of brace matching. See the testBuildClass test in
1289
# cpplint_unittest.py for an example of this.
1290
error(filename, self.classinfo_stack[0].linenum, 'build/class', 5,
1291
'Failed to find complete declaration of class %s' %
1292
self.classinfo_stack[0].name)
1295
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
1296
class_state, error):
1297
"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
1299
Complain about several constructs which gcc-2 accepts, but which are
1300
not standard C++. Warning about these in lint is one way to ease the
1301
transition to new compilers.
1302
- put storage class first (e.g. "static const" instead of "const static").
1303
- "%lld" instead of %qd" in printf-type functions.
1304
- "%1$d" is non-standard in printf-type functions.
1305
- "\%" is an undefined character escape sequence.
1306
- text after #endif is not allowed.
1307
- invalid inner-style forward declaration.
1308
- >? and <? operators, and their >?= and <?= cousins.
1309
- classes with virtual methods need virtual destructors (compiler warning
1310
available, but not turned on yet.)
1312
Additionally, check for constructor/destructor style violations and reference
1313
members, as it is very convenient to do so while checking for
1317
filename: The name of the current file.
1318
clean_lines: A CleansedLines instance containing the file.
1319
linenum: The number of the line to check.
1320
class_state: A _ClassState instance which maintains information about
1321
the current stack of nested class declarations being parsed.
1322
error: A callable to which errors are reported, which takes 4 arguments:
1323
filename, line number, error level, and message
1326
# Remove comments from the line, but leave in strings for now.
1327
line = clean_lines.lines[linenum]
1329
if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
1330
error(filename, linenum, 'runtime/printf_format', 3,
1331
'%q in format strings is deprecated. Use %ll instead.')
1333
if Search(r'printf\s*\(.*".*%\d+\$', line):
1334
error(filename, linenum, 'runtime/printf_format', 2,
1335
'%N$ formats are unconventional. Try rewriting to avoid them.')
1337
# Remove escaped backslashes before looking for undefined escapes.
1338
line = line.replace('\\\\', '')
1340
if Search(r'("|\').*\\(%|\[|\(|{)', line):
1341
error(filename, linenum, 'build/printf_format', 3,
1342
'%, [, (, and { are undefined character escapes. Unescape them.')
1344
# For the rest, work with both comments and strings removed.
1345
line = clean_lines.elided[linenum]
1347
if Search(r'\b(const|volatile|void|char|short|int|long'
1348
r'|float|double|signed|unsigned'
1349
r'|schar|u?int8|u?int16|u?int32|u?int64)'
1350
r'\s+(auto|register|static|extern|typedef)\b',
1352
error(filename, linenum, 'build/storage_class', 5,
1353
'Storage class (static, extern, typedef, etc) should be first.')
1355
if Match(r'\s*#\s*endif\s*[^/\s]+', line):
1356
error(filename, linenum, 'build/endif_comment', 5,
1357
'Uncommented text after #endif is non-standard. Use a comment.')
1359
if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
1360
error(filename, linenum, 'build/forward_decl', 5,
1361
'Inner-style forward declarations are invalid. Remove this line.')
1363
if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
1365
error(filename, linenum, 'build/deprecated', 3,
1366
'>? and <? (max and min) operators are non-standard and deprecated.')
1368
if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
1369
# TODO(unknown): Could it be expanded safely to arbitrary references,
1370
# without triggering too many false positives? The first
1371
# attempt triggered 5 warnings for mostly benign code in the regtest, hence
1373
# Here's the original regexp, for the reference:
1374
# type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
1375
# r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
1376
error(filename, linenum, 'runtime/member_string_references', 2,
1377
'const string& members are dangerous. It is much better to use '
1378
'alternatives, such as pointers or simple constants.')
1380
# Track class entry and exit, and attempt to find cases within the
1381
# class declaration that don't meet the C++ style
1382
# guidelines. Tracking is very dependent on the code matching Google
1383
# style guidelines, but it seems to perform well enough in testing
1384
# to be a worthwhile addition to the checks.
1385
classinfo_stack = class_state.classinfo_stack
1386
# Look for a class declaration
1387
class_decl_match = Match(
1388
r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line)
1389
if class_decl_match:
1390
classinfo_stack.append(_ClassInfo(class_decl_match.group(3), linenum))
1392
# Everything else in this function uses the top of the stack if it's
1394
if not classinfo_stack:
1397
classinfo = classinfo_stack[-1]
1399
# If the opening brace hasn't been seen look for it and also
1400
# parent class declarations.
1401
if not classinfo.seen_open_brace:
1402
# If the line has a ';' in it, assume it's a forward declaration or
1403
# a single-line class declaration, which we won't process.
1404
if line.find(';') != -1:
1405
classinfo_stack.pop()
1407
classinfo.seen_open_brace = (line.find('{') != -1)
1408
# Look for a bare ':'
1409
if Search('(^|[^:]):($|[^:])', line):
1410
classinfo.is_derived = True
1411
if not classinfo.seen_open_brace:
1412
return # Everything else in this function is for after open brace
1414
# The class may have been declared with namespace or classname qualifiers.
1415
# The constructor and destructor will not have those qualifiers.
1416
base_classname = classinfo.name.split('::')[-1]
1418
# Look for single-argument constructors that aren't marked explicit.
1419
# Technically a valid construct, but against style.
1420
args = Match(r'(?<!explicit)\s+%s\s*\(([^,()]+)\)'
1421
% re.escape(base_classname),
1424
args.group(1) != 'void' and
1425
not Match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
1426
args.group(1).strip())):
1427
error(filename, linenum, 'runtime/explicit', 5,
1428
'Single-argument constructors should be marked explicit.')
1430
# Look for methods declared virtual.
1431
if Search(r'\bvirtual\b', line):
1432
classinfo.virtual_method_linenumber = linenum
1433
# Only look for a destructor declaration on the same line. It would
1434
# be extremely unlikely for the destructor declaration to occupy
1435
# more than one line.
1436
if Search(r'~%s\s*\(' % base_classname, line):
1437
classinfo.has_virtual_destructor = True
1439
# Look for class end.
1440
brace_depth = classinfo.brace_depth
1441
brace_depth = brace_depth + line.count('{') - line.count('}')
1442
if brace_depth <= 0:
1443
classinfo = classinfo_stack.pop()
1444
# Try to detect missing virtual destructor declarations.
1445
# For now, only warn if a non-derived class with virtual methods lacks
1446
# a virtual destructor. This is to make it less likely that people will
1447
# declare derived virtual destructors without declaring the base
1448
# destructor virtual.
1449
if ((classinfo.virtual_method_linenumber is not None) and
1450
(not classinfo.has_virtual_destructor) and
1451
(not classinfo.is_derived)): # Only warn for base classes
1452
error(filename, classinfo.linenum, 'runtime/virtual', 4,
1453
'The class %s probably needs a virtual destructor due to '
1454
'having virtual method(s), one declared at line %d.'
1455
% (classinfo.name, classinfo.virtual_method_linenumber))
1457
classinfo.brace_depth = brace_depth
1460
def CheckSpacingForFunctionCall(filename, line, linenum, error):
1461
"""Checks for the correctness of various spacing around function calls.
1464
filename: The name of the current file.
1465
line: The text of the line to check.
1466
linenum: The number of the line to check.
1467
error: The function to call with any errors found.
1470
# Since function calls often occur inside if/for/while/switch
1471
# expressions - which have their own, more liberal conventions - we
1472
# first see if we should be looking inside such an expression for a
1473
# function call, to which we can apply more strict standards.
1474
fncall = line # if there's no control flow construct, look at whole line
1475
for pattern in (r'\bif\s*\((.*)\)\s*{',
1476
r'\bfor\s*\((.*)\)\s*{',
1477
r'\bwhile\s*\((.*)\)\s*[{;]',
1478
r'\bswitch\s*\((.*)\)\s*{'):
1479
match = Search(pattern, line)
1481
fncall = match.group(1) # look inside the parens for function calls
1484
# Except in if/for/while/switch, there should never be space
1485
# immediately inside parens (eg "f( 3, 4 )"). We make an exception
1486
# for nested parens ( (a+b) + c ). Likewise, there should never be
1487
# a space before a ( when it's a function argument. I assume it's a
1488
# function argument when the char before the whitespace is legal in
1489
# a function name (alnum + _) and we're not starting a macro. Also ignore
1490
# pointers and references to arrays and functions coz they're too tricky:
1491
# we use a very simple way to recognize these:
1492
# " (something)(maybe-something)" or
1493
# " (something)(maybe-something," or
1494
# " (something)[something]"
1495
# Note that we assume the contents of [] to be short enough that
1496
# they'll never need to wrap.
1497
if ( # Ignore control structures.
1498
not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and
1499
# Ignore pointers/references to functions.
1500
not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
1501
# Ignore pointers/references to arrays.
1502
not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
1503
if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
1504
error(filename, linenum, 'whitespace/parens', 4,
1505
'Extra space after ( in function call')
1506
elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
1507
error(filename, linenum, 'whitespace/parens', 2,
1508
'Extra space after (')
1509
if (Search(r'\w\s+\(', fncall) and
1510
not Search(r'#\s*define|typedef', fncall)):
1511
error(filename, linenum, 'whitespace/parens', 4,
1512
'Extra space before ( in function call')
1513
# If the ) is followed only by a newline or a { + newline, assume it's
1514
# part of a control statement (if/while/etc), and don't complain
1515
if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
1516
error(filename, linenum, 'whitespace/parens', 2,
1517
'Extra space before )')
1520
def IsBlankLine(line):
1521
"""Returns true if the given line is blank.
1523
We consider a line to be blank if the line is empty or consists of
1527
line: A line of a string.
1530
True, if the given line is blank.
1532
return not line or line.isspace()
1535
def CheckForFunctionLengths(filename, clean_lines, linenum,
1536
function_state, error):
1537
"""Reports for long function bodies.
1539
For an overview why this is done, see:
1540
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
1542
Uses a simplistic algorithm assuming other style guidelines
1543
(especially spacing) are followed.
1544
Only checks unindented functions, so class members are unchecked.
1545
Trivial bodies are unchecked, so constructors with huge initializer lists
1547
Blank/comment lines are not counted so as to avoid encouraging the removal
1548
of vertical space and commments just to get through a lint check.
1549
NOLINT *on the last line of a function* disables this check.
1552
filename: The name of the current file.
1553
clean_lines: A CleansedLines instance containing the file.
1554
linenum: The number of the line to check.
1555
function_state: Current function name and lines in body so far.
1556
error: The function to call with any errors found.
1558
lines = clean_lines.lines
1559
line = lines[linenum]
1560
raw = clean_lines.raw_lines
1561
raw_line = raw[linenum]
1564
starting_func = False
1565
regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ...
1566
match_result = Match(regexp, line)
1568
# If the name is all caps and underscores, figure it's a macro and
1569
# ignore it, unless it's TEST or TEST_F.
1570
function_name = match_result.group(1).split()[-1]
1571
if function_name == 'TEST' or function_name == 'TEST_F' or (
1572
not Match(r'[A-Z_]+$', function_name)):
1573
starting_func = True
1577
for start_linenum in xrange(linenum, clean_lines.NumLines()):
1578
start_line = lines[start_linenum]
1579
joined_line += ' ' + start_line.lstrip()
1580
if Search(r'(;|})', start_line): # Declarations and trivial functions
1583
elif Search(r'{', start_line):
1585
function = Search(r'((\w|:)*)\(', line).group(1)
1586
if Match(r'TEST', function): # Handle TEST... macros
1587
parameter_regexp = Search(r'(\(.*\))', joined_line)
1588
if parameter_regexp: # Ignore bad syntax
1589
function += parameter_regexp.group(1)
1592
function_state.Begin(function)
1595
# No body for the function (or evidence of a non-function) was found.
1596
error(filename, linenum, 'readability/fn_size', 5,
1597
'Lint failed to find start of function body.')
1598
elif Match(r'^\}\s*$', line): # function end
1599
function_state.Check(error, filename, linenum)
1600
function_state.End()
1601
elif not Match(r'^\s*$', line):
1602
function_state.Count() # Count non-blank/non-comment lines.
1605
_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
1608
def CheckComment(comment, filename, linenum, error):
1609
"""Checks for common mistakes in TODO comments.
1612
comment: The text of the comment from the line in question.
1613
filename: The name of the current file.
1614
linenum: The number of the line to check.
1615
error: The function to call with any errors found.
1617
match = _RE_PATTERN_TODO.match(comment)
1619
# One whitespace is correct; zero whitespace is handled elsewhere.
1620
leading_whitespace = match.group(1)
1621
if len(leading_whitespace) > 1:
1622
error(filename, linenum, 'whitespace/todo', 2,
1623
'Too many spaces before TODO')
1625
username = match.group(2)
1627
error(filename, linenum, 'readability/todo', 2,
1628
'Missing username in TODO; it should look like '
1629
'"// TODO(my_username): Stuff."')
1631
middle_whitespace = match.group(3)
1632
# Comparisons made explicit for correctness -- pylint: disable-msg=C6403
1633
if middle_whitespace != ' ' and middle_whitespace != '':
1634
error(filename, linenum, 'whitespace/todo', 2,
1635
'TODO(my_username) should be followed by a space')
1638
def CheckSpacing(filename, clean_lines, linenum, error):
1639
"""Checks for the correctness of various spacing issues in the code.
1641
Things we check for: spaces around operators, spaces after
1642
if/for/while/switch, no spaces around parens in function calls, two
1643
spaces between code and comment, don't start a block with a blank
1644
line, don't end a function with a blank line, don't have too many
1645
blank lines in a row.
1648
filename: The name of the current file.
1649
clean_lines: A CleansedLines instance containing the file.
1650
linenum: The number of the line to check.
1651
error: The function to call with any errors found.
1654
raw = clean_lines.raw_lines
1657
# Before nixing comments, check if the line is blank for no good
1658
# reason. This includes the first line after a block is opened, and
1659
# blank lines at the end of a function (ie, right before a line like '}'
1660
if IsBlankLine(line):
1661
elided = clean_lines.elided
1662
prev_line = elided[linenum - 1]
1663
prevbrace = prev_line.rfind('{')
1664
# TODO(unknown): Don't complain if line before blank line, and line after,
1665
# both start with alnums and are indented the same amount.
1666
# This ignores whitespace at the start of a namespace block
1667
# because those are not usually indented.
1668
if (prevbrace != -1 and prev_line[prevbrace:].find('}') == -1
1669
and prev_line[:prevbrace].find('namespace') == -1):
1670
# OK, we have a blank line at the start of a code block. Before we
1671
# complain, we check if it is an exception to the rule: The previous
1672
# non-empty line has the paramters of a function header that are indented
1673
# 4 spaces (because they did not fit in a 80 column line when placed on
1674
# the same line as the function name). We also check for the case where
1675
# the previous line is indented 6 spaces, which may happen when the
1676
# initializers of a constructor do not fit into a 80 column line.
1678
if Match(r' {6}\w', prev_line): # Initializer list?
1679
# We are looking for the opening column of initializer list, which
1680
# should be indented 4 spaces to cause 6 space indentation afterwards.
1681
search_position = linenum-2
1682
while (search_position >= 0
1683
and Match(r' {6}\w', elided[search_position])):
1684
search_position -= 1
1685
exception = (search_position >= 0
1686
and elided[search_position][:5] == ' :')
1688
# Search for the function arguments or an initializer list. We use a
1689
# simple heuristic here: If the line is indented 4 spaces; and we have a
1690
# closing paren, without the opening paren, followed by an opening brace
1691
# or colon (for initializer lists) we assume that it is the last line of
1692
# a function header. If we have a colon indented 4 spaces, it is an
1694
exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
1696
or Match(r' {4}:', prev_line))
1699
error(filename, linenum, 'whitespace/blank_line', 2,
1700
'Blank line at the start of a code block. Is this needed?')
1701
# This doesn't ignore whitespace at the end of a namespace block
1702
# because that is too hard without pairing open/close braces;
1703
# however, a special exception is made for namespace closing
1704
# brackets which have a comment containing "namespace".
1706
# Also, ignore blank lines at the end of a block in a long if-else
1709
# // Something followed by a blank line
1711
# } else if (condition2) {
1714
if linenum + 1 < clean_lines.NumLines():
1715
next_line = raw[linenum + 1]
1717
and Match(r'\s*}', next_line)
1718
and next_line.find('namespace') == -1
1719
and next_line.find('} else ') == -1):
1720
error(filename, linenum, 'whitespace/blank_line', 3,
1721
'Blank line at the end of a code block. Is this needed?')
1723
# Next, we complain if there's a comment too near the text
1724
commentpos = line.find('//')
1725
if commentpos != -1:
1726
# Check if the // may be in quotes. If so, ignore it
1727
# Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1728
if (line.count('"', 0, commentpos) -
1729
line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
1730
# Allow one space for new scopes, two spaces otherwise:
1731
if (not Match(r'^\s*{ //', line) and
1732
((commentpos >= 1 and
1733
line[commentpos-1] not in string.whitespace) or
1734
(commentpos >= 2 and
1735
line[commentpos-2] not in string.whitespace))):
1736
error(filename, linenum, 'whitespace/comments', 2,
1737
'At least two spaces is best between code and comments')
1738
# There should always be a space between the // and the comment
1739
commentend = commentpos + 2
1740
if commentend < len(line) and not line[commentend] == ' ':
1741
# but some lines are exceptions -- e.g. if they're big
1742
# comment delimiters like:
1743
# //----------------------------------------------------------
1744
# or are an empty C++ style Doxygen comment, like:
1746
# or they begin with multiple slashes followed by a space:
1747
# //////// Header comment
1748
match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
1749
Search(r'^/$', line[commentend:]) or
1750
Search(r'^/+ ', line[commentend:]))
1752
error(filename, linenum, 'whitespace/comments', 4,
1753
'Should have a space between // and comment')
1754
CheckComment(line[commentpos:], filename, linenum, error)
1756
line = clean_lines.elided[linenum] # get rid of comments and strings
1758
# Don't try to do spacing checks for operator methods
1759
line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
1761
# We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
1762
# Otherwise not. Note we only check for non-spaces on *both* sides;
1763
# sometimes people put non-spaces on one side when aligning ='s among
1764
# many lines (not that this is behavior that I approve of...)
1765
if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line):
1766
error(filename, linenum, 'whitespace/operators', 4,
1767
'Missing spaces around =')
1769
# It's ok not to have spaces around binary operators like + - * /, but if
1770
# there's too little whitespace, we get concerned. It's hard to tell,
1771
# though, so we punt on this one for now. TODO.
1773
# You should always have whitespace around binary operators.
1774
# Alas, we can't test < or > because they're legitimately used sans spaces
1775
# (a->b, vector<int> a). The only time we can tell is a < with no >, and
1776
# only if it's not template params list spilling into the next line.
1777
match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
1779
# Note that while it seems that the '<[^<]*' term in the following
1780
# regexp could be simplified to '<.*', which would indeed match
1781
# the same class of strings, the [^<] means that searching for the
1782
# regexp takes linear rather than quadratic time.
1783
if not Search(r'<[^<]*,\s*$', line): # template params spill
1784
match = Search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line)
1786
error(filename, linenum, 'whitespace/operators', 3,
1787
'Missing spaces around %s' % match.group(1))
1788
# We allow no-spaces around << and >> when used like this: 10<<20, but
1789
# not otherwise (particularly, not when used as streams)
1790
match = Search(r'[^0-9\s](<<|>>)[^0-9\s]', line)
1792
error(filename, linenum, 'whitespace/operators', 3,
1793
'Missing spaces around %s' % match.group(1))
1795
# There shouldn't be space around unary operators
1796
match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
1798
error(filename, linenum, 'whitespace/operators', 4,
1799
'Extra space for operator %s' % match.group(1))
1801
# A pet peeve of mine: no spaces after an if, while, switch, or for
1802
match = Search(r' (if\(|for\(|while\(|switch\()', line)
1804
error(filename, linenum, 'whitespace/parens', 5,
1805
'Missing space before ( in %s' % match.group(1))
1807
# For if/for/while/switch, the left and right parens should be
1808
# consistent about how many spaces are inside the parens, and
1809
# there should either be zero or one spaces inside the parens.
1810
# We don't want: "if ( foo)" or "if ( foo )".
1811
# Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
1812
match = Search(r'\b(if|for|while|switch)\s*'
1813
r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
1816
if len(match.group(2)) != len(match.group(4)):
1817
if not (match.group(3) == ';' and
1818
len(match.group(2)) == 1 + len(match.group(4)) or
1819
not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
1820
error(filename, linenum, 'whitespace/parens', 5,
1821
'Mismatching spaces inside () in %s' % match.group(1))
1822
if not len(match.group(2)) in [0, 1]:
1823
error(filename, linenum, 'whitespace/parens', 5,
1824
'Should have zero or one spaces inside ( and ) in %s' %
1827
# You should always have a space after a comma (either as fn arg or operator)
1828
if Search(r',[^\s]', line):
1829
error(filename, linenum, 'whitespace/comma', 3,
1830
'Missing space after ,')
1832
# Next we will look for issues with function calls.
1833
CheckSpacingForFunctionCall(filename, line, linenum, error)
1835
# Except after an opening paren, you should have spaces before your braces.
1836
# And since you should never have braces at the beginning of a line, this is
1838
if Search(r'[^ (]{', line):
1839
error(filename, linenum, 'whitespace/braces', 5,
1840
'Missing space before {')
1842
# Make sure '} else {' has spaces.
1843
if Search(r'}else', line):
1844
error(filename, linenum, 'whitespace/braces', 5,
1845
'Missing space before else')
1847
# You shouldn't have spaces before your brackets, except maybe after
1848
# 'delete []' or 'new char * []'.
1849
if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
1850
error(filename, linenum, 'whitespace/braces', 5,
1851
'Extra space before [')
1853
# You shouldn't have a space before a semicolon at the end of the line.
1854
# There's a special case for "for" since the style guide allows space before
1855
# the semicolon there.
1856
if Search(r':\s*;\s*$', line):
1857
error(filename, linenum, 'whitespace/semicolon', 5,
1858
'Semicolon defining empty statement. Use { } instead.')
1859
elif Search(r'^\s*;\s*$', line):
1860
error(filename, linenum, 'whitespace/semicolon', 5,
1861
'Line contains only semicolon. If this should be an empty statement, '
1863
elif (Search(r'\s+;\s*$', line) and
1864
not Search(r'\bfor\b', line)):
1865
error(filename, linenum, 'whitespace/semicolon', 5,
1866
'Extra space before last semicolon. If this should be an empty '
1867
'statement, use { } instead.')
1870
def GetPreviousNonBlankLine(clean_lines, linenum):
1871
"""Return the most recent non-blank line and its line number.
1874
clean_lines: A CleansedLines instance containing the file contents.
1875
linenum: The number of the line to check.
1878
A tuple with two elements. The first element is the contents of the last
1879
non-blank line before the current line, or the empty string if this is the
1880
first non-blank line. The second is the line number of that line, or -1
1881
if this is the first non-blank line.
1884
prevlinenum = linenum - 1
1885
while prevlinenum >= 0:
1886
prevline = clean_lines.elided[prevlinenum]
1887
if not IsBlankLine(prevline): # if not a blank line...
1888
return (prevline, prevlinenum)
1893
def CheckBraces(filename, clean_lines, linenum, error):
1894
"""Looks for misplaced braces (e.g. at the end of line).
1897
filename: The name of the current file.
1898
clean_lines: A CleansedLines instance containing the file.
1899
linenum: The number of the line to check.
1900
error: The function to call with any errors found.
1903
line = clean_lines.elided[linenum] # get rid of comments and strings
1905
if Match(r'\s*{\s*$', line):
1906
# We allow an open brace to start a line in the case where someone
1907
# is using braces in a block to explicitly create a new scope,
1908
# which is commonly used to control the lifetime of
1909
# stack-allocated variables. We don't detect this perfectly: we
1910
# just don't complain if the last non-whitespace character on the
1911
# previous non-blank line is ';', ':', '{', or '}'.
1912
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
1913
if not Search(r'[;:}{]\s*$', prevline):
1914
error(filename, linenum, 'whitespace/braces', 4,
1915
'{ should almost always be at the end of the previous line')
1917
# An else clause should be on the same line as the preceding closing brace.
1918
if Match(r'\s*else\s*', line):
1919
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
1920
if Match(r'\s*}\s*$', prevline):
1921
error(filename, linenum, 'whitespace/newline', 4,
1922
'An else should appear on the same line as the preceding }')
1924
# If braces come on one side of an else, they should be on both.
1925
# However, we have to worry about "else if" that spans multiple lines!
1926
if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
1927
if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if
1928
# find the ( after the if
1929
pos = line.find('else if')
1930
pos = line.find('(', pos)
1932
(endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
1933
if endline[endpos:].find('{') == -1: # must be brace after if
1934
error(filename, linenum, 'readability/braces', 5,
1935
'If an else has a brace on one side, it should have it on both')
1936
else: # common case: else not followed by a multi-line if
1937
error(filename, linenum, 'readability/braces', 5,
1938
'If an else has a brace on one side, it should have it on both')
1940
# Likewise, an else should never have the else clause on the same line
1941
if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
1942
error(filename, linenum, 'whitespace/newline', 4,
1943
'Else clause should never be on same line as else (use 2 lines)')
1945
# In the same way, a do/while should never be on one line
1946
if Match(r'\s*do [^\s{]', line):
1947
error(filename, linenum, 'whitespace/newline', 4,
1948
'do/while clauses should not be on a single line')
1950
# Braces shouldn't be followed by a ; unless they're defining a struct
1951
# or initializing an array.
1952
# We can't tell in general, but we can for some common cases.
1953
prevlinenum = linenum
1955
(prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum)
1956
if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'):
1957
line = prevline + line
1960
if (Search(r'{.*}\s*;', line) and
1961
line.count('{') == line.count('}') and
1962
not Search(r'struct|class|enum|\s*=\s*{', line)):
1963
error(filename, linenum, 'readability/braces', 4,
1964
"You don't need a ; after a }")
1967
def ReplaceableCheck(operator, macro, line):
1968
"""Determine whether a basic CHECK can be replaced with a more specific one.
1970
For example suggest using CHECK_EQ instead of CHECK(a == b) and
1971
similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
1974
operator: The C++ operator used in the CHECK.
1975
macro: The CHECK or EXPECT macro being called.
1976
line: The current source line.
1979
True if the CHECK can be replaced with a more specific one.
1982
# This matches decimal and hex integers, strings, and chars (in that order).
1983
match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
1985
# Expression to match two sides of the operator with something that
1986
# looks like a literal, since CHECK(x == iterator) won't compile.
1987
# This means we can't catch all the cases where a more specific
1988
# CHECK is possible, but it's less annoying than dealing with
1989
# extraneous warnings.
1990
match_this = (r'\s*' + macro + r'\((\s*' +
1991
match_constant + r'\s*' + operator + r'[^<>].*|'
1992
r'.*[^<>]' + operator + r'\s*' + match_constant +
1995
# Don't complain about CHECK(x == NULL) or similar because
1996
# CHECK_EQ(x, NULL) won't compile (requires a cast).
1997
# Also, don't complain about more complex boolean expressions
1998
# involving && or || such as CHECK(a == b || c == d).
1999
return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line)
2002
def CheckCheck(filename, clean_lines, linenum, error):
2003
"""Checks the use of CHECK and EXPECT macros.
2006
filename: The name of the current file.
2007
clean_lines: A CleansedLines instance containing the file.
2008
linenum: The number of the line to check.
2009
error: The function to call with any errors found.
2012
# Decide the set of replacement macros that should be suggested
2013
raw_lines = clean_lines.raw_lines
2015
for macro in _CHECK_MACROS:
2016
if raw_lines[linenum].find(macro) >= 0:
2017
current_macro = macro
2019
if not current_macro:
2020
# Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
2023
line = clean_lines.elided[linenum] # get rid of comments and strings
2025
# Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.
2026
for operator in ['==', '!=', '>=', '>', '<=', '<']:
2027
if ReplaceableCheck(operator, current_macro, line):
2028
error(filename, linenum, 'readability/check', 2,
2029
'Consider using %s instead of %s(a %s b)' % (
2030
_CHECK_REPLACEMENT[current_macro][operator],
2031
current_macro, operator))
2035
def GetLineWidth(line):
2036
"""Determines the width of the line in column positions.
2039
line: A string, which may be a Unicode string.
2042
The width of the line in column positions, accounting for Unicode
2043
combining characters and wide characters.
2045
if isinstance(line, unicode):
2047
for c in unicodedata.normalize('NFC', line):
2048
if unicodedata.east_asian_width(c) in ('W', 'F'):
2050
elif not unicodedata.combining(c):
2057
def CheckStyle(filename, clean_lines, linenum, file_extension, error):
2058
"""Checks rules from the 'C++ style rules' section of cppguide.html.
2060
Most of these rules are hard to test (naming, comment style), but we
2061
do what we can. In particular we check for 2-space indents, line lengths,
2062
tab usage, spaces inside code, etc.
2065
filename: The name of the current file.
2066
clean_lines: A CleansedLines instance containing the file.
2067
linenum: The number of the line to check.
2068
file_extension: The extension (without the dot) of the filename.
2069
error: The function to call with any errors found.
2072
raw_lines = clean_lines.raw_lines
2073
line = raw_lines[linenum]
2075
if line.find('\t') != -1:
2076
error(filename, linenum, 'whitespace/tab', 1,
2077
'Tab found; better to use spaces')
2079
# One or three blank spaces at the beginning of the line is weird; it's
2080
# hard to reconcile that with 2-space indents.
2081
# NOTE: here are the conditions rob pike used for his tests. Mine aren't
2082
# as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
2083
# if(RLENGTH > 20) complain = 0;
2084
# if(match($0, " +(error|private|public|protected):")) complain = 0;
2085
# if(match(prev, "&& *$")) complain = 0;
2086
# if(match(prev, "\\|\\| *$")) complain = 0;
2087
# if(match(prev, "[\",=><] *$")) complain = 0;
2088
# if(match($0, " <<")) complain = 0;
2089
# if(match(prev, " +for \\(")) complain = 0;
2090
# if(prevodd && match(prevprev, " +for \\(")) complain = 0;
2092
cleansed_line = clean_lines.elided[linenum]
2093
while initial_spaces < len(line) and line[initial_spaces] == ' ':
2095
if line and line[-1].isspace():
2096
error(filename, linenum, 'whitespace/end_of_line', 4,
2097
'Line ends in whitespace. Consider deleting these extra spaces.')
2098
# There are certain situations we allow one space, notably for labels
2099
elif ((initial_spaces == 1 or initial_spaces == 3) and
2100
not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
2101
error(filename, linenum, 'whitespace/indent', 3,
2102
'Weird number of spaces at line-start. '
2103
'Are you using a 2-space indent?')
2104
# Labels should always be indented at least one space.
2105
elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
2107
error(filename, linenum, 'whitespace/labels', 4,
2108
'Labels should always be indented at least one space. '
2109
'If this is a member-initializer list in a constructor or '
2110
'the base class list in a class definition, the colon should '
2111
'be on the following line.')
2114
# Check if the line is a header guard.
2115
is_header_guard = False
2116
if file_extension == 'h':
2117
cppvar = GetHeaderGuardCPPVariable(filename)
2118
if (line.startswith('#ifndef %s' % cppvar) or
2119
line.startswith('#define %s' % cppvar) or
2120
line.startswith('#endif // %s' % cppvar)):
2121
is_header_guard = True
2122
# #include lines and header guards can be long, since there's no clean way to
2125
# URLs can be long too. It's possible to split these, but it makes them
2126
# harder to cut&paste.
2127
if (not line.startswith('#include') and not is_header_guard and
2128
not Match(r'^\s*//.*http(s?)://\S*$', line)):
2129
line_width = GetLineWidth(line)
2130
if line_width > 100:
2131
error(filename, linenum, 'whitespace/line_length', 4,
2132
'Lines should very rarely be longer than 100 characters')
2133
elif line_width > 80:
2134
error(filename, linenum, 'whitespace/line_length', 2,
2135
'Lines should be <= 80 characters long')
2137
if (cleansed_line.count(';') > 1 and
2138
# for loops are allowed two ;'s (and may run over two lines).
2139
cleansed_line.find('for') == -1 and
2140
(GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
2141
GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
2142
# It's ok to have many commands in a switch case that fits in 1 line
2143
not ((cleansed_line.find('case ') != -1 or
2144
cleansed_line.find('default:') != -1) and
2145
cleansed_line.find('break;') != -1)):
2146
error(filename, linenum, 'whitespace/newline', 4,
2147
'More than one command on the same line')
2149
# Some more style checks
2150
CheckBraces(filename, clean_lines, linenum, error)
2151
CheckSpacing(filename, clean_lines, linenum, error)
2152
CheckCheck(filename, clean_lines, linenum, error)
2155
_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.hh"')
2156
_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
2157
# Matches the first component of a filename delimited by -s and _s. That is:
2158
# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
2159
# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
2160
# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
2161
# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
2162
_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
2165
def _DropCommonSuffixes(filename):
2166
"""Drops common suffixes like _test.cc or -inl.hh from filename.
2169
>>> _DropCommonSuffixes('foo/foo-inl.hh')
2171
>>> _DropCommonSuffixes('foo/bar/foo.cc')
2173
>>> _DropCommonSuffixes('foo/foo_internal.hh')
2175
>>> _DropCommonSuffixes('foo/foo_unusualinternal.hh')
2176
'foo/foo_unusualinternal'
2179
filename: The input filename.
2182
The filename with the common suffix removed.
2184
for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
2185
'inl.hh', 'impl.hh', 'internal.hh'):
2186
if (filename.endswith(suffix) and len(filename) > len(suffix) and
2187
filename[-len(suffix) - 1] in ('-', '_')):
2188
return filename[:-len(suffix) - 1]
2189
return os.path.splitext(filename)[0]
2192
def _IsTestFilename(filename):
2193
"""Determines if the given filename has a suffix that identifies it as a test.
2196
filename: The input filename.
2199
True if 'filename' looks like a test, False otherwise.
2201
if (filename.endswith('_test.cc') or
2202
filename.endswith('_unittest.cc') or
2203
filename.endswith('_regtest.cc')):
2209
def _ClassifyInclude(fileinfo, include, is_system):
2210
"""Figures out what kind of header 'include' is.
2213
fileinfo: The current file cpplint is running over. A FileInfo instance.
2214
include: The path to a #included file.
2215
is_system: True if the #include used <> rather than "".
2218
One of the _XXX_HEADER constants.
2221
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
2223
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
2225
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.hh', False)
2227
>>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
2228
... 'bar/foo_other_ext.hh', False)
2230
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.hh', False)
2233
# This is a list of all standard c++ header files, except
2234
# those already checked for above.
2235
is_stl_h = include in _STL_HEADERS
2236
is_cpp_h = is_stl_h or include in _CPP_HEADERS
2240
return _CPP_SYS_HEADER
2242
return _C_SYS_HEADER
2244
# If the target file and the include we're checking share a
2245
# basename when we drop common extensions, and the include
2246
# lives in . , then it's likely to be owned by the target file.
2247
target_dir, target_base = (
2248
os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
2249
include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
2250
if target_base == include_base and (
2251
include_dir == target_dir or
2252
include_dir == os.path.normpath(target_dir + '/../public')):
2253
return _LIKELY_MY_HEADER
2255
# If the target and include share some initial basename
2256
# component, it's possible the target is implementing the
2257
# include, so it's allowed to be first, but we'll never
2258
# complain if it's not there.
2259
target_first_component = _RE_FIRST_COMPONENT.match(target_base)
2260
include_first_component = _RE_FIRST_COMPONENT.match(include_base)
2261
if (target_first_component and include_first_component and
2262
target_first_component.group(0) ==
2263
include_first_component.group(0)):
2264
return _POSSIBLE_MY_HEADER
2266
return _OTHER_HEADER
2270
def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
2271
"""Check rules that are applicable to #include lines.
2273
Strings on #include lines are NOT removed from elided line, to make
2274
certain tasks easier. However, to prevent false positives, checks
2275
applicable to #include lines in CheckLanguage must be put here.
2278
filename: The name of the current file.
2279
clean_lines: A CleansedLines instance containing the file.
2280
linenum: The number of the line to check.
2281
include_state: An _IncludeState instance in which the headers are inserted.
2282
error: The function to call with any errors found.
2284
fileinfo = FileInfo(filename)
2286
line = clean_lines.lines[linenum]
2288
# "include" should use the new style "foo/bar.hh" instead of just "bar.hh"
2289
if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
2290
error(filename, linenum, 'build/include', 4,
2291
'Include the directory when naming .hh files')
2293
# we shouldn't include a file more than once. actually, there are a
2294
# handful of instances where doing so is okay, but in general it's
2296
match = _RE_PATTERN_INCLUDE.search(line)
2298
include = match.group(2)
2299
is_system = (match.group(1) == '<')
2300
if include in include_state:
2301
error(filename, linenum, 'build/include', 4,
2302
'"%s" already included at %s:%s' %
2303
(include, filename, include_state[include]))
2305
include_state[include] = linenum
2307
# We want to ensure that headers appear in the right order:
2308
# 1) for foo.cc, foo.hh (preferred location)
2310
# 3) cpp system files
2311
# 4) for foo.cc, foo.hh (deprecated location)
2312
# 5) other google headers
2314
# We classify each include statement as one of those 5 types
2315
# using a number of techniques. The include_state object keeps
2316
# track of the highest type seen, and complains if we see a
2317
# lower type after that.
2318
error_message = include_state.CheckNextIncludeOrder(
2319
_ClassifyInclude(fileinfo, include, is_system))
2321
error(filename, linenum, 'build/include_order', 4,
2322
'%s. Should be: %s.hh, c system, c++ system, other.' %
2323
(error_message, fileinfo.BaseName()))
2324
if not include_state.IsInAlphabeticalOrder(include):
2325
error(filename, linenum, 'build/include_alpha', 4,
2326
'Include "%s" not in alphabetical order' % include)
2328
# Look for any of the stream classes that are part of standard C++.
2329
match = _RE_PATTERN_INCLUDE.match(line)
2331
include = match.group(2)
2332
if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
2333
# Many unit tests use cout, so we exempt them.
2334
#if not _IsTestFilename(filename):
2335
#error(filename, linenum, 'readability/streams', 3,
2336
# 'Streams are highly discouraged.')
2339
def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state,
2341
"""Checks rules from the 'C++ language rules' section of cppguide.html.
2343
Some of these rules are hard to test (function overloading, using
2344
uint32 inappropriately), but we do the best we can.
2347
filename: The name of the current file.
2348
clean_lines: A CleansedLines instance containing the file.
2349
linenum: The number of the line to check.
2350
file_extension: The extension (without the dot) of the filename.
2351
include_state: An _IncludeState instance in which the headers are inserted.
2352
error: The function to call with any errors found.
2354
# If the line is empty or consists of entirely a comment, no need to
2356
line = clean_lines.elided[linenum]
2360
match = _RE_PATTERN_INCLUDE.search(line)
2362
CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
2365
# Create an extended_line, which is the concatenation of the current and
2366
# next lines, for more effective checking of code that may span more than one
2368
if linenum + 1 < clean_lines.NumLines():
2369
extended_line = line + clean_lines.elided[linenum + 1]
2371
extended_line = line
2373
# Make Windows paths like Unix.
2374
fullname = os.path.abspath(filename).replace('\\', '/')
2376
# TODO(unknown): figure out if they're using default arguments in fn proto.
2378
# Check for non-const references in functions. This is tricky because &
2379
# is also used to take the address of something. We allow <> for templates,
2380
# (ignoring whatever is between the braces) and : for classes.
2381
# These are complicated re's. They try to capture the following:
2382
# paren (for fn-prototype start), typename, &, varname. For the const
2383
# version, we're willing for const to be before typename or after
2384
# Don't check the implemention on same line.
2385
fnline = line.split('{', 1)[0]
2386
if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) >
2387
len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?'
2388
r'(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) +
2389
len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+\s+const(\s?&|&\s?)[\w]+',
2392
# We allow non-const references in a few standard places, like functions
2393
# called "swap()" or iostream operators like "<<" or ">>".
2395
r'(swap|Swap|operator[<>][<>])\s*\(\s*(?:[\w:]|<.*>)+\s*&',
2397
error(filename, linenum, 'runtime/references', 2,
2398
'Is this a non-const reference? '
2399
'If so, make const or use a pointer.')
2401
# Check to see if they're using an conversion function cast.
2402
# I just try to capture the most common basic types, though there are more.
2403
# Parameterless conversion functions, such as bool(), are allowed as they are
2404
# probably a member operator declaration or default constructor.
2406
r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there
2407
r'(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
2409
# gMock methods are defined using some variant of MOCK_METHODx(name, type)
2410
# where type may be float(), int(string), etc. Without context they are
2411
# virtually indistinguishable from int(x) casts.
2412
if (match.group(1) is None and # If new operator, then this isn't a cast
2413
not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line)):
2414
error(filename, linenum, 'readability/casting', 4,
2415
'Using deprecated casting style. '
2416
'Use static_cast<%s>(...) instead' %
2419
CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2421
r'\((int|float|double|bool|char|u?int(16|32|64))\)',
2423
# This doesn't catch all cases. Consider (const char * const)"hello".
2424
CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2425
'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
2427
# In addition, we look for people taking the address of a cast. This
2428
# is dangerous -- casts can assign to temporaries, so the pointer doesn't
2429
# point where you think.
2431
r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
2432
error(filename, linenum, 'runtime/casting', 4,
2433
('Are you taking an address of a cast? '
2434
'This is dangerous: could be a temp var. '
2435
'Take the address before doing the cast, rather than after'))
2437
# Check for people declaring static/global STL strings at the top level.
2438
# This is dangerous because the C++ language does not guarantee that
2439
# globals with constructors are initialized before the first access.
2441
r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
2443
# Make sure it's not a function.
2444
# Function template specialization looks like: "string foo<Type>(...".
2445
# Class template definitions look like: "string Foo<Type>::Method(...".
2446
if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)',
2448
error(filename, linenum, 'runtime/string', 4,
2449
'For a static/global string constant, use a C style string instead: '
2451
(match.group(1), match.group(2)))
2453
# Check that we're not using RTTI outside of testing code.
2454
if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename):
2455
error(filename, linenum, 'runtime/rtti', 5,
2456
'Do not use dynamic_cast<>. If you need to cast within a class '
2457
"hierarchy, use static_cast<> to upcast. Google doesn't support "
2460
if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
2461
error(filename, linenum, 'runtime/init', 4,
2462
'You seem to be initializing a member variable with itself.')
2464
if file_extension == 'h':
2465
# TODO(unknown): check that 1-arg constructors are explicit.
2466
# How to tell it's a constructor?
2467
# (handled in CheckForNonStandardConstructs for now)
2468
# TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
2472
# Check if people are using the verboten C basic types. The only exception
2473
# we regularly allow is "unsigned short port" for port.
2474
if Search(r'\bshort port\b', line):
2475
if not Search(r'\bunsigned short port\b', line):
2476
error(filename, linenum, 'runtime/int', 4,
2477
'Use "unsigned short" for ports, not "short"')
2479
match = Search(r'\b(short|long(?! +double)|long long)\b', line)
2481
error(filename, linenum, 'runtime/int', 4,
2482
'Use int16/int64/etc, rather than the C type %s' % match.group(1))
2484
# When snprintf is used, the second argument shouldn't be a literal.
2485
match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
2486
if match and match.group(2) != '0':
2487
# If 2nd arg is zero, snprintf is used to calculate size.
2488
error(filename, linenum, 'runtime/printf', 3,
2489
'If you can, use sizeof(%s) instead of %s as the 2nd arg '
2490
'to snprintf.' % (match.group(1), match.group(2)))
2492
# Check if some verboten C functions are being used.
2493
if Search(r'\bsprintf\b', line):
2494
error(filename, linenum, 'runtime/printf', 5,
2495
'Never use sprintf. Use snprintf instead.')
2496
match = Search(r'\b(strcpy|strcat)\b', line)
2498
error(filename, linenum, 'runtime/printf', 4,
2499
'Almost always, snprintf is better than %s' % match.group(1))
2501
if Search(r'\bsscanf\b', line):
2502
error(filename, linenum, 'runtime/printf', 1,
2503
'sscanf can be ok, but is slow and can overflow buffers.')
2505
# Check if some verboten operator overloading is going on
2506
# TODO(unknown): catch out-of-line unary operator&:
2508
# int operator&(const X& x) { return 42; } // unary operator&
2509
# The trick is it's hard to tell apart from binary operator&:
2510
# class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
2511
if Search(r'\boperator\s*&\s*\(\s*\)', line):
2512
error(filename, linenum, 'runtime/operator', 4,
2513
'Unary operator& is dangerous. Do not use it.')
2515
# Check for suspicious usage of "if" like
2517
if Search(r'\}\s*if\s*\(', line):
2518
error(filename, linenum, 'readability/braces', 4,
2519
'Did you mean "else if"? If not, start a new line for "if".')
2521
# Check for potential format string bugs like printf(foo).
2522
# We constrain the pattern not to pick things like DocidForPrintf(foo).
2523
# Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
2524
match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I)
2526
error(filename, linenum, 'runtime/printf', 4,
2527
'Potential format string bug. Do %s("%%s", %s) instead.'
2528
% (match.group(1), match.group(2)))
2530
# Check for potential memset bugs like memset(buf, sizeof(buf), 0).
2531
match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
2532
if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
2533
error(filename, linenum, 'runtime/memset', 4,
2534
'Did you mean "memset(%s, 0, %s)"?'
2535
% (match.group(1), match.group(2)))
2537
if Search(r'\busing namespace\b', line):
2538
error(filename, linenum, 'build/namespaces', 5,
2539
'Do not use namespace using-directives. '
2540
'Use using-declarations instead.')
2542
# Detect variable-length arrays.
2543
match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
2544
if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
2545
match.group(3).find(']') == -1):
2546
# Split the size using space and arithmetic operators as delimiters.
2547
# If any of the resulting tokens are not compile time constants then
2549
tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
2557
if Search(r'sizeof\(.+\)', tok): continue
2558
if Search(r'arraysize\(\w+\)', tok): continue
2560
tok = tok.lstrip('(')
2561
tok = tok.rstrip(')')
2562
if not tok: continue
2563
if Match(r'\d+', tok): continue
2564
if Match(r'0[xX][0-9a-fA-F]+', tok): continue
2565
if Match(r'k[A-Z0-9]\w*', tok): continue
2566
if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
2567
if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
2568
# A catch all for tricky sizeof cases, including 'sizeof expression',
2569
# 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
2570
# requires skipping the next token becasue we split on ' ' and '*'.
2571
if tok.startswith('sizeof'):
2577
error(filename, linenum, 'runtime/arrays', 1,
2578
'Do not use variable-length arrays. Use an appropriately named '
2579
"('k' followed by CamelCase) compile-time constant for the size.")
2581
# If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or
2582
# DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing
2583
# in the class declaration.
2586
r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'
2589
if match and linenum + 1 < clean_lines.NumLines():
2590
next_line = clean_lines.elided[linenum + 1]
2591
if not Search(r'^\s*};', next_line):
2592
error(filename, linenum, 'readability/constructors', 3,
2593
match.group(1) + ' should be the last thing in the class')
2595
# Check for use of unnamed namespaces in header files. Registration
2596
# macros are typically OK, so we allow use of "namespace {" on lines
2597
# that end with backslashes.
2598
if (file_extension == 'h'
2599
and Search(r'\bnamespace\s*{', line)
2600
and line[-1] != '\\'):
2601
error(filename, linenum, 'build/namespaces', 4,
2602
'Do not use unnamed namespaces in header files. See '
2603
'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2604
' for more information.')
2607
def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
2609
"""Checks for a C-style cast by looking for the pattern.
2611
This also handles sizeof(type) warnings, due to similarity of content.
2614
filename: The name of the current file.
2615
linenum: The number of the line to check.
2616
line: The line of code to check.
2617
raw_line: The raw line of code to check, with comments.
2618
cast_type: The string for the C++ cast to recommend. This is either
2619
reinterpret_cast or static_cast, depending.
2620
pattern: The regular expression used to find C-style casts.
2621
error: The function to call with any errors found.
2623
match = Search(pattern, line)
2628
sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
2630
error(filename, linenum, 'runtime/sizeof', 1,
2631
'Using sizeof(type). Use sizeof(varname) instead if possible')
2634
remainder = line[match.end(0):]
2636
# The close paren is for function pointers as arguments to a function.
2637
# eg, void foo(void (*bar)(int));
2638
# The semicolon check is a more basic function check; also possibly a
2639
# function pointer typedef.
2640
# eg, void foo(int); or void foo(int) const;
2641
# The equals check is for function pointer assignment.
2642
# eg, void *(*foo)(int) = ...
2644
# Right now, this will only catch cases where there's a single argument, and
2645
# it's unnamed. It should probably be expanded to check for multiple
2646
# arguments with some unnamed.
2647
function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder)
2649
if (not function_match.group(3) or
2650
function_match.group(3) == ';' or
2651
raw_line.find('/*') < 0):
2652
error(filename, linenum, 'readability/function', 3,
2653
'All parameters should be named in a function')
2656
# At this point, all that should be left is actual casts.
2657
error(filename, linenum, 'readability/casting', 4,
2658
'Using C-style cast. Use %s<%s>(...) instead' %
2659
(cast_type, match.group(1)))
2662
_HEADERS_CONTAINING_TEMPLATES = (
2663
('<deque>', ('deque',)),
2664
('<functional>', ('unary_function', 'binary_function',
2665
'plus', 'minus', 'multiplies', 'divides', 'modulus',
2667
'equal_to', 'not_equal_to', 'greater', 'less',
2668
'greater_equal', 'less_equal',
2669
'logical_and', 'logical_or', 'logical_not',
2670
'unary_negate', 'not1', 'binary_negate', 'not2',
2671
'bind1st', 'bind2nd',
2672
'pointer_to_unary_function',
2673
'pointer_to_binary_function',
2675
'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
2677
'const_mem_fun_t', 'const_mem_fun1_t',
2678
'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
2681
('<limits>', ('numeric_limits',)),
2682
('<list>', ('list',)),
2683
('<map>', ('map', 'multimap',)),
2684
('<memory>', ('allocator',)),
2685
('<queue>', ('queue', 'priority_queue',)),
2686
('<set>', ('set', 'multiset',)),
2687
('<stack>', ('stack',)),
2688
('<string>', ('char_traits', 'basic_string',)),
2689
('<utility>', ('pair',)),
2690
('<vector>', ('vector',)),
2693
# Note: std::hash is their hash, ::hash is our hash
2694
('<hash_map>', ('hash_map', 'hash_multimap',)),
2695
('<hash_set>', ('hash_set', 'hash_multiset',)),
2696
('<slist>', ('slist',)),
2699
_HEADERS_ACCEPTED_BUT_NOT_PROMOTED = {
2700
# We can trust with reasonable confidence that map gives us pair<>, too.
2701
'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap')
2704
_RE_PATTERN_STRING = re.compile(r'\bstring\b')
2706
_re_pattern_algorithm_header = []
2707
for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
2709
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
2711
_re_pattern_algorithm_header.append(
2712
(re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
2716
_re_pattern_templates = []
2717
for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
2718
for _template in _templates:
2719
_re_pattern_templates.append(
2720
(re.compile(r'(\<|\b)' + _template + r'\s*\<'),
2725
def FilesBelongToSameModule(filename_cc, filename_h):
2726
"""Check if these two filenames belong to the same module.
2728
The concept of a 'module' here is a as follows:
2729
foo.hh, foo-inl.hh, foo.cc, foo_test.cc and foo_unittest.cc belong to the
2730
same 'module' if they are in the same directory.
2731
some/path/public/xyzzy and some/path/internal/xyzzy are also considered
2732
to belong to the same module here.
2734
If the filename_cc contains a longer path than the filename_h, for example,
2735
'/absolute/path/to/base/sysinfo.cc', and this file would include
2736
'base/sysinfo.hh', this function also produces the prefix needed to open the
2737
header. This is used by the caller of this function to more robustly open the
2738
header file. We don't have access to the real include paths in this context,
2739
so we need this guesswork here.
2741
Known bugs: tools/base/bar.cc and base/bar.hh belong to the same module
2742
according to this implementation. Because of this, this function gives
2743
some false positives. This should be sufficiently rare in practice.
2746
filename_cc: is the path for the .cc file
2747
filename_h: is the path for the header path
2750
Tuple with a bool and a string:
2751
bool: True if filename_cc and filename_h belong to the same module.
2752
string: the additional prefix needed to open the header file.
2755
if not filename_cc.endswith('.cc'):
2757
filename_cc = filename_cc[:-len('.cc')]
2758
if filename_cc.endswith('_unittest'):
2759
filename_cc = filename_cc[:-len('_unittest')]
2760
elif filename_cc.endswith('_test'):
2761
filename_cc = filename_cc[:-len('_test')]
2762
filename_cc = filename_cc.replace('/public/', '/')
2763
filename_cc = filename_cc.replace('/internal/', '/')
2765
if not filename_h.endswith('.hh'):
2767
filename_h = filename_h[:-len('.hh')]
2768
if filename_h.endswith('-inl'):
2769
filename_h = filename_h[:-len('-inl')]
2770
filename_h = filename_h.replace('/public/', '/')
2771
filename_h = filename_h.replace('/internal/', '/')
2773
files_belong_to_same_module = filename_cc.endswith(filename_h)
2775
if files_belong_to_same_module:
2776
common_path = filename_cc[:-len(filename_h)]
2777
return files_belong_to_same_module, common_path
2780
def UpdateIncludeState(filename, include_state, io=codecs):
2781
"""Fill up the include_state with new includes found from the file.
2784
filename: the name of the header to read.
2785
include_state: an _IncludeState instance in which the headers are inserted.
2786
io: The io factory to use to read the file. Provided for testability.
2789
True if a header was succesfully added. False otherwise.
2793
headerfile = io.open(filename, 'r', 'utf8', 'replace')
2797
for line in headerfile:
2799
clean_line = CleanseComments(line)
2800
match = _RE_PATTERN_INCLUDE.search(clean_line)
2802
include = match.group(2)
2803
# The value formatting is cute, but not really used right now.
2804
# What matters here is that the key is in include_state.
2805
include_state.setdefault(include, '%s:%d' % (filename, linenum))
2809
def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
2811
"""Reports for missing stl includes.
2813
This function will output warnings to make sure you are including the headers
2814
necessary for the stl containers and functions that you use. We only give one
2815
reason to include a header. For example, if you use both equal_to<> and
2816
less<> in a .hh file, only one (the latter in the file) of these will be
2817
reported as a reason to include the <functional>.
2820
filename: The name of the current file.
2821
clean_lines: A CleansedLines instance containing the file.
2822
include_state: An _IncludeState instance.
2823
error: The function to call with any errors found.
2824
io: The IO factory to use to read the header file. Provided for unittest
2827
required = {} # A map of header name to linenumber and the template entity.
2828
# Example of required: { '<functional>': (1219, 'less<>') }
2830
for linenum in xrange(clean_lines.NumLines()):
2831
line = clean_lines.elided[linenum]
2832
if not line or line[0] == '#':
2835
# String is special -- it is a non-templatized type in STL.
2836
m = _RE_PATTERN_STRING.search(line)
2838
# Don't warn about strings in non-STL namespaces:
2839
# (We check only the first match per line; good enough.)
2840
prefix = line[:m.start()]
2841
if prefix.endswith('std::') or not prefix.endswith('::'):
2842
required['<string>'] = (linenum, 'string')
2844
for pattern, template, header in _re_pattern_algorithm_header:
2845
if pattern.search(line):
2846
required[header] = (linenum, template)
2848
# The following function is just a speed up, no semantics are changed.
2849
if not '<' in line: # Reduces the cpu time usage by skipping lines.
2852
for pattern, template, header in _re_pattern_templates:
2853
if pattern.search(line):
2854
required[header] = (linenum, template)
2856
# The policy is that if you #include something in foo.hh you don't need to
2857
# include it again in foo.cc. Here, we will look at possible includes.
2858
# Let's copy the include_state so it is only messed up within this function.
2859
include_state = include_state.copy()
2861
# Did we find the header for this file (if any) and succesfully load it?
2862
header_found = False
2864
# Use the absolute path so that matching works properly.
2865
abs_filename = os.path.abspath(filename)
2867
# For Emacs's flymake.
2868
# If cpplint is invoked from Emacs's flymake, a temporary file is generated
2869
# by flymake and that file name might end with '_flymake.cc'. In that case,
2870
# restore original file name here so that the corresponding header file can be
2872
# e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.hh'
2873
# instead of 'foo_flymake.hh'
2874
abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename)
2876
# include_state is modified during iteration, so we iterate over a copy of
2878
for header in include_state.keys(): #NOLINT
2879
(same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
2880
fullpath = common_path + header
2881
if same_module and UpdateIncludeState(fullpath, include_state, io):
2884
# If we can't find the header file for a .cc, assume it's because we don't
2885
# know where to look. In that case we'll give up as we're not sure they
2886
# didn't include it in the .hh file.
2887
# TODO(unknown): Do a better job of finding .hh files so we are confident that
2888
# not having the .hh file means there isn't one.
2889
if filename.endswith('.cc') and not header_found:
2892
# All the lines have been processed, report the errors found.
2893
for required_header_unstripped in required:
2894
template = required[required_header_unstripped][1]
2895
if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED:
2896
headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template]
2897
if [True for header in headers if header in include_state]:
2899
if required_header_unstripped.strip('<>"') not in include_state:
2900
error(filename, required[required_header_unstripped][0],
2901
'build/include_what_you_use', 4,
2902
'Add #include ' + required_header_unstripped + ' for ' + template)
2905
def ProcessLine(filename, file_extension,
2906
clean_lines, line, include_state, function_state,
2907
class_state, error):
2908
"""Processes a single line in the file.
2911
filename: Filename of the file that is being processed.
2912
file_extension: The extension (dot not included) of the file.
2913
clean_lines: An array of strings, each representing a line of the file,
2914
with comments stripped.
2915
line: Number of line being processed.
2916
include_state: An _IncludeState instance in which the headers are inserted.
2917
function_state: A _FunctionState instance which counts function lines, etc.
2918
class_state: A _ClassState instance which maintains information about
2919
the current stack of nested class declarations being parsed.
2920
error: A callable to which errors are reported, which takes 4 arguments:
2921
filename, line number, error level, and message
2924
raw_lines = clean_lines.raw_lines
2925
ParseNolintSuppressions(filename, raw_lines[line], line, error)
2926
CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
2927
CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
2928
CheckStyle(filename, clean_lines, line, file_extension, error)
2929
CheckLanguage(filename, clean_lines, line, file_extension, include_state,
2931
CheckForNonStandardConstructs(filename, clean_lines, line,
2933
CheckPosixThreading(filename, clean_lines, line, error)
2934
CheckInvalidIncrement(filename, clean_lines, line, error)
2937
def ProcessFileData(filename, file_extension, lines, error):
2938
"""Performs lint checks and reports any errors to the given error function.
2941
filename: Filename of the file that is being processed.
2942
file_extension: The extension (dot not included) of the file.
2943
lines: An array of strings, each representing a line of the file, with the
2944
last element being empty if the file is termined with a newline.
2945
error: A callable to which errors are reported, which takes 4 arguments:
2947
lines = (['// marker so line numbers and indices both start at 1'] + lines +
2948
['// marker so line numbers end in a known way'])
2950
include_state = _IncludeState()
2951
function_state = _FunctionState()
2952
class_state = _ClassState()
2954
ResetNolintSuppressions()
2956
CheckForCopyright(filename, lines, error)
2958
if file_extension == 'h':
2959
CheckForHeaderGuard(filename, lines, error)
2961
RemoveMultiLineComments(filename, lines, error)
2962
clean_lines = CleansedLines(lines)
2963
for line in xrange(clean_lines.NumLines()):
2964
ProcessLine(filename, file_extension, clean_lines, line,
2965
include_state, function_state, class_state, error)
2966
class_state.CheckFinished(filename, error)
2968
CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
2970
# We check here rather than inside ProcessLine so that we see raw
2971
# lines rather than "cleaned" lines.
2972
CheckForUnicodeReplacementCharacters(filename, lines, error)
2974
CheckForNewlineAtEOF(filename, lines, error)
2976
def ProcessFile(filename, vlevel):
2977
"""Does google-lint on a single file.
2980
filename: The name of the file to parse.
2982
vlevel: The level of errors to report. Every error of confidence
2983
>= verbose_level will be reported. 0 is a good default.
2986
_SetVerboseLevel(vlevel)
2989
# Support the UNIX convention of using "-" for stdin. Note that
2990
# we are not opening the file with universal newline support
2991
# (which codecs doesn't support anyway), so the resulting lines do
2992
# contain trailing '\r' characters if we are reading a file that
2994
# If after the split a trailing '\r' is present, it is removed
2995
# below. If it is not expected to be present (i.e. os.linesep !=
2996
# '\r\n' as in Windows), a warning is issued below if this file
3000
lines = codecs.StreamReaderWriter(sys.stdin,
3001
codecs.getreader('utf8'),
3002
codecs.getwriter('utf8'),
3003
'replace').read().split('\n')
3005
lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
3007
carriage_return_found = False
3008
# Remove trailing '\r'.
3009
for linenum in range(len(lines)):
3010
if lines[linenum].endswith('\r'):
3011
lines[linenum] = lines[linenum].rstrip('\r')
3012
carriage_return_found = True
3015
_cpplint_state.output_handle.write(
3016
"Skipping input '%s': Can't open for reading\n" % filename)
3019
# Note, if no dot is found, this will give the entire filename as the ext.
3020
file_extension = filename[filename.rfind('.') + 1:]
3022
# When reading from stdin, the extension is unknown, so no cpplint tests
3023
# should rely on the extension.
3024
if (filename != '-' and file_extension != 'cc' and file_extension != 'hh'
3025
and file_extension != 'cpp'):
3026
_cpplint_state.output_handle.write('Ignoring %s; not a .cc or .hh file\n' % filename)
3028
ProcessFileData(filename, file_extension, lines, Error)
3029
if carriage_return_found and os.linesep != '\r\n':
3030
# Use 0 for linenum since outputing only one error for potentially
3032
Error(filename, 0, 'whitespace/newline', 1,
3033
'One or more unexpected \\r (^M) found;'
3034
'better to use only a \\n')
3036
_cpplint_state.output_handle.write('Done processing %s\n' % filename)
3039
def PrintUsage(message):
3040
"""Prints a brief usage string and exits, optionally with an error message.
3043
message: The optional error message.
3045
_cpplint_state.output_handle.write(_USAGE)
3047
sys.exit('\nFATAL ERROR: ' + message)
3052
def PrintCategories():
3053
"""Prints a list of all the error-categories used by error messages.
3055
These are the categories used to filter messages via --filter.
3057
_cpplint_state.output_handle.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES))
3061
def ParseArguments(args):
3062
"""Parses the command line arguments.
3064
This may set the output format and verbosity level as side-effects.
3067
args: The command line arguments:
3070
The list of filenames to lint.
3073
(opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
3076
except getopt.GetoptError:
3077
PrintUsage('Invalid arguments.')
3079
verbosity = _VerboseLevel()
3080
output_format = _OutputFormat()
3084
for (opt, val) in opts:
3087
elif opt == '--output':
3088
if not val in ('emacs', 'vs7'):
3089
PrintUsage('The only allowed output formats are emacs and vs7.')
3091
elif opt == '--verbose':
3092
verbosity = int(val)
3093
elif opt == '--filter':
3097
elif opt == '--counting':
3098
if val not in ('total', 'toplevel', 'detailed'):
3099
PrintUsage('Valid counting options are total, toplevel, and detailed')
3100
counting_style = val
3103
PrintUsage('No files were specified.')
3105
_SetOutputFormat(output_format)
3106
_SetVerboseLevel(verbosity)
3107
_SetFilters(filters)
3108
_SetCountingStyle(counting_style)
3114
filenames = ParseArguments(sys.argv[1:])
3116
# Change stderr to write with replacement characters so we don't die
3117
# if we try to print something containing non-ASCII characters.
3118
_cpplint_state.output_handle = codecs.StreamReaderWriter(_cpplint_state.output_handle,
3119
codecs.getreader('utf8'),
3120
codecs.getwriter('utf8'),
3123
_cpplint_state.ResetErrorCounts()
3124
for filename in filenames:
3125
ProcessFile(filename, _cpplint_state.verbose_level)
3126
_cpplint_state.PrintErrorCounts()
3128
sys.exit(_cpplint_state.error_count > 0)
3131
if __name__ == '__main__':