3
# cpplint.py is Copyright (C) 2009 Google Inc.
5
# It is free software; you can redistribute it and/or modify it under the
8
# a) the GNU General Public License as published by the Free Software
9
# Foundation; either version 1, or (at your option) any later version, or
11
# b) the "Artistic License".
13
# Modified for Drizzle by Monty Taylor & Robert Collins
15
# Here are some issues that I've had people identify in my code during reviews,
16
# that I think are possible to flag automatically in a lint tool. If these were
17
# caught by lint, it would save time both for myself and that of my reviewers.
18
# Most likely, some of these are beyond the scope of the current lint framework,
19
# but I think it is valuable to retain these wish-list items even if they cannot
20
# be immediately implemented.
24
# - Check for no 'explicit' for multi-arg ctor
25
# - Check for boolean assign RHS in parens
26
# - Check for ctor initializer-list colon position and spacing
27
# - Check that if there's a ctor, there should be a dtor
28
# - Check accessors that return non-pointer member variables are
30
# - Check accessors that return non-const pointer member vars are
31
# *not* declared const
32
# - Check for using public includes for testing
33
# - Check for spaces between brackets in one-line inline method
34
# - Check for no assert()
35
# - Check for spaces surrounding operators
36
# - Check for 0 in pointer context (should be NULL)
37
# - Check for 0 in char context (should be '\0')
38
# - Check for camel-case method name conventions for methods
39
# that are not simple inline getters and setters
40
# - Check that base classes have virtual destructors
41
# put " // namespace" after } that closes a namespace, with
42
# namespace's name after 'namespace' if it is named.
43
# - Do not indent namespace contents
44
# - Avoid inlining non-trivial constructors in header files
45
# include base/basictypes.h if DISALLOW_EVIL_CONSTRUCTORS is used
46
# - Check for old-school (void) cast for call-sites of functions
47
# ignored return value
48
# - Check gUnit usage of anonymous namespace
49
# - Check for class declaration order (typedefs, consts, enums,
50
# ctor(s?), dtor, friend declarations, methods, member vars)
53
"""Does google-lint on c++ files.
55
The goal of this script is to identify places in the code that *may*
56
be in non-compliance with google style. It does not attempt to fix
57
up these problems -- the point is to educate. It does also not
58
attempt to find all problems, or to ensure that everything it does
59
find is legitimately a problem.
61
In particular, we can get very confused by /* and // inside strings!
62
We do a small hack, which is to ignore //'s with "'s after them on the
63
same line, but it is far from perfect (in either direction).
78
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--deps=path] [--filter=-x,+y,...]
81
The style guidelines this tries to follow are those in
82
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
84
Every problem is given a confidence score from 1-5, with 5 meaning we are
85
certain of the problem, and 1 meaning it could be a legitimate construct.
86
This will miss some errors, and is not a substitute for a code review.
88
To prevent specific lines from being linted, add a '// NOLINT' comment to the
91
The files passed in will be linted; at least one file must be provided.
92
Linted extensions are .cc, .cpp, and .h. Other file types will be ignored.
97
By default, the output is formatted to ease emacs parsing. Visual Studio
98
compatible output (vs7) may also be used. Other formats are unsupported.
101
Specify a number 0-5 to restrict errors to certain verbosity levels.
104
write out a Makefile that can be included listing the files included
105
during the lint process as make style dependencies with null-build rules
106
(so that deleted headers will not cause failures). This can be useful to
107
perform on-demand linting. The top level target will be the name of the
111
Specify a comma-separated list of category-filters to apply: only
112
error messages whose category names pass the filters will be printed.
113
(Category names are printed with the message and look like
114
"[whitespace/indent]".) Filters are evaluated left to right.
115
"-FOO" and "FOO" means "do not print categories that start with FOO".
116
"+FOO" means "do print categories that start with FOO".
118
Examples: --filter=-whitespace,+whitespace/braces
119
--filter=whitespace,runtime/printf,+runtime/printf_format
120
--filter=-,+build/include_what_you_use
122
To see a list of all the categories used in cpplint, pass no arg:
126
# We categorize each error message we print. Here are the categories.
127
# We want an explicit list so we can list them all in cpplint --filter=.
128
# If you add a new error message with a new category, add it to the list
129
# here! cpplint_unittest.py should tell you if you forget to do this.
130
# \ used for clearer layout -- pylint: disable-msg=C6013
131
_ERROR_CATEGORIES = '''\
140
build/include_what_you_use
148
readability/constructors
151
readability/multiline_comment
152
readability/multiline_string
161
runtime/invalid_increment
164
runtime/printf_format
169
runtime/threadsafe_fn
171
whitespace/blank_line
175
whitespace/end_of_line
176
whitespace/ending_newline
179
whitespace/line_length
188
# The default state of the category filter. This is overrided by the --filter=
189
# flag. By default all errors are on, so only add here categories that should be
190
# off by default (i.e., categories that must be enabled by the --filter= flags).
191
# All entries here should start with a '-' or '+', as in the --filter= flag.
192
_DEFAULT_FILTERS = []
194
# We used to check for high-bit characters, but after much discussion we
195
# decided those were OK, as long as they were in UTF-8 and didn't represent
196
# hard-coded international strings, which belong in a seperate i18n file.
198
# Headers that we consider STL headers.
199
_STL_HEADERS = frozenset([
200
'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
201
'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
202
'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h',
203
'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
204
'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
205
'utility', 'vector', 'vector.h',
209
# Non-STL C++ system headers.
210
_CPP_HEADERS = frozenset([
211
'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
212
'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
213
'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
214
'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
215
'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
216
'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
217
'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h',
218
'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
219
'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h',
220
'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h',
221
'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
222
'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
223
'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
227
# Assertion macros. These are defined in base/logging.h and
228
# testing/base/gunit.h. Note that the _M versions need to come first
229
# for substring matching to work.
232
'EXPECT_TRUE_M', 'EXPECT_TRUE',
233
'ASSERT_TRUE_M', 'ASSERT_TRUE',
234
'EXPECT_FALSE_M', 'EXPECT_FALSE',
235
'ASSERT_FALSE_M', 'ASSERT_FALSE',
238
# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
239
_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
241
for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
242
('>=', 'GE'), ('>', 'GT'),
243
('<=', 'LE'), ('<', 'LT')]:
244
_CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
245
_CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
246
_CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
247
_CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
248
_CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
249
_CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
251
for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
252
('>=', 'LT'), ('>', 'LE'),
253
('<=', 'GT'), ('<', 'GE')]:
254
_CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
255
_CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
256
_CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
257
_CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
260
# These constants define types of headers for use with
261
# _IncludeState.CheckNextIncludeOrder().
264
_LIKELY_MY_HEADER = 3
265
_POSSIBLE_MY_HEADER = 4
269
_regexp_compile_cache = {}
272
def Match(pattern, s):
273
"""Matches the string with the pattern, caching the compiled regexp."""
274
# The regexp compilation caching is inlined in both Match and Search for
275
# performance reasons; factoring it out into a separate function turns out
276
# to be noticeably expensive.
277
if not pattern in _regexp_compile_cache:
278
_regexp_compile_cache[pattern] = sre_compile.compile(pattern)
279
return _regexp_compile_cache[pattern].match(s)
282
def Search(pattern, s):
283
"""Searches the string for the pattern, caching the compiled regexp."""
284
if not pattern in _regexp_compile_cache:
285
_regexp_compile_cache[pattern] = sre_compile.compile(pattern)
286
return _regexp_compile_cache[pattern].search(s)
289
class _IncludeState(dict):
290
"""Tracks line numbers for includes, and the order in which includes appear.
292
As a dict, an _IncludeState object serves as a mapping between include
293
filename and line number on which that file was included.
295
Call CheckNextIncludeOrder() once for each header in the file, passing
296
in the type constants defined above. Calls in an illegal order will
297
raise an _IncludeError with an appropriate error message.
300
# self._section will move monotonically through this set. If it ever
301
# needs to move backwards, CheckNextIncludeOrder will raise an error.
309
_C_SYS_HEADER: 'C system header',
310
_CPP_SYS_HEADER: 'C++ system header',
311
_LIKELY_MY_HEADER: 'header this file implements',
312
_POSSIBLE_MY_HEADER: 'header this file may implement',
313
_OTHER_HEADER: 'other header',
316
_INITIAL_SECTION: "... nothing. (This can't be an error.)",
317
_MY_H_SECTION: 'a header this file implements',
318
_C_SECTION: 'C system header',
319
_CPP_SECTION: 'C++ system header',
320
_OTHER_H_SECTION: 'other header',
325
self._section = self._INITIAL_SECTION
327
def CheckNextIncludeOrder(self, header_type):
328
"""Returns a non-empty error message if the next header is out of order.
330
This function also updates the internal state to be ready to check
334
header_type: One of the _XXX_HEADER constants defined above.
337
The empty string if the header is in the right order, or an
338
error message describing what's wrong.
341
error_message = ('Found %s after %s' %
342
(self._TYPE_NAMES[header_type],
343
self._SECTION_NAMES[self._section]))
345
if header_type == _C_SYS_HEADER:
346
if self._section <= self._C_SECTION:
347
self._section = self._C_SECTION
350
elif header_type == _CPP_SYS_HEADER:
351
if self._section <= self._CPP_SECTION:
352
self._section = self._CPP_SECTION
355
elif header_type == _LIKELY_MY_HEADER:
356
if self._section <= self._MY_H_SECTION:
357
self._section = self._MY_H_SECTION
359
self._section = self._OTHER_H_SECTION
360
elif header_type == _POSSIBLE_MY_HEADER:
361
if self._section <= self._MY_H_SECTION:
362
self._section = self._MY_H_SECTION
364
# This will always be the fallback because we're not sure
365
# enough that the header is associated with this file.
366
self._section = self._OTHER_H_SECTION
368
assert header_type == _OTHER_HEADER
369
self._section = self._OTHER_H_SECTION
374
class _CppLintState(object):
375
"""Maintains module-wide state.."""
378
self.verbose_level = 1 # global setting.
379
self.error_count = 0 # global count of reported errors
380
# filters to apply when emitting error messages
381
self.filters = _DEFAULT_FILTERS[:]
384
# "emacs" - format that emacs can parse (default)
385
# "vs7" - format that Microsoft Visual Studio 7 can parse
386
self.output_format = 'emacs'
389
self.depfilename = None
390
self.seen_fnames = set()
393
"""Complete things that wait for the end of the lint operation."""
394
if self.depfilename is not None:
396
# Don't alter dependency data
398
depfile = file(self.depfilename, 'w+')
399
# depend on what we read
400
depfile.write("%s: " % self.depfilename)
401
names = sorted(self.seen_fnames)
402
depfile.write(' '.join(names))
404
# anything we read shouldn't cause an error if its missing - so claim
407
depfile.write('%s:\n' % name)
410
def seen_file(self, fname):
411
self.seen_fnames.add(fname)
413
def SetOutputFormat(self, output_format):
414
"""Sets the output format for errors."""
415
self.output_format = output_format
417
def SetVerboseLevel(self, level):
418
"""Sets the module's verbosity, and returns the previous setting."""
419
last_verbose_level = self.verbose_level
420
self.verbose_level = level
421
return last_verbose_level
423
def SetFilters(self, filters):
424
"""Sets the error-message filters.
426
These filters are applied when deciding whether to emit a given
430
filters: A string of comma-separated filters (eg "+whitespace/indent").
431
Each filter should start with + or -; else we die.
434
ValueError: The comma-separated filters did not all start with '+' or '-'.
435
E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
437
# Default filters always have less priority than the flag ones.
438
self.filters = _DEFAULT_FILTERS[:]
439
for filt in filters.split(','):
440
clean_filt = filt.strip()
442
self.filters.append(clean_filt)
443
for filt in self.filters:
444
if not (filt.startswith('+') or filt.startswith('-')):
445
raise ValueError('Every filter in --filters must start with + or -'
446
' (%s does not)' % filt)
448
def ResetErrorCount(self):
449
"""Sets the module's error statistic back to zero."""
452
def IncrementErrorCount(self):
453
"""Bumps the module's error statistic."""
454
self.error_count += 1
457
_cpplint_state = _CppLintState()
461
"""Gets the module's output format."""
462
return _cpplint_state.output_format
465
def _SetOutputFormat(output_format):
466
"""Sets the module's output format."""
467
_cpplint_state.SetOutputFormat(output_format)
471
"""Returns the module's verbosity setting."""
472
return _cpplint_state.verbose_level
475
def _SetVerboseLevel(level):
476
"""Sets the module's verbosity, and returns the previous setting."""
477
return _cpplint_state.SetVerboseLevel(level)
481
"""Returns the module's list of output filters, as a list."""
482
return _cpplint_state.filters
485
def _SetFilters(filters):
486
"""Sets the module's error-message filters.
488
These filters are applied when deciding whether to emit a given
492
filters: A string of comma-separated filters (eg "whitespace/indent").
493
Each filter should start with + or -; else we die.
495
_cpplint_state.SetFilters(filters)
498
class _FunctionState(object):
499
"""Tracks current function name and the number of lines in its body."""
501
_NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc.
502
_TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER.
505
self.in_a_function = False
506
self.lines_in_function = 0
507
self.current_function = ''
509
def Begin(self, function_name):
510
"""Start analyzing function body.
513
function_name: The name of the function being tracked.
515
self.in_a_function = True
516
self.lines_in_function = 0
517
self.current_function = function_name
520
"""Count line in current function body."""
521
if self.in_a_function:
522
self.lines_in_function += 1
524
def Check(self, error, filename, linenum):
525
"""Report if too many lines in function body.
528
error: The function to call with any errors found.
529
filename: The name of the current file.
530
linenum: The number of the line to check.
532
if Match(r'T(EST|est)', self.current_function):
533
base_trigger = self._TEST_TRIGGER
535
base_trigger = self._NORMAL_TRIGGER
536
trigger = base_trigger * 2**_VerboseLevel()
538
if self.lines_in_function > trigger:
539
error_level = int(math.log(self.lines_in_function / base_trigger, 2))
540
# 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
543
error(filename, linenum, 'readability/fn_size', error_level,
544
'Small and focused functions are preferred:'
545
' %s has %d non-comment lines'
546
' (error triggered by exceeding %d lines).' % (
547
self.current_function, self.lines_in_function, trigger))
550
"""Stop analizing function body."""
551
self.in_a_function = False
554
class _IncludeError(Exception):
555
"""Indicates a problem with the include order in a file."""
560
"""Provides utility functions for filenames.
562
FileInfo provides easy access to the components of a file's path
563
relative to the project root.
566
def __init__(self, filename):
567
self._filename = filename
570
"""Make Windows paths like Unix."""
571
return os.path.abspath(self._filename).replace('\\', '/')
573
def RepositoryName(self):
574
"""FullName after removing the local path to the repository.
576
If we have a real absolute path name here we can try to do something smart:
577
detecting the root of the checkout and truncating /path/to/checkout from
578
the name so that we get header guards that don't include things like
579
"C:\Documents and Settings\..." or "/home/username/..." in them and thus
580
people on different computers who have checked the source out to different
581
locations won't see bogus errors.
583
fullname = self.FullName()
585
if os.path.exists(fullname):
586
project_dir = os.path.dirname(fullname)
588
root_dir = os.path.dirname(fullname)
589
while (root_dir != os.path.dirname(root_dir) and
590
not (os.path.exists(os.path.join(root_dir, ".bzr"))
592
os.path.exists(os.path.join(root_dir, "_build")))):
593
root_dir = os.path.dirname(root_dir)
594
if (os.path.exists(os.path.join(root_dir, ".bzr")) or
595
os.path.exists(os.path.join(root_dir, "_build"))):
596
prefix = os.path.commonprefix([root_dir, project_dir])
597
return fullname[len(prefix) + 1:]
599
# Don't know what to do; header guard warnings may be wrong...
603
"""Splits the file into the directory, basename, and extension.
605
For 'chrome/browser/browser.cc', Split() would
606
return ('chrome/browser', 'browser', '.cc')
609
A tuple of (directory, basename, extension).
612
googlename = self.RepositoryName()
613
project, rest = os.path.split(googlename)
614
return (project,) + os.path.splitext(rest)
617
"""File base name - text after the final slash, before the final period."""
618
return self.Split()[1]
621
"""File extension - text following the final period."""
622
return self.Split()[2]
624
def NoExtension(self):
625
"""File has no source file extension."""
626
return '/'.join(self.Split()[0:2])
629
"""File has a source file extension."""
630
return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
633
def _ShouldPrintError(category, confidence):
634
"""Returns true iff confidence >= verbose, and category passes filter."""
635
# There are two ways we might decide not to print an error message:
636
# the verbosity level isn't high enough, or the filters filter it out.
637
if confidence < _cpplint_state.verbose_level:
641
for one_filter in _Filters():
642
if one_filter.startswith('-'):
643
if category.startswith(one_filter[1:]):
645
elif one_filter.startswith('+'):
646
if category.startswith(one_filter[1:]):
649
assert False # should have been checked for in SetFilter.
656
def Error(filename, linenum, category, confidence, message):
657
"""Logs the fact we've found a lint error.
659
We log where the error was found, and also our confidence in the error,
660
that is, how certain we are this is a legitimate style regression, and
661
not a misidentification or a use that's sometimes justified.
664
filename: The name of the file containing the error.
665
linenum: The number of the line containing the error.
666
category: A string used to describe the "category" this bug
667
falls under: "whitespace", say, or "runtime". Categories
668
may have a hierarchy separated by slashes: "whitespace/indent".
669
confidence: A number from 1-5 representing a confidence score for
670
the error, with 5 meaning that we are certain of the problem,
671
and 1 meaning that it could be a legitimate construct.
672
message: The error message.
674
# There are two ways we might decide not to print an error message:
675
# the verbosity level isn't high enough, or the filters filter it out.
676
if _ShouldPrintError(category, confidence):
677
_cpplint_state.IncrementErrorCount()
678
if _cpplint_state.output_format == 'vs7':
679
sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
680
filename, linenum, message, category, confidence))
682
sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
683
filename, linenum, message, category, confidence))
686
# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
687
_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
688
r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
689
# Matches strings. Escape codes should already be removed by ESCAPES.
690
_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
691
# Matches characters. Escape codes should already be removed by ESCAPES.
692
_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
693
# Matches multi-line C++ comments.
694
# This RE is a little bit more complicated than one might expect, because we
695
# have to take care of space removals tools so we can handle comments inside
697
# The current rule is: We only clear spaces from both sides when we're at the
698
# end of the line. Otherwise, we try to remove spaces from the right side,
699
# if this doesn't work we try on left side but only if there's a non-character
701
_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
702
r"""(\s*/\*.*\*/\s*$|
705
/\*.*\*/)""", re.VERBOSE)
708
def IsCppString(line):
709
"""Does line terminate so, that the next symbol is in string constant.
711
This function does not consider single-line nor multi-line comments.
714
line: is a partial line of code starting from the 0..n.
717
True, if next character appended to 'line' is inside a
721
line = line.replace(r'\\', 'XX') # after this, \\" does not match to \"
722
return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
725
def FindNextMultiLineCommentStart(lines, lineix):
726
"""Find the beginning marker for a multiline comment."""
727
while lineix < len(lines):
728
if lines[lineix].strip().startswith('/*'):
729
# Only return this marker if the comment goes beyond this line
730
if lines[lineix].strip().find('*/', 2) < 0:
736
def FindNextMultiLineCommentEnd(lines, lineix):
737
"""We are inside a comment, find the end marker."""
738
while lineix < len(lines):
739
if lines[lineix].strip().endswith('*/'):
745
def RemoveMultiLineCommentsFromRange(lines, begin, end):
746
"""Clears a range of lines for multi-line comments."""
747
# Having // dummy comments makes the lines non-empty, so we will not get
748
# unnecessary blank line warnings later in the code.
749
for i in range(begin, end):
750
lines[i] = '// dummy'
753
def RemoveMultiLineComments(filename, lines, error):
754
"""Removes multiline (c-style) comments from lines."""
756
while lineix < len(lines):
757
lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
758
if lineix_begin >= len(lines):
760
lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
761
if lineix_end >= len(lines):
762
error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
763
'Could not find end of multi-line comment')
765
RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
766
lineix = lineix_end + 1
769
def CleanseComments(line):
770
"""Removes //-comments and single-line C-style /* */ comments.
773
line: A line of C++ source.
776
The line with single-line comments removed.
778
commentpos = line.find('//')
779
if commentpos != -1 and not IsCppString(line[:commentpos]):
780
line = line[:commentpos]
781
# get rid of /* ... */
782
return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
785
class CleansedLines(object):
786
"""Holds 3 copies of all lines with different preprocessing applied to them.
788
1) elided member contains lines without strings and comments,
789
2) lines member contains lines without comments, and
790
3) raw member contains all the lines without processing.
791
All these three members are of <type 'list'>, and of the same length.
794
def __init__(self, lines):
797
self.raw_lines = lines
798
self.num_lines = len(lines)
799
for linenum in range(len(lines)):
800
self.lines.append(CleanseComments(lines[linenum]))
801
elided = self._CollapseStrings(lines[linenum])
802
self.elided.append(CleanseComments(elided))
805
"""Returns the number of lines represented."""
806
return self.num_lines
809
def _CollapseStrings(elided):
810
"""Collapses strings and chars on a line to simple "" or '' blocks.
812
We nix strings first so we're not fooled by text like '"http://"'
815
elided: The line being processed.
818
The line with collapsed strings.
820
if not _RE_PATTERN_INCLUDE.match(elided):
821
# Remove escaped characters first to make quote/single quote collapsing
822
# basic. Things that look like escaped characters shouldn't occur
823
# outside of strings and chars.
824
elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
825
elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
826
elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
830
def CloseExpression(clean_lines, linenum, pos):
831
"""If input points to ( or { or [, finds the position that closes it.
833
If lines[linenum][pos] points to a '(' or '{' or '[', finds the the
834
linenum/pos that correspond to the closing of the expression.
837
clean_lines: A CleansedLines instance containing the file.
838
linenum: The number of the line to check.
839
pos: A position on the line.
842
A tuple (line, linenum, pos) pointer *past* the closing brace, or
843
(line, len(lines), -1) if we never find a close. Note we ignore
844
strings and comments when matching; and the line we return is the
845
'cleansed' line at linenum.
848
line = clean_lines.elided[linenum]
849
startchar = line[pos]
850
if startchar not in '({[':
851
return (line, clean_lines.NumLines(), -1)
852
if startchar == '(': endchar = ')'
853
if startchar == '[': endchar = ']'
854
if startchar == '{': endchar = '}'
856
num_open = line.count(startchar) - line.count(endchar)
857
while linenum < clean_lines.NumLines() and num_open > 0:
859
line = clean_lines.elided[linenum]
860
num_open += line.count(startchar) - line.count(endchar)
861
# OK, now find the endchar that actually got us back to even
864
endpos = line.rfind(')', 0, endpos)
865
num_open -= 1 # chopped off another )
866
return (line, linenum, endpos + 1)
869
def CheckForCopyright(filename, lines, error):
870
"""Logs an error if no Copyright message appears at the top of the file."""
872
# We'll say it should occur by line 10. Don't forget there's a
873
# dummy line at the front.
874
for line in xrange(1, min(len(lines), 11)):
875
if re.search(r'Copyright', lines[line], re.I): break
876
else: # means no copyright line was found
877
error(filename, 0, 'legal/copyright', 5,
878
'No copyright message found. '
879
'You should have a line: "Copyright [year] <Copyright Owner>"')
882
def GetHeaderGuardCPPVariable(filename):
883
"""Returns the CPP variable that should be used as a header guard.
886
filename: The name of a C++ header file.
889
The CPP variable that should be used as a header guard in the
894
fileinfo = FileInfo(filename)
895
return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper()
898
def CheckForHeaderGuard(filename, lines, error):
899
"""Checks that the file contains a header guard.
901
Logs an error if no #ifndef header guard is present. For other
902
headers, checks that the full pathname is used.
905
filename: The name of the C++ header file.
906
lines: An array of strings, each representing a line of the file.
907
error: The function to call with any errors found.
910
cppvar = GetHeaderGuardCPPVariable(filename)
917
for linenum, line in enumerate(lines):
918
linesplit = line.split()
919
if len(linesplit) >= 2:
920
# find the first occurrence of #ifndef and #define, save arg
921
if not ifndef and linesplit[0] == '#ifndef':
922
# set ifndef to the header guard presented on the #ifndef line.
923
ifndef = linesplit[1]
924
ifndef_linenum = linenum
925
if not define and linesplit[0] == '#define':
926
define = linesplit[1]
927
# find the last occurrence of #endif, save entire line
928
if line.startswith('#endif'):
930
endif_linenum = linenum
932
if not ifndef or not define or ifndef != define:
933
error(filename, 0, 'build/header_guard', 5,
934
'No #ifndef header guard found, suggested CPP variable is: %s' %
938
# The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
939
# for backward compatibility.
942
if ifndef != cppvar + '_':
945
error(filename, ifndef_linenum, 'build/header_guard', error_level,
946
'#ifndef header guard has wrong style, please use: %s' % cppvar)
948
if endif != ('#endif /* %s */' % cppvar):
950
if endif != ('#endif /* %s */' % (cppvar + '_')):
953
error(filename, endif_linenum, 'build/header_guard', error_level,
954
'#endif line should be "#endif /* %s */"' % cppvar)
957
def CheckForUnicodeReplacementCharacters(filename, lines, error):
958
"""Logs an error for each line containing Unicode replacement characters.
960
These indicate that either the file contained invalid UTF-8 (likely)
961
or Unicode replacement characters (which it shouldn't). Note that
962
it's possible for this to throw off line numbering if the invalid
963
UTF-8 occurred adjacent to a newline.
966
filename: The name of the current file.
967
lines: An array of strings, each representing a line of the file.
968
error: The function to call with any errors found.
970
for linenum, line in enumerate(lines):
971
if u'\ufffd' in line:
972
error(filename, linenum, 'readability/utf8', 5,
973
'Line contains invalid UTF-8 (or Unicode replacement character).')
976
def CheckForNewlineAtEOF(filename, lines, error):
977
"""Logs an error if there is no newline char at the end of the file.
980
filename: The name of the current file.
981
lines: An array of strings, each representing a line of the file.
982
error: The function to call with any errors found.
985
# The array lines() was created by adding two newlines to the
986
# original file (go figure), then splitting on \n.
987
# To verify that the file ends in \n, we just have to make sure the
988
# last-but-two element of lines() exists and is empty.
989
if len(lines) < 3 or lines[-2]:
990
error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
991
'Could not find a newline character at the end of the file.')
994
def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
995
"""Logs an error if we see /* ... */ or "..." that extend past one line.
997
/* ... */ comments are legit inside macros, for one line.
998
Otherwise, we prefer // comments, so it's ok to warn about the
999
other. Likewise, it's ok for strings to extend across multiple
1000
lines, as long as a line continuation character (backslash)
1001
terminates each line. Although not currently prohibited by the C++
1002
style guide, it's ugly and unnecessary. We don't do well with either
1003
in this lint program, so we warn about both.
1006
filename: The name of the current file.
1007
clean_lines: A CleansedLines instance containing the file.
1008
linenum: The number of the line to check.
1009
error: The function to call with any errors found.
1011
line = clean_lines.elided[linenum]
1013
# Remove all \\ (escaped backslashes) from the line. They are OK, and the
1014
# second (escaped) slash may trigger later \" detection erroneously.
1015
line = line.replace('\\\\', '')
1017
if line.count('/*') > line.count('*/'):
1018
error(filename, linenum, 'readability/multiline_comment', 5,
1019
'Complex multi-line /*...*/-style comment found. '
1020
'Lint may give bogus warnings. '
1021
'Consider replacing these with //-style comments, '
1022
'with #if 0...#endif, '
1023
'or with more clearly structured multi-line comments.')
1025
if (line.count('"') - line.count('\\"')) % 2:
1026
error(filename, linenum, 'readability/multiline_string', 5,
1027
'Multi-line string ("...") found. This lint script doesn\'t '
1028
'do well with such strings, and may give bogus warnings. They\'re '
1029
'ugly and unnecessary, and you should use concatenation instead".')
1033
('asctime(', 'asctime_r('),
1034
('ctime(', 'ctime_r('),
1035
('getgrgid(', 'getgrgid_r('),
1036
('getgrnam(', 'getgrnam_r('),
1037
('getlogin(', 'getlogin_r('),
1038
('getpwnam(', 'getpwnam_r('),
1039
('getpwuid(', 'getpwuid_r('),
1040
('gmtime(', 'gmtime_r('),
1041
('localtime(', 'localtime_r('),
1042
('rand(', 'rand_r('),
1043
('readdir(', 'readdir_r('),
1044
('strtok(', 'strtok_r('),
1045
('ttyname(', 'ttyname_r('),
1049
def CheckPosixThreading(filename, clean_lines, linenum, error):
1050
"""Checks for calls to thread-unsafe functions.
1052
Much code has been originally written without consideration of
1053
multi-threading. Also, engineers are relying on their old experience;
1054
they have learned posix before threading extensions were added. These
1055
tests guide the engineers to use thread-safe functions (when using
1059
filename: The name of the current file.
1060
clean_lines: A CleansedLines instance containing the file.
1061
linenum: The number of the line to check.
1062
error: The function to call with any errors found.
1064
line = clean_lines.elided[linenum]
1065
for single_thread_function, multithread_safe_function in threading_list:
1066
ix = line.find(single_thread_function)
1067
# Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1068
if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
1069
line[ix - 1] not in ('_', '.', '>'))):
1070
error(filename, linenum, 'runtime/threadsafe_fn', 2,
1071
'Consider using ' + multithread_safe_function +
1072
'...) instead of ' + single_thread_function +
1073
'...) for improved thread safety.')
1076
# Matches invalid increment: *count++, which moves pointer insead of
1077
# incrementing a value.
1078
_RE_PATTERN_IVALID_INCREMENT = re.compile(
1079
r'^\s*\*\w+(\+\+|--);')
1082
def CheckInvalidIncrement(filename, clean_lines, linenum, error):
1083
"""Checks for invalud increment *count++.
1085
For example following function:
1086
void increment_counter(int* count) {
1089
is invalid, because it effectively does count++, moving pointer, and should
1090
be replaced with ++*count, (*count)++ or *count += 1.
1093
filename: The name of the current file.
1094
clean_lines: A CleansedLines instance containing the file.
1095
linenum: The number of the line to check.
1096
error: The function to call with any errors found.
1098
line = clean_lines.elided[linenum]
1099
if _RE_PATTERN_IVALID_INCREMENT.match(line):
1100
error(filename, linenum, 'runtime/invalid_increment', 5,
1101
'Changing pointer instead of value (or unused value of operator*).')
1104
class _ClassInfo(object):
1105
"""Stores information about a class."""
1107
def __init__(self, name, linenum):
1109
self.linenum = linenum
1110
self.seen_open_brace = False
1111
self.is_derived = False
1112
self.virtual_method_linenumber = None
1113
self.has_virtual_destructor = False
1114
self.brace_depth = 0
1117
class _ClassState(object):
1118
"""Holds the current state of the parse relating to class declarations.
1120
It maintains a stack of _ClassInfos representing the parser's guess
1121
as to the current nesting of class declarations. The innermost class
1122
is at the top (back) of the stack. Typically, the stack will either
1123
be empty or have exactly one entry.
1127
self.classinfo_stack = []
1129
def CheckFinished(self, filename, error):
1130
"""Checks that all classes have been completely parsed.
1132
Call this when all lines in a file have been processed.
1134
filename: The name of the current file.
1135
error: The function to call with any errors found.
1137
if self.classinfo_stack:
1138
# Note: This test can result in false positives if #ifdef constructs
1139
# get in the way of brace matching. See the testBuildClass test in
1140
# cpplint_unittest.py for an example of this.
1141
error(filename, self.classinfo_stack[0].linenum, 'build/class', 5,
1142
'Failed to find complete declaration of class %s' %
1143
self.classinfo_stack[0].name)
1146
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
1147
class_state, error):
1148
"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
1150
Complain about several constructs which gcc-2 accepts, but which are
1151
not standard C++. Warning about these in lint is one way to ease the
1152
transition to new compilers.
1153
- put storage class first (e.g. "static const" instead of "const static").
1154
- "%lld" instead of %qd" in printf-type functions.
1155
- "%1$d" is non-standard in printf-type functions.
1156
- "\%" is an undefined character escape sequence.
1157
- text after #endif is not allowed.
1158
- invalid inner-style forward declaration.
1159
- >? and <? operators, and their >?= and <?= cousins.
1160
- classes with virtual methods need virtual destructors (compiler warning
1161
available, but not turned on yet.)
1163
Additionally, check for constructor/destructor style violations as it
1164
is very convenient to do so while checking for gcc-2 compliance.
1167
filename: The name of the current file.
1168
clean_lines: A CleansedLines instance containing the file.
1169
linenum: The number of the line to check.
1170
class_state: A _ClassState instance which maintains information about
1171
the current stack of nested class declarations being parsed.
1172
error: A callable to which errors are reported, which takes 4 arguments:
1173
filename, line number, error level, and message
1176
# Remove comments from the line, but leave in strings for now.
1177
line = clean_lines.lines[linenum]
1179
if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
1180
error(filename, linenum, 'runtime/printf_format', 3,
1181
'%q in format strings is deprecated. Use %ll instead.')
1183
if Search(r'printf\s*\(.*".*%\d+\$', line):
1184
error(filename, linenum, 'runtime/printf_format', 2,
1185
'%N$ formats are unconventional. Try rewriting to avoid them.')
1187
# Remove escaped backslashes before looking for undefined escapes.
1188
line = line.replace('\\\\', '')
1190
if Search(r'("|\').*\\(%|\[|\(|{)', line):
1191
error(filename, linenum, 'build/printf_format', 3,
1192
'%, [, (, and { are undefined character escapes. Unescape them.')
1194
# For the rest, work with both comments and strings removed.
1195
line = clean_lines.elided[linenum]
1197
if Search(r'\b(const|volatile|void|char|short|int|long'
1198
r'|float|double|signed|unsigned'
1199
r'|schar|u?int8|u?int16|u?int32|u?int64)'
1200
r'\s+(auto|register|static|extern|typedef)\b',
1202
error(filename, linenum, 'build/storage_class', 5,
1203
'Storage class (static, extern, typedef, etc) should be first.')
1205
if Match(r'\s*#\s*endif\s*[^/\s]+', line):
1206
error(filename, linenum, 'build/endif_comment', 5,
1207
'Uncommented text after #endif is non-standard. Use a comment.')
1209
if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
1210
error(filename, linenum, 'build/forward_decl', 5,
1211
'Inner-style forward declarations are invalid. Remove this line.')
1213
if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
1215
error(filename, linenum, 'build/deprecated', 3,
1216
'>? and <? (max and min) operators are non-standard and deprecated.')
1218
# Track class entry and exit, and attempt to find cases within the
1219
# class declaration that don't meet the C++ style
1220
# guidelines. Tracking is very dependent on the code matching Google
1221
# style guidelines, but it seems to perform well enough in testing
1222
# to be a worthwhile addition to the checks.
1223
classinfo_stack = class_state.classinfo_stack
1224
# Look for a class declaration
1225
class_decl_match = Match(
1226
r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line)
1227
if class_decl_match:
1228
classinfo_stack.append(_ClassInfo(class_decl_match.group(3), linenum))
1230
# Everything else in this function uses the top of the stack if it's
1232
if not classinfo_stack:
1235
classinfo = classinfo_stack[-1]
1237
# If the opening brace hasn't been seen look for it and also
1238
# parent class declarations.
1239
if not classinfo.seen_open_brace:
1240
# If the line has a ';' in it, assume it's a forward declaration or
1241
# a single-line class declaration, which we won't process.
1242
if line.find(';') != -1:
1243
classinfo_stack.pop()
1245
classinfo.seen_open_brace = (line.find('{') != -1)
1246
# Look for a bare ':'
1247
if Search('(^|[^:]):($|[^:])', line):
1248
classinfo.is_derived = True
1249
if not classinfo.seen_open_brace:
1250
return # Everything else in this function is for after open brace
1252
# The class may have been declared with namespace or classname qualifiers.
1253
# The constructor and destructor will not have those qualifiers.
1254
base_classname = classinfo.name.split('::')[-1]
1256
# Look for single-argument constructors that aren't marked explicit.
1257
# Technically a valid construct, but against style.
1258
args = Match(r'(?<!explicit)\s+%s\s*\(([^,()]+)\)'
1259
% re.escape(base_classname),
1262
args.group(1) != 'void' and
1263
not Match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
1264
args.group(1).strip())):
1265
error(filename, linenum, 'runtime/explicit', 5,
1266
'Single-argument constructors should be marked explicit.')
1268
# Look for methods declared virtual.
1269
if Search(r'\bvirtual\b', line):
1270
classinfo.virtual_method_linenumber = linenum
1271
# Only look for a destructor declaration on the same line. It would
1272
# be extremely unlikely for the destructor declaration to occupy
1273
# more than one line.
1274
if Search(r'~%s\s*\(' % base_classname, line):
1275
classinfo.has_virtual_destructor = True
1277
# Look for class end.
1278
brace_depth = classinfo.brace_depth
1279
brace_depth = brace_depth + line.count('{') - line.count('}')
1280
if brace_depth <= 0:
1281
classinfo = classinfo_stack.pop()
1282
# Try to detect missing virtual destructor declarations.
1283
# For now, only warn if a non-derived class with virtual methods lacks
1284
# a virtual destructor. This is to make it less likely that people will
1285
# declare derived virtual destructors without declaring the base
1286
# destructor virtual.
1287
if ((classinfo.virtual_method_linenumber is not None) and
1288
(not classinfo.has_virtual_destructor) and
1289
(not classinfo.is_derived)): # Only warn for base classes
1290
error(filename, classinfo.linenum, 'runtime/virtual', 4,
1291
'The class %s probably needs a virtual destructor due to '
1292
'having virtual method(s), one declared at line %d.'
1293
% (classinfo.name, classinfo.virtual_method_linenumber))
1295
classinfo.brace_depth = brace_depth
1298
def CheckSpacingForFunctionCall(filename, line, linenum, error):
1299
"""Checks for the correctness of various spacing around function calls.
1302
filename: The name of the current file.
1303
line: The text of the line to check.
1304
linenum: The number of the line to check.
1305
error: The function to call with any errors found.
1308
# Since function calls often occur inside if/for/while/switch
1309
# expressions - which have their own, more liberal conventions - we
1310
# first see if we should be looking inside such an expression for a
1311
# function call, to which we can apply more strict standards.
1312
fncall = line # if there's no control flow construct, look at whole line
1313
for pattern in (r'\bif\s*\((.*)\)\s*{',
1314
r'\bfor\s*\((.*)\)\s*{',
1315
r'\bwhile\s*\((.*)\)\s*[{;]',
1316
r'\bswitch\s*\((.*)\)\s*{'):
1317
match = Search(pattern, line)
1319
fncall = match.group(1) # look inside the parens for function calls
1322
# Except in if/for/while/switch, there should never be space
1323
# immediately inside parens (eg "f( 3, 4 )"). We make an exception
1324
# for nested parens ( (a+b) + c ). Likewise, there should never be
1325
# a space before a ( when it's a function argument. I assume it's a
1326
# function argument when the char before the whitespace is legal in
1327
# a function name (alnum + _) and we're not starting a macro. Also ignore
1328
# pointers and references to arrays and functions coz they're too tricky:
1329
# we use a very simple way to recognize these:
1330
# " (something)(maybe-something)" or
1331
# " (something)(maybe-something," or
1332
# " (something)[something]"
1333
# Note that we assume the contents of [] to be short enough that
1334
# they'll never need to wrap.
1335
if ( # Ignore control structures.
1336
not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and
1337
# Ignore pointers/references to functions.
1338
not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
1339
# Ignore pointers/references to arrays.
1340
not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
1341
if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
1342
error(filename, linenum, 'whitespace/parens', 4,
1343
'Extra space after ( in function call')
1344
elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
1345
error(filename, linenum, 'whitespace/parens', 2,
1346
'Extra space after (')
1347
if (Search(r'\w\s+\(', fncall) and
1348
not Search(r'#\s*define|typedef', fncall)):
1349
error(filename, linenum, 'whitespace/parens', 4,
1350
'Extra space before ( in function call')
1351
# If the ) is followed only by a newline or a { + newline, assume it's
1352
# part of a control statement (if/while/etc), and don't complain
1353
if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
1354
error(filename, linenum, 'whitespace/parens', 2,
1355
'Extra space before )')
1358
def IsBlankLine(line):
1359
"""Returns true if the given line is blank.
1361
We consider a line to be blank if the line is empty or consists of
1365
line: A line of a string.
1368
True, if the given line is blank.
1370
return not line or line.isspace()
1373
def CheckForFunctionLengths(filename, clean_lines, linenum,
1374
function_state, error):
1375
"""Reports for long function bodies.
1377
For an overview why this is done, see:
1378
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
1380
Uses a simplistic algorithm assuming other style guidelines
1381
(especially spacing) are followed.
1382
Only checks unindented functions, so class members are unchecked.
1383
Trivial bodies are unchecked, so constructors with huge initializer lists
1385
Blank/comment lines are not counted so as to avoid encouraging the removal
1386
of vertical space and commments just to get through a lint check.
1387
NOLINT *on the last line of a function* disables this check.
1390
filename: The name of the current file.
1391
clean_lines: A CleansedLines instance containing the file.
1392
linenum: The number of the line to check.
1393
function_state: Current function name and lines in body so far.
1394
error: The function to call with any errors found.
1396
lines = clean_lines.lines
1397
line = lines[linenum]
1398
raw = clean_lines.raw_lines
1399
raw_line = raw[linenum]
1402
starting_func = False
1403
regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ...
1404
match_result = Match(regexp, line)
1406
# If the name is all caps and underscores, figure it's a macro and
1407
# ignore it, unless it's TEST or TEST_F.
1408
function_name = match_result.group(1).split()[-1]
1409
if function_name == 'TEST' or function_name == 'TEST_F' or (
1410
not Match(r'[A-Z_]+$', function_name)):
1411
starting_func = True
1415
for start_linenum in xrange(linenum, clean_lines.NumLines()):
1416
start_line = lines[start_linenum]
1417
joined_line += ' ' + start_line.lstrip()
1418
if Search(r'(;|})', start_line): # Declarations and trivial functions
1421
elif Search(r'{', start_line):
1423
function = Search(r'((\w|:)*)\(', line).group(1)
1424
if Match(r'TEST', function): # Handle TEST... macros
1425
parameter_regexp = Search(r'(\(.*\))', joined_line)
1426
if parameter_regexp: # Ignore bad syntax
1427
function += parameter_regexp.group(1)
1430
function_state.Begin(function)
1433
# No body for the function (or evidence of a non-function) was found.
1434
error(filename, linenum, 'readability/fn_size', 5,
1435
'Lint failed to find start of function body.')
1436
elif Match(r'^\}\s*$', line): # function end
1437
if not Search(r'\bNOLINT\b', raw_line):
1438
function_state.Check(error, filename, linenum)
1439
function_state.End()
1440
elif not Match(r'^\s*$', line):
1441
function_state.Count() # Count non-blank/non-comment lines.
1444
_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
1447
def CheckComment(comment, filename, linenum, error):
1448
"""Checks for common mistakes in TODO comments.
1451
comment: The text of the comment from the line in question.
1452
filename: The name of the current file.
1453
linenum: The number of the line to check.
1454
error: The function to call with any errors found.
1456
match = _RE_PATTERN_TODO.match(comment)
1458
# One whitespace is correct; zero whitespace is handled elsewhere.
1459
leading_whitespace = match.group(1)
1460
if len(leading_whitespace) > 1:
1461
error(filename, linenum, 'whitespace/todo', 2,
1462
'Too many spaces before TODO')
1464
username = match.group(2)
1466
error(filename, linenum, 'readability/todo', 2,
1467
'Missing username in TODO; it should look like '
1468
'"// TODO(my_username): Stuff."')
1470
middle_whitespace = match.group(3)
1471
# Comparisons made explicit for correctness -- pylint: disable-msg=C6403
1472
if middle_whitespace != ' ' and middle_whitespace != '':
1473
error(filename, linenum, 'whitespace/todo', 2,
1474
'TODO(my_username) should be followed by a space')
1477
def CheckSpacing(filename, clean_lines, linenum, error):
1478
"""Checks for the correctness of various spacing issues in the code.
1480
Things we check for: spaces around operators, spaces after
1481
if/for/while/switch, no spaces around parens in function calls, two
1482
spaces between code and comment, don't start a block with a blank
1483
line, don't end a function with a blank line, don't have too many
1484
blank lines in a row.
1487
filename: The name of the current file.
1488
clean_lines: A CleansedLines instance containing the file.
1489
linenum: The number of the line to check.
1490
error: The function to call with any errors found.
1493
raw = clean_lines.raw_lines
1496
# Before nixing comments, check if the line is blank for no good
1497
# reason. This includes the first line after a block is opened, and
1498
# blank lines at the end of a function (ie, right before a line like '}'
1499
if IsBlankLine(line):
1500
elided = clean_lines.elided
1501
prev_line = elided[linenum - 1]
1502
prevbrace = prev_line.rfind('{')
1503
# TODO(unknown): Don't complain if line before blank line, and line after,
1504
# both start with alnums and are indented the same amount.
1505
# This ignores whitespace at the start of a namespace block
1506
# because those are not usually indented.
1507
if (prevbrace != -1 and prev_line[prevbrace:].find('}') == -1
1508
and prev_line[:prevbrace].find('namespace') == -1):
1509
# OK, we have a blank line at the start of a code block. Before we
1510
# complain, we check if it is an exception to the rule: The previous
1511
# non-empty line has the paramters of a function header that are indented
1512
# 4 spaces (because they did not fit in a 80 column line when placed on
1513
# the same line as the function name). We also check for the case where
1514
# the previous line is indented 6 spaces, which may happen when the
1515
# initializers of a constructor do not fit into a 80 column line.
1517
if Match(r' {6}\w', prev_line): # Initializer list?
1518
# We are looking for the opening column of initializer list, which
1519
# should be indented 4 spaces to cause 6 space indentation afterwards.
1520
search_position = linenum-2
1521
while (search_position >= 0
1522
and Match(r' {6}\w', elided[search_position])):
1523
search_position -= 1
1524
exception = (search_position >= 0
1525
and elided[search_position][:5] == ' :')
1527
# Search for the function arguments or an initializer list. We use a
1528
# simple heuristic here: If the line is indented 4 spaces; and we have a
1529
# closing paren, without the opening paren, followed by an opening brace
1530
# or colon (for initializer lists) we assume that it is the last line of
1531
# a function header. If we have a colon indented 4 spaces, it is an
1533
exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
1535
or Match(r' {4}:', prev_line))
1538
error(filename, linenum, 'whitespace/blank_line', 2,
1539
'Blank line at the start of a code block. Is this needed?')
1540
# This doesn't ignore whitespace at the end of a namespace block
1541
# because that is too hard without pairing open/close braces;
1542
# however, a special exception is made for namespace closing
1543
# brackets which have a comment containing "namespace".
1545
# Also, ignore blank lines at the end of a block in a long if-else
1548
# // Something followed by a blank line
1550
# } else if (condition2) {
1553
if linenum + 1 < clean_lines.NumLines():
1554
next_line = raw[linenum + 1]
1556
and Match(r'\s*}', next_line)
1557
and next_line.find('namespace') == -1
1558
and next_line.find('} else ') == -1):
1559
error(filename, linenum, 'whitespace/blank_line', 3,
1560
'Blank line at the end of a code block. Is this needed?')
1562
# Next, we complain if there's a comment too near the text
1563
commentpos = line.find('//')
1564
if commentpos != -1:
1565
# Check if the // may be in quotes. If so, ignore it
1566
# Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1567
if (line.count('"', 0, commentpos) -
1568
line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
1569
# Allow one space for new scopes, two spaces otherwise:
1570
if (not Match(r'^\s*{ //', line) and
1571
((commentpos >= 1 and
1572
line[commentpos-1] not in string.whitespace) or
1573
(commentpos >= 2 and
1574
line[commentpos-2] not in string.whitespace))):
1575
error(filename, linenum, 'whitespace/comments', 2,
1576
'At least two spaces is best between code and comments')
1577
# There should always be a space between the // and the comment
1578
commentend = commentpos + 2
1579
if commentend < len(line) and not line[commentend] == ' ':
1580
# but some lines are exceptions -- e.g. if they're big
1581
# comment delimiters like:
1582
# //----------------------------------------------------------
1583
# or they begin with multiple slashes followed by a space:
1584
# //////// Header comment
1585
match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
1586
Search(r'^/+ ', line[commentend:]))
1588
error(filename, linenum, 'whitespace/comments', 4,
1589
'Should have a space between // and comment')
1590
CheckComment(line[commentpos:], filename, linenum, error)
1592
line = clean_lines.elided[linenum] # get rid of comments and strings
1594
# Don't try to do spacing checks for operator methods
1595
line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
1597
# = should have no space before and should always have a space after.
1598
if Search(r'[\s.]=[^=]', line):
1599
error(filename, linenum, 'whitespace/operators', 4,
1600
'Space found before =')
1601
if Search(r'=[\w.]', line):
1602
error(filename, linenum, 'whitespace/operators', 4,
1603
'Missing space after =')
1605
# It's ok not to have spaces around binary operators like + - * /, but if
1606
# there's too little whitespace, we get concerned. It's hard to tell,
1607
# though, so we punt on this one for now. TODO.
1609
# You should always have whitespace around binary operators.
1610
# Alas, we can't test < or > because they're legitimately used sans spaces
1611
# (a->b, vector<int> a). The only time we can tell is a < with no >, and
1612
# only if it's not template params list spilling into the next line.
1613
match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
1615
# Note that while it seems that the '<[^<]*' term in the following
1616
# regexp could be simplified to '<.*', which would indeed match
1617
# the same class of strings, the [^<] means that searching for the
1618
# regexp takes linear rather than quadratic time.
1619
if not Search(r'<[^<]*,\s*$', line): # template params spill
1620
match = Search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line)
1622
error(filename, linenum, 'whitespace/operators', 3,
1623
'Missing spaces around %s' % match.group(1))
1624
# We allow no-spaces around << and >> when used like this: 10<<20, but
1625
# not otherwise (particularly, not when used as streams)
1626
match = Search(r'[^0-9\s](<<|>>)[^0-9\s]', line)
1628
error(filename, linenum, 'whitespace/operators', 3,
1629
'Missing spaces around %s' % match.group(1))
1631
# There shouldn't be space around unary operators
1632
match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
1634
error(filename, linenum, 'whitespace/operators', 4,
1635
'Extra space for operator %s' % match.group(1))
1637
# A pet peeve of mine: no spaces after an if, while, switch, or for
1638
match = Search(r' (if\(|for\(|while\(|switch\()', line)
1640
error(filename, linenum, 'whitespace/parens', 5,
1641
'Missing space before ( in %s' % match.group(1))
1643
# For if/for/while/switch, the left and right parens should be
1644
# consistent about how many spaces are inside the parens, and
1645
# there should either be zero or one spaces inside the parens.
1646
# We don't want: "if ( foo)" or "if ( foo )".
1647
# Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
1648
match = Search(r'\b(if|for|while|switch)\s*'
1649
r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
1652
if len(match.group(2)) != len(match.group(4)):
1653
if not (match.group(3) == ';' and
1654
len(match.group(2)) == 1 + len(match.group(4)) or
1655
not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
1656
error(filename, linenum, 'whitespace/parens', 5,
1657
'Mismatching spaces inside () in %s' % match.group(1))
1658
if not len(match.group(2)) in [0, 1]:
1659
error(filename, linenum, 'whitespace/parens', 5,
1660
'Should have zero or one spaces inside ( and ) in %s' %
1663
# You should always have a space after a comma (either as fn arg or operator)
1664
if Search(r',[^\s]', line):
1665
error(filename, linenum, 'whitespace/comma', 3,
1666
'Missing space after ,')
1668
# Next we will look for issues with function calls.
1669
CheckSpacingForFunctionCall(filename, line, linenum, error)
1671
# Except after an opening paren, you should have spaces before your braces.
1672
# And since you should never have braces at the beginning of a line, this is
1674
if Search(r'[^ (]{', line):
1675
error(filename, linenum, 'whitespace/braces', 5,
1676
'Missing space before {')
1678
# Make sure '} else {' has spaces.
1679
if Search(r'}else', line):
1680
error(filename, linenum, 'whitespace/braces', 5,
1681
'Missing space before else')
1683
# You shouldn't have spaces before your brackets, except maybe after
1684
# 'delete []' or 'new char * []'.
1685
if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
1686
error(filename, linenum, 'whitespace/braces', 5,
1687
'Extra space before [')
1689
# You shouldn't have a space before a semicolon at the end of the line.
1690
# There's a special case for "for" since the style guide allows space before
1691
# the semicolon there.
1692
if Search(r':\s*;\s*$', line):
1693
error(filename, linenum, 'whitespace/semicolon', 5,
1694
'Semicolon defining empty statement. Use { } instead.')
1695
elif Search(r'^\s*;\s*$', line):
1696
error(filename, linenum, 'whitespace/semicolon', 5,
1697
'Line contains only semicolon. If this should be an empty statement, '
1699
elif (Search(r'\s+;\s*$', line) and
1700
not Search(r'\bfor\b', line)):
1701
error(filename, linenum, 'whitespace/semicolon', 5,
1702
'Extra space before last semicolon. If this should be an empty '
1703
'statement, use { } instead.')
1706
def GetPreviousNonBlankLine(clean_lines, linenum):
1707
"""Return the most recent non-blank line and its line number.
1710
clean_lines: A CleansedLines instance containing the file contents.
1711
linenum: The number of the line to check.
1714
A tuple with two elements. The first element is the contents of the last
1715
non-blank line before the current line, or the empty string if this is the
1716
first non-blank line. The second is the line number of that line, or -1
1717
if this is the first non-blank line.
1720
prevlinenum = linenum - 1
1721
while prevlinenum >= 0:
1722
prevline = clean_lines.elided[prevlinenum]
1723
if not IsBlankLine(prevline): # if not a blank line...
1724
return (prevline, prevlinenum)
1729
def CheckBraces(filename, clean_lines, linenum, error):
1730
"""Looks for misplaced braces (e.g. at the end of line).
1733
filename: The name of the current file.
1734
clean_lines: A CleansedLines instance containing the file.
1735
linenum: The number of the line to check.
1736
error: The function to call with any errors found.
1739
line = clean_lines.elided[linenum] # get rid of comments and strings
1741
if Match(r'\s*{\s*$', line):
1742
# We allow an open brace to start a line in the case where someone
1743
# is using braces in a block to explicitly create a new scope,
1744
# which is commonly used to control the lifetime of
1745
# stack-allocated variables. We don't detect this perfectly: we
1746
# just don't complain if the last non-whitespace character on the
1747
# previous non-blank line is ';', ':', '{', or '}'.
1748
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
1749
if not Search(r'[;:}{]\s*$', prevline):
1750
error(filename, linenum, 'whitespace/braces', 4,
1751
'{ should almost always be at the end of the previous line')
1753
# An else clause should be on the same line as the preceding closing brace.
1754
if Match(r'\s*else\s*', line):
1755
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
1756
if Match(r'\s*}\s*$', prevline):
1757
error(filename, linenum, 'whitespace/newline', 4,
1758
'An else should appear on the same line as the preceding }')
1760
# If braces come on one side of an else, they should be on both.
1761
# However, we have to worry about "else if" that spans multiple lines!
1762
if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
1763
if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if
1764
# find the ( after the if
1765
pos = line.find('else if')
1766
pos = line.find('(', pos)
1768
(endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
1769
if endline[endpos:].find('{') == -1: # must be brace after if
1770
error(filename, linenum, 'readability/braces', 5,
1771
'If an else has a brace on one side, it should have it on both')
1772
else: # common case: else not followed by a multi-line if
1773
error(filename, linenum, 'readability/braces', 5,
1774
'If an else has a brace on one side, it should have it on both')
1776
# Likewise, an else should never have the else clause on the same line
1777
if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
1778
error(filename, linenum, 'whitespace/newline', 4,
1779
'Else clause should never be on same line as else (use 2 lines)')
1781
# In the same way, a do/while should never be on one line
1782
if Match(r'\s*do [^\s{]', line):
1783
error(filename, linenum, 'whitespace/newline', 4,
1784
'do/while clauses should not be on a single line')
1786
# Braces shouldn't be followed by a ; unless they're defining a struct
1787
# or initializing an array.
1788
# We can't tell in general, but we can for some common cases.
1789
prevlinenum = linenum
1791
(prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum)
1792
if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'):
1793
line = prevline + line
1796
if (Search(r'{.*}\s*;', line) and
1797
line.count('{') == line.count('}') and
1798
not Search(r'struct|class|enum|\s*=\s*{', line)):
1799
error(filename, linenum, 'readability/braces', 4,
1800
"You don't need a ; after a }")
1803
def ReplaceableCheck(operator, macro, line):
1804
"""Determine whether a basic CHECK can be replaced with a more specific one.
1806
For example suggest using CHECK_EQ instead of CHECK(a == b) and
1807
similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
1810
operator: The C++ operator used in the CHECK.
1811
macro: The CHECK or EXPECT macro being called.
1812
line: The current source line.
1815
True if the CHECK can be replaced with a more specific one.
1818
# This matches decimal and hex integers, strings, and chars (in that order).
1819
match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
1821
# Expression to match two sides of the operator with something that
1822
# looks like a literal, since CHECK(x == iterator) won't compile.
1823
# This means we can't catch all the cases where a more specific
1824
# CHECK is possible, but it's less annoying than dealing with
1825
# extraneous warnings.
1826
match_this = (r'\s*' + macro + r'\((\s*' +
1827
match_constant + r'\s*' + operator + r'[^<>].*|'
1828
r'.*[^<>]' + operator + r'\s*' + match_constant +
1831
# Don't complain about CHECK(x == NULL) or similar because
1832
# CHECK_EQ(x, NULL) won't compile (requires a cast).
1833
# Also, don't complain about more complex boolean expressions
1834
# involving && or || such as CHECK(a == b || c == d).
1835
return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line)
1838
def CheckCheck(filename, clean_lines, linenum, error):
1839
"""Checks the use of CHECK and EXPECT macros.
1842
filename: The name of the current file.
1843
clean_lines: A CleansedLines instance containing the file.
1844
linenum: The number of the line to check.
1845
error: The function to call with any errors found.
1848
# Decide the set of replacement macros that should be suggested
1849
raw_lines = clean_lines.raw_lines
1851
for macro in _CHECK_MACROS:
1852
if raw_lines[linenum].find(macro) >= 0:
1853
current_macro = macro
1855
if not current_macro:
1856
# Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
1859
line = clean_lines.elided[linenum] # get rid of comments and strings
1861
# Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.
1862
for operator in ['==', '!=', '>=', '>', '<=', '<']:
1863
if ReplaceableCheck(operator, current_macro, line):
1864
error(filename, linenum, 'readability/check', 2,
1865
'Consider using %s instead of %s(a %s b)' % (
1866
_CHECK_REPLACEMENT[current_macro][operator],
1867
current_macro, operator))
1871
def GetLineWidth(line):
1872
"""Determines the width of the line in column positions.
1875
line: A string, which may be a Unicode string.
1878
The width of the line in column positions, accounting for Unicode
1879
combining characters and wide characters.
1881
if isinstance(line, unicode):
1883
for c in unicodedata.normalize('NFC', line):
1884
if unicodedata.east_asian_width(c) in ('W', 'F'):
1886
elif not unicodedata.combining(c):
1893
def CheckStyle(filename, clean_lines, linenum, file_extension, error):
1894
"""Checks rules from the 'C++ style rules' section of cppguide.html.
1896
Most of these rules are hard to test (naming, comment style), but we
1897
do what we can. In particular we check for 2-space indents, line lengths,
1898
tab usage, spaces inside code, etc.
1901
filename: The name of the current file.
1902
clean_lines: A CleansedLines instance containing the file.
1903
linenum: The number of the line to check.
1904
file_extension: The extension (without the dot) of the filename.
1905
error: The function to call with any errors found.
1908
raw_lines = clean_lines.raw_lines
1909
line = raw_lines[linenum]
1911
if line.find('\t') != -1:
1912
error(filename, linenum, 'whitespace/tab', 1,
1913
'Tab found; better to use spaces')
1915
# One or three blank spaces at the beginning of the line is weird; it's
1916
# hard to reconcile that with 2-space indents.
1917
# NOTE: here are the conditions rob pike used for his tests. Mine aren't
1918
# as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
1919
# if(RLENGTH > 20) complain = 0;
1920
# if(match($0, " +(error|private|public|protected):")) complain = 0;
1921
# if(match(prev, "&& *$")) complain = 0;
1922
# if(match(prev, "\\|\\| *$")) complain = 0;
1923
# if(match(prev, "[\",=><] *$")) complain = 0;
1924
# if(match($0, " <<")) complain = 0;
1925
# if(match(prev, " +for \\(")) complain = 0;
1926
# if(prevodd && match(prevprev, " +for \\(")) complain = 0;
1928
cleansed_line = clean_lines.elided[linenum]
1929
while initial_spaces < len(line) and line[initial_spaces] == ' ':
1931
if line and line[-1].isspace():
1932
error(filename, linenum, 'whitespace/end_of_line', 4,
1933
'Line ends in whitespace. Consider deleting these extra spaces.')
1934
# There are certain situations we allow one space, notably for labels
1935
elif ((initial_spaces == 1 or initial_spaces == 3) and
1936
not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
1937
error(filename, linenum, 'whitespace/indent', 3,
1938
'Weird number of spaces at line-start. '
1939
'Are you using a 2-space indent?')
1940
# Labels should always be indented at least one space.
1941
elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
1943
error(filename, linenum, 'whitespace/labels', 4,
1944
'Labels should always be indented at least one space. '
1945
'If this is a member-initializer list in a constructor, '
1946
'the colon should be on the line after the definition header.')
1948
# Check if the line is a header guard.
1949
is_header_guard = False
1950
if file_extension == 'h':
1951
cppvar = GetHeaderGuardCPPVariable(filename)
1952
if (line.startswith('#ifndef %s' % cppvar) or
1953
line.startswith('#define %s' % cppvar) or
1954
line.startswith('#endif // %s' % cppvar)):
1955
is_header_guard = True
1956
# #include lines and header guards can be long, since there's no clean way to
1959
# URLs can be long too. It's possible to split these, but it makes them
1960
# harder to cut&paste.
1961
if (not line.startswith('#include') and not is_header_guard and
1962
not Match(r'^\s*//.*http(s?)://\S*$', line)):
1963
line_width = GetLineWidth(line)
1964
if line_width > 100:
1965
error(filename, linenum, 'whitespace/line_length', 4,
1966
'Lines should very rarely be longer than 100 characters')
1967
elif line_width > 80:
1968
error(filename, linenum, 'whitespace/line_length', 2,
1969
'Lines should be <= 80 characters long')
1971
if (cleansed_line.count(';') > 1 and
1972
# for loops are allowed two ;'s (and may run over two lines).
1973
cleansed_line.find('for') == -1 and
1974
(GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
1975
GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
1976
# It's ok to have many commands in a switch case that fits in 1 line
1977
not ((cleansed_line.find('case ') != -1 or
1978
cleansed_line.find('default:') != -1) and
1979
cleansed_line.find('break;') != -1)):
1980
error(filename, linenum, 'whitespace/newline', 4,
1981
'More than one command on the same line')
1983
# Some more style checks
1984
CheckBraces(filename, clean_lines, linenum, error)
1985
CheckSpacing(filename, clean_lines, linenum, error)
1986
CheckCheck(filename, clean_lines, linenum, error)
1989
_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
1990
_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
1991
# Matches the first component of a filename delimited by -s and _s. That is:
1992
# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
1993
# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
1994
# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
1995
# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
1996
_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
1999
def _DropCommonSuffixes(filename):
2000
"""Drops common suffixes like _test.cc or -inl.h from filename.
2003
>>> _DropCommonSuffixes('foo/foo-inl.h')
2005
>>> _DropCommonSuffixes('foo/bar/foo.cc')
2007
>>> _DropCommonSuffixes('foo/foo_internal.h')
2009
>>> _DropCommonSuffixes('foo/foo_unusualinternal.h')
2010
'foo/foo_unusualinternal'
2013
filename: The input filename.
2016
The filename with the common suffix removed.
2018
for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
2019
'inl.h', 'impl.h', 'internal.h'):
2020
if (filename.endswith(suffix) and len(filename) > len(suffix) and
2021
filename[-len(suffix) - 1] in ('-', '_')):
2022
return filename[:-len(suffix) - 1]
2023
return os.path.splitext(filename)[0]
2026
def _IsTestFilename(filename):
2027
"""Determines if the given filename has a suffix that identifies it as a test.
2030
filename: The input filename.
2033
True if 'filename' looks like a test, False otherwise.
2035
if (filename.endswith('_test.cc') or
2036
filename.endswith('_unittest.cc') or
2037
filename.endswith('_regtest.cc')):
2043
def _ClassifyInclude(fileinfo, include, is_system):
2044
"""Figures out what kind of header 'include' is.
2047
fileinfo: The current file cpplint is running over. A FileInfo instance.
2048
include: The path to a #included file.
2049
is_system: True if the #include used <> rather than "".
2052
One of the _XXX_HEADER constants.
2055
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
2057
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
2059
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
2061
>>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
2062
... 'bar/foo_other_ext.h', False)
2064
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
2067
# This is a list of all standard c++ header files, except
2068
# those already checked for above.
2069
is_stl_h = include in _STL_HEADERS
2070
is_cpp_h = is_stl_h or include in _CPP_HEADERS
2074
return _CPP_SYS_HEADER
2076
return _C_SYS_HEADER
2078
# If the target file and the include we're checking share a
2079
# basename when we drop common extensions, and the include
2080
# lives in . , then it's likely to be owned by the target file.
2081
target_dir, target_base = (
2082
os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
2083
include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
2084
if target_base == include_base and (
2085
include_dir == target_dir or
2086
include_dir == os.path.normpath(target_dir + '/../public')):
2087
return _LIKELY_MY_HEADER
2089
# If the target and include share some initial basename
2090
# component, it's possible the target is implementing the
2091
# include, so it's allowed to be first, but we'll never
2092
# complain if it's not there.
2093
target_first_component = _RE_FIRST_COMPONENT.match(target_base)
2094
include_first_component = _RE_FIRST_COMPONENT.match(include_base)
2095
if (target_first_component and include_first_component and
2096
target_first_component.group(0) ==
2097
include_first_component.group(0)):
2098
return _POSSIBLE_MY_HEADER
2100
return _OTHER_HEADER
2104
def CheckGlobalInclude(filename, clean_lines, linenum, include_state, error):
2105
"""Check rules that are applicable to #include lines.
2107
global.h, config.h and server_includes.h should NEVER be included in headers
2108
unless those headers end in _priv and therefore are private headers.
2111
filename: The name of the current file.
2112
clean_lines: A CleansedLines instance containing the file.
2113
linenum: The number of the line to check.
2114
include_state: An _IncludeState instance in which the headers are inserted.
2115
error: The function to call with any errors found.
2117
if filename.endswith("config.h") or filename.endswith("global.h") or filename.endswith("server_includes.h") or filename.endswith("_priv.h") or not filename.endswith(".h"):
2120
fileinfo = FileInfo(filename)
2122
line = clean_lines.lines[linenum]
2124
match = _RE_PATTERN_INCLUDE.search(line)
2126
include = match.group(2)
2127
if Match(r'(config|global|server_includes|_priv)\.h$', include):
2128
error(filename, linenum, 'build/include_config', 4,
2129
'Do not include config.h or files that include config.h in .h files')
2131
def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
2132
"""Check rules that are applicable to #include lines.
2134
Strings on #include lines are NOT removed from elided line, to make
2135
certain tasks easier. However, to prevent false positives, checks
2136
applicable to #include lines in CheckLanguage must be put here.
2139
filename: The name of the current file.
2140
clean_lines: A CleansedLines instance containing the file.
2141
linenum: The number of the line to check.
2142
include_state: An _IncludeState instance in which the headers are inserted.
2143
error: The function to call with any errors found.
2145
fileinfo = FileInfo(filename)
2147
line = clean_lines.lines[linenum]
2149
# "include" should use the new style "foo/bar.h" instead of just "bar.h"
2150
if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
2151
error(filename, linenum, 'build/include', 4,
2152
'Include the directory when naming .h files')
2154
# we shouldn't include a file more than once. actually, there are a
2155
# handful of instances where doing so is okay, but in general it's
2157
match = _RE_PATTERN_INCLUDE.search(line)
2159
include = match.group(2)
2160
is_system = (match.group(1) == '<')
2161
if include in include_state:
2162
error(filename, linenum, 'build/include', 4,
2163
'"%s" already included at %s:%s' %
2164
(include, filename, include_state[include]))
2166
include_state[include] = linenum
2168
# We want to ensure that headers appear in the right order:
2169
# 1) for foo.cc, foo.h (preferred location)
2171
# 3) cpp system files
2172
# 4) for foo.cc, foo.h (deprecated location)
2173
# 5) other google headers
2175
# We classify each include statement as one of those 5 types
2176
# using a number of techniques. The include_state object keeps
2177
# track of the highest type seen, and complains if we see a
2178
# lower type after that.
2179
error_message = include_state.CheckNextIncludeOrder(
2180
_ClassifyInclude(fileinfo, include, is_system))
2182
error(filename, linenum, 'build/include_order', 4,
2183
'%s. Should be: %s.h, c system, c++ system, other.' %
2184
(error_message, fileinfo.BaseName()))
2186
# Look for any of the stream classes that are part of standard C++.
2187
match = _RE_PATTERN_INCLUDE.match(line)
2189
include = match.group(2)
2190
if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
2191
# Many unit tests use cout, so we exempt them.
2192
if not _IsTestFilename(filename):
2193
error(filename, linenum, 'readability/streams', 3,
2194
'Streams are highly discouraged.')
2196
def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state,
2198
"""Checks rules from the 'C++ language rules' section of cppguide.html.
2200
Some of these rules are hard to test (function overloading, using
2201
uint32 inappropriately), but we do the best we can.
2204
filename: The name of the current file.
2205
clean_lines: A CleansedLines instance containing the file.
2206
linenum: The number of the line to check.
2207
file_extension: The extension (without the dot) of the filename.
2208
include_state: An _IncludeState instance in which the headers are inserted.
2209
error: The function to call with any errors found.
2211
# If the line is empty or consists of entirely a comment, no need to
2213
line = clean_lines.elided[linenum]
2217
match = _RE_PATTERN_INCLUDE.search(line)
2219
CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
2220
CheckGlobalInclude(filename, clean_lines, linenum, include_state, error)
2223
# Create an extended_line, which is the concatenation of the current and
2224
# next lines, for more effective checking of code that may span more than one
2226
if linenum + 1 < clean_lines.NumLines():
2227
extended_line = line + clean_lines.elided[linenum + 1]
2229
extended_line = line
2231
# Make Windows paths like Unix.
2232
fullname = os.path.abspath(filename).replace('\\', '/')
2234
# TODO(unknown): figure out if they're using default arguments in fn proto.
2236
# Check to see if they're using an conversion function cast.
2237
# I just try to capture the most common basic types, though there are more.
2238
# Parameterless conversion functions, such as bool(), are allowed as they are
2239
# probably a member operator declaration or default constructor.
2241
r'\b(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
2243
# gMock methods are defined using some variant of MOCK_METHODx(name, type)
2244
# where type may be float(), int(string), etc. Without context they are
2245
# virtually indistinguishable from int(x) casts.
2246
if not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line):
2247
error(filename, linenum, 'readability/casting', 4,
2248
'Using deprecated casting style. '
2249
'Use static_cast<%s>(...) instead' %
2252
CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2254
r'\((int|float|double|bool|char|u?int(16|32|64))\)',
2256
# This doesn't catch all cases. Consider (const char * const)"hello".
2257
CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2258
'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
2260
# In addition, we look for people taking the address of a cast. This
2261
# is dangerous -- casts can assign to temporaries, so the pointer doesn't
2262
# point where you think.
2264
r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
2265
error(filename, linenum, 'runtime/casting', 4,
2266
('Are you taking an address of a cast? '
2267
'This is dangerous: could be a temp var. '
2268
'Take the address before doing the cast, rather than after'))
2270
# Check for people declaring static/global STL strings at the top level.
2271
# This is dangerous because the C++ language does not guarantee that
2272
# globals with constructors are initialized before the first access.
2274
r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
2276
# Make sure it's not a function.
2277
# Function template specialization looks like: "string foo<Type>(...".
2278
# Class template definitions look like: "string Foo<Type>::Method(...".
2279
if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)',
2281
error(filename, linenum, 'runtime/string', 4,
2282
'For a static/global string constant, use a C style string instead: '
2284
(match.group(1), match.group(2)))
2286
# Check that we're not using RTTI outside of testing code.
2287
if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename):
2288
error(filename, linenum, 'runtime/rtti', 5,
2289
'Do not use dynamic_cast<>. If you need to cast within a class '
2290
"hierarchy, use static_cast<> to upcast. Google doesn't support "
2293
if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
2294
error(filename, linenum, 'runtime/init', 4,
2295
'You seem to be initializing a member variable with itself.')
2297
if file_extension == 'h':
2298
# TODO(unknown): check that 1-arg constructors are explicit.
2299
# How to tell it's a constructor?
2300
# (handled in CheckForNonStandardConstructs for now)
2301
# TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
2305
# Check if people are using the verboten C basic types. The only exception
2306
# we regularly allow is "unsigned short port" for port.
2307
if Search(r'\bshort port\b', line):
2308
if not Search(r'\bunsigned short port\b', line):
2309
error(filename, linenum, 'runtime/int', 4,
2310
'Use "unsigned short" for ports, not "short"')
2312
match = Search(r'\b(short|long(?! +double)|long long)\b', line)
2314
error(filename, linenum, 'runtime/int', 4,
2315
'Use int16/int64/etc, rather than the C type %s' % match.group(1))
2317
# When snprintf is used, the second argument shouldn't be a literal.
2318
match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
2320
error(filename, linenum, 'runtime/printf', 3,
2321
'If you can, use sizeof(%s) instead of %s as the 2nd arg '
2322
'to snprintf.' % (match.group(1), match.group(2)))
2324
# Check if some verboten C functions are being used.
2325
if Search(r'\bsprintf\b', line):
2326
error(filename, linenum, 'runtime/printf', 5,
2327
'Never use sprintf. Use snprintf instead.')
2328
match = Search(r'\b(strcpy|strcat)\b', line)
2330
error(filename, linenum, 'runtime/printf', 4,
2331
'Almost always, snprintf is better than %s' % match.group(1))
2333
if Search(r'\bsscanf\b', line):
2334
error(filename, linenum, 'runtime/printf', 1,
2335
'sscanf can be ok, but is slow and can overflow buffers.')
2337
# Check for suspicious usage of "if" like
2339
if Search(r'\}\s*if\s*\(', line):
2340
error(filename, linenum, 'readability/braces', 4,
2341
'Did you mean "else if"? If not, start a new line for "if".')
2343
# Check for potential format string bugs like printf(foo).
2344
# We constrain the pattern not to pick things like DocidForPrintf(foo).
2345
# Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
2346
match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I)
2348
error(filename, linenum, 'runtime/printf', 4,
2349
'Potential format string bug. Do %s("%%s", %s) instead.'
2350
% (match.group(1), match.group(2)))
2352
# Check for potential memset bugs like memset(buf, sizeof(buf), 0).
2353
match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
2354
if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
2355
error(filename, linenum, 'runtime/memset', 4,
2356
'Did you mean "memset(%s, 0, %s)"?'
2357
% (match.group(1), match.group(2)))
2359
if Search(r'\busing namespace\b', line) and filename.endswith(".h"):
2360
error(filename, linenum, 'build/namespaces', 5,
2361
'Do not use namespace using-directives in headers. ')
2363
# Detect variable-length arrays.
2364
match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
2365
if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
2366
match.group(3).find(']') == -1):
2367
# Split the size using space and arithmetic operators as delimiters.
2368
# If any of the resulting tokens are not compile time constants then
2370
tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
2378
if Search(r'sizeof\(.+\)', tok): continue
2379
if Search(r'arraysize\(\w+\)', tok): continue
2381
tok = tok.lstrip('(')
2382
tok = tok.rstrip(')')
2383
if not tok: continue
2384
if Match(r'\d+', tok): continue
2385
if Match(r'0[xX][0-9a-fA-F]+', tok): continue
2386
if Match(r'k[A-Z0-9]\w*', tok): continue
2387
if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
2388
if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
2389
# A catch all for tricky sizeof cases, including 'sizeof expression',
2390
# 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
2391
# requires skipping the next token becasue we split on ' ' and '*'.
2392
if tok.startswith('sizeof'):
2398
error(filename, linenum, 'runtime/arrays', 1,
2399
'Do not use variable-length arrays. Use an appropriately named '
2400
"('k' followed by CamelCase) compile-time constant for the size.")
2402
# If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or
2403
# DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing
2404
# in the class declaration.
2407
r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'
2410
if match and linenum + 1 < clean_lines.NumLines():
2411
next_line = clean_lines.elided[linenum + 1]
2412
if not Search(r'^\s*};', next_line):
2413
error(filename, linenum, 'readability/constructors', 3,
2414
match.group(1) + ' should be the last thing in the class')
2416
# Check for use of unnamed namespaces in header files. Registration
2417
# macros are typically OK, so we allow use of "namespace {" on lines
2418
# that end with backslashes.
2419
if (file_extension == 'h'
2420
and Search(r'\bnamespace\s*{', line)
2421
and line[-1] != '\\'):
2422
error(filename, linenum, 'build/namespaces', 4,
2423
'Do not use unnamed namespaces in header files. See '
2424
'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2425
' for more information.')
2428
def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
2430
"""Checks for a C-style cast by looking for the pattern.
2432
This also handles sizeof(type) warnings, due to similarity of content.
2435
filename: The name of the current file.
2436
linenum: The number of the line to check.
2437
line: The line of code to check.
2438
raw_line: The raw line of code to check, with comments.
2439
cast_type: The string for the C++ cast to recommend. This is either
2440
reinterpret_cast or static_cast, depending.
2441
pattern: The regular expression used to find C-style casts.
2442
error: The function to call with any errors found.
2444
match = Search(pattern, line)
2449
sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
2451
error(filename, linenum, 'runtime/sizeof', 1,
2452
'Using sizeof(type). Use sizeof(varname) instead if possible')
2455
remainder = line[match.end(0):]
2457
# The close paren is for function pointers as arguments to a function.
2458
# eg, void foo(void (*bar)(int));
2459
# The semicolon check is a more basic function check; also possibly a
2460
# function pointer typedef.
2461
# eg, void foo(int); or void foo(int) const;
2462
# The equals check is for function pointer assignment.
2463
# eg, void *(*foo)(int) = ...
2465
# Right now, this will only catch cases where there's a single argument, and
2466
# it's unnamed. It should probably be expanded to check for multiple
2467
# arguments with some unnamed.
2468
function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder)
2470
if (not function_match.group(3) or
2471
function_match.group(3) == ';' or
2472
raw_line.find('/*') < 0):
2473
error(filename, linenum, 'readability/function', 3,
2474
'All parameters should be named in a function')
2477
# At this point, all that should be left is actual casts.
2478
error(filename, linenum, 'readability/casting', 4,
2479
'Using C-style cast. Use %s<%s>(...) instead' %
2480
(cast_type, match.group(1)))
2483
_HEADERS_CONTAINING_TEMPLATES = (
2484
('<deque>', ('deque',)),
2485
('<functional>', ('unary_function', 'binary_function',
2486
'plus', 'minus', 'multiplies', 'divides', 'modulus',
2488
'equal_to', 'not_equal_to', 'greater', 'less',
2489
'greater_equal', 'less_equal',
2490
'logical_and', 'logical_or', 'logical_not',
2491
'unary_negate', 'not1', 'binary_negate', 'not2',
2492
'bind1st', 'bind2nd',
2493
'pointer_to_unary_function',
2494
'pointer_to_binary_function',
2496
'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
2498
'const_mem_fun_t', 'const_mem_fun1_t',
2499
'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
2502
('<limits>', ('numeric_limits',)),
2503
('<list>', ('list',)),
2504
('<map>', ('map', 'multimap',)),
2505
('<memory>', ('allocator',)),
2506
('<queue>', ('queue', 'priority_queue',)),
2507
('<set>', ('set', 'multiset',)),
2508
('<stack>', ('stack',)),
2509
('<string>', ('char_traits', 'basic_string',)),
2510
('<utility>', ('pair',)),
2511
('<vector>', ('vector',)),
2514
# Note: std::hash is their hash, ::hash is our hash
2515
('<hash_map>', ('hash_map', 'hash_multimap',)),
2516
('<hash_set>', ('hash_set', 'hash_multiset',)),
2517
('<slist>', ('slist',)),
2520
_HEADERS_ACCEPTED_BUT_NOT_PROMOTED = {
2521
# We can trust with reasonable confidence that map gives us pair<>, too.
2522
'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap')
2525
_RE_PATTERN_STRING = re.compile(r'\bstring\b')
2527
_re_pattern_algorithm_header = []
2528
for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
2530
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
2532
_re_pattern_algorithm_header.append(
2533
(re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
2537
_re_pattern_templates = []
2538
for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
2539
for _template in _templates:
2540
_re_pattern_templates.append(
2541
(re.compile(r'(\<|\b)' + _template + r'\s*\<'),
2546
def FilesBelongToSameModule(filename_cc, filename_h):
2547
"""Check if these two filenames belong to the same module.
2549
The concept of a 'module' here is a as follows:
2550
foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the
2551
same 'module' if they are in the same directory.
2552
some/path/public/xyzzy and some/path/internal/xyzzy are also considered
2553
to belong to the same module here.
2555
If the filename_cc contains a longer path than the filename_h, for example,
2556
'/absolute/path/to/base/sysinfo.cc', and this file would include
2557
'base/sysinfo.h', this function also produces the prefix needed to open the
2558
header. This is used by the caller of this function to more robustly open the
2559
header file. We don't have access to the real include paths in this context,
2560
so we need this guesswork here.
2562
Known bugs: tools/base/bar.cc and base/bar.h belong to the same module
2563
according to this implementation. Because of this, this function gives
2564
some false positives. This should be sufficiently rare in practice.
2567
filename_cc: is the path for the .cc file
2568
filename_h: is the path for the header path
2571
Tuple with a bool and a string:
2572
bool: True if filename_cc and filename_h belong to the same module.
2573
string: the additional prefix needed to open the header file.
2576
if not filename_cc.endswith('.cc'):
2578
filename_cc = filename_cc[:-len('.cc')]
2579
if filename_cc.endswith('_unittest'):
2580
filename_cc = filename_cc[:-len('_unittest')]
2581
elif filename_cc.endswith('_test'):
2582
filename_cc = filename_cc[:-len('_test')]
2583
filename_cc = filename_cc.replace('/public/', '/')
2584
filename_cc = filename_cc.replace('/internal/', '/')
2586
if not filename_h.endswith('.h'):
2588
filename_h = filename_h[:-len('.h')]
2589
if filename_h.endswith('-inl'):
2590
filename_h = filename_h[:-len('-inl')]
2591
filename_h = filename_h.replace('/public/', '/')
2592
filename_h = filename_h.replace('/internal/', '/')
2594
files_belong_to_same_module = filename_cc.endswith(filename_h)
2596
if files_belong_to_same_module:
2597
common_path = filename_cc[:-len(filename_h)]
2598
return files_belong_to_same_module, common_path
2601
def UpdateIncludeState(filename, include_state, io=codecs):
2602
"""Fill up the include_state with new includes found from the file.
2605
filename: the name of the header to read.
2606
include_state: an _IncludeState instance in which the headers are inserted.
2607
io: The io factory to use to read the file. Provided for testability.
2610
True if a header was succesfully added. False otherwise.
2614
headerfile = io.open(filename, 'r', 'utf8', 'replace')
2617
_cpplint_state.seen_file(filename)
2619
for line in headerfile:
2621
clean_line = CleanseComments(line)
2622
match = _RE_PATTERN_INCLUDE.search(clean_line)
2624
include = match.group(2)
2625
# The value formatting is cute, but not really used right now.
2626
# What matters here is that the key is in include_state.
2627
include_state.setdefault(include, '%s:%d' % (filename, linenum))
2631
def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
2633
"""Reports for missing stl includes.
2635
This function will output warnings to make sure you are including the headers
2636
necessary for the stl containers and functions that you use. We only give one
2637
reason to include a header. For example, if you use both equal_to<> and
2638
less<> in a .h file, only one (the latter in the file) of these will be
2639
reported as a reason to include the <functional>.
2642
filename: The name of the current file.
2643
clean_lines: A CleansedLines instance containing the file.
2644
include_state: An _IncludeState instance.
2645
error: The function to call with any errors found.
2646
io: The IO factory to use to read the header file. Provided for unittest
2649
required = {} # A map of header name to linenumber and the template entity.
2650
# Example of required: { '<functional>': (1219, 'less<>') }
2652
for linenum in xrange(clean_lines.NumLines()):
2653
line = clean_lines.elided[linenum]
2654
if not line or line[0] == '#':
2657
# String is special -- it is a non-templatized type in STL.
2658
if _RE_PATTERN_STRING.search(line):
2659
required['<string>'] = (linenum, 'string')
2661
for pattern, template, header in _re_pattern_algorithm_header:
2662
if pattern.search(line):
2663
required[header] = (linenum, template)
2665
# The following function is just a speed up, no semantics are changed.
2666
if not '<' in line: # Reduces the cpu time usage by skipping lines.
2669
for pattern, template, header in _re_pattern_templates:
2670
if pattern.search(line):
2671
required[header] = (linenum, template)
2673
# The policy is that if you #include something in foo.h you don't need to
2674
# include it again in foo.cc. Here, we will look at possible includes.
2675
# Let's copy the include_state so it is only messed up within this function.
2676
include_state = include_state.copy()
2678
# Did we find the header for this file (if any) and succesfully load it?
2679
header_found = False
2681
# Use the absolute path so that matching works properly.
2682
abs_filename = os.path.abspath(filename)
2684
# For Emacs's flymake.
2685
# If cpplint is invoked from Emacs's flymake, a temporary file is generated
2686
# by flymake and that file name might end with '_flymake.cc'. In that case,
2687
# restore original file name here so that the corresponding header file can be
2689
# e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
2690
# instead of 'foo_flymake.h'
2691
emacs_flymake_suffix = '_flymake.cc'
2692
if abs_filename.endswith(emacs_flymake_suffix):
2693
abs_filename = abs_filename[:-len(emacs_flymake_suffix)] + '.cc'
2695
# include_state is modified during iteration, so we iterate over a copy of
2697
for header in include_state.keys(): #NOLINT
2698
(same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
2699
fullpath = common_path + header
2700
if same_module and UpdateIncludeState(fullpath, include_state, io):
2703
# If we can't find the header file for a .cc, assume it's because we don't
2704
# know where to look. In that case we'll give up as we're not sure they
2705
# didn't include it in the .h file.
2706
# TODO(unknown): Do a better job of finding .h files so we are confident that
2707
# not having the .h file means there isn't one.
2708
if filename.endswith('.cc') and not header_found:
2711
# All the lines have been processed, report the errors found.
2712
for required_header_unstripped in required:
2713
template = required[required_header_unstripped][1]
2714
if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED:
2715
headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template]
2716
if [True for header in headers if header in include_state]:
2718
if required_header_unstripped.strip('<>"') not in include_state:
2719
error(filename, required[required_header_unstripped][0],
2720
'build/include_what_you_use', 4,
2721
'Add #include ' + required_header_unstripped + ' for ' + template)
2724
def ProcessLine(filename, file_extension,
2725
clean_lines, line, include_state, function_state,
2726
class_state, error):
2727
"""Processes a single line in the file.
2730
filename: Filename of the file that is being processed.
2731
file_extension: The extension (dot not included) of the file.
2732
clean_lines: An array of strings, each representing a line of the file,
2733
with comments stripped.
2734
line: Number of line being processed.
2735
include_state: An _IncludeState instance in which the headers are inserted.
2736
function_state: A _FunctionState instance which counts function lines, etc.
2737
class_state: A _ClassState instance which maintains information about
2738
the current stack of nested class declarations being parsed.
2739
error: A callable to which errors are reported, which takes 4 arguments:
2740
filename, line number, error level, and message
2743
raw_lines = clean_lines.raw_lines
2744
CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
2745
if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines
2747
CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
2748
CheckStyle(filename, clean_lines, line, file_extension, error)
2749
CheckLanguage(filename, clean_lines, line, file_extension, include_state,
2751
CheckForNonStandardConstructs(filename, clean_lines, line,
2753
CheckPosixThreading(filename, clean_lines, line, error)
2754
CheckInvalidIncrement(filename, clean_lines, line, error)
2757
def ProcessFileData(filename, file_extension, lines, error):
2758
"""Performs lint checks and reports any errors to the given error function.
2761
filename: Filename of the file that is being processed.
2762
file_extension: The extension (dot not included) of the file.
2763
lines: An array of strings, each representing a line of the file, with the
2764
last element being empty if the file is termined with a newline.
2765
error: A callable to which errors are reported, which takes 4 arguments:
2767
lines = (['// marker so line numbers and indices both start at 1'] + lines +
2768
['// marker so line numbers end in a known way'])
2770
include_state = _IncludeState()
2771
function_state = _FunctionState()
2772
class_state = _ClassState()
2774
CheckForCopyright(filename, lines, error)
2776
if file_extension == 'h':
2777
CheckForHeaderGuard(filename, lines, error)
2779
RemoveMultiLineComments(filename, lines, error)
2780
clean_lines = CleansedLines(lines)
2781
for line in xrange(clean_lines.NumLines()):
2782
ProcessLine(filename, file_extension, clean_lines, line,
2783
include_state, function_state, class_state, error)
2784
class_state.CheckFinished(filename, error)
2786
CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
2788
# We check here rather than inside ProcessLine so that we see raw
2789
# lines rather than "cleaned" lines.
2790
CheckForUnicodeReplacementCharacters(filename, lines, error)
2792
CheckForNewlineAtEOF(filename, lines, error)
2795
def ProcessFile(filename, vlevel):
2796
"""Does google-lint on a single file.
2799
filename: The name of the file to parse.
2801
vlevel: The level of errors to report. Every error of confidence
2802
>= verbose_level will be reported. 0 is a good default.
2805
_SetVerboseLevel(vlevel)
2808
# Support the UNIX convention of using "-" for stdin. Note that
2809
# we are not opening the file with universal newline support
2810
# (which codecs doesn't support anyway), so the resulting lines do
2811
# contain trailing '\r' characters if we are reading a file that
2813
# If after the split a trailing '\r' is present, it is removed
2814
# below. If it is not expected to be present (i.e. os.linesep !=
2815
# '\r\n' as in Windows), a warning is issued below if this file
2819
lines = codecs.StreamReaderWriter(sys.stdin,
2820
codecs.getreader('utf8'),
2821
codecs.getwriter('utf8'),
2822
'replace').read().split('\n')
2824
_cpplint_state.seen_file(filename)
2825
lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
2827
carriage_return_found = False
2828
# Remove trailing '\r'.
2829
for linenum in range(len(lines)):
2830
if lines[linenum].endswith('\r'):
2831
lines[linenum] = lines[linenum].rstrip('\r')
2832
carriage_return_found = True
2836
"Skipping input '%s': Can't open for reading\n" % filename)
2839
# Note, if no dot is found, this will give the entire filename as the ext.
2840
file_extension = filename[filename.rfind('.') + 1:]
2842
# When reading from stdin, the extension is unknown, so no cpplint tests
2843
# should rely on the extension.
2844
if (filename != '-' and file_extension != 'cc' and file_extension != 'h'
2845
and file_extension != 'cpp'):
2846
sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename)
2848
ProcessFileData(filename, file_extension, lines, Error)
2849
if carriage_return_found and os.linesep != '\r\n':
2850
# Use 0 for linenum since outputing only one error for potentially
2852
Error(filename, 0, 'whitespace/newline', 1,
2853
'One or more unexpected \\r (^M) found;'
2854
'better to use only a \\n')
2856
sys.stderr.write('Done processing %s\n' % filename)
2859
def PrintUsage(message):
2860
"""Prints a brief usage string and exits, optionally with an error message.
2863
message: The optional error message.
2865
sys.stderr.write(_USAGE)
2867
sys.exit('\nFATAL ERROR: ' + message)
2872
def PrintCategories():
2873
"""Prints a list of all the error-categories used by error messages.
2875
These are the categories used to filter messages via --filter.
2877
sys.stderr.write(_ERROR_CATEGORIES)
2881
def ParseArguments(args):
2882
"""Parses the command line arguments.
2884
This may set the output format and verbosity level as side-effects.
2887
args: The command line arguments:
2890
The list of filenames to lint.
2893
(opts, filenames) = getopt.getopt(args, '',
2894
['help', 'output=', 'verbose=', 'deps=', 'filter='])
2895
except getopt.GetoptError:
2896
PrintUsage('Invalid arguments.')
2898
verbosity = _VerboseLevel()
2899
output_format = _OutputFormat()
2902
for (opt, val) in opts:
2905
elif opt == '--output':
2906
if not val in ('emacs', 'vs7'):
2907
PrintUsage('The only allowed output formats are emacs and vs7.')
2909
elif opt == '--verbose':
2910
verbosity = int(val)
2911
elif opt == '--filter':
2915
elif opt == '--deps':
2916
_cpplint_state.depfilename = val
2919
PrintUsage('No files were specified.')
2921
_SetOutputFormat(output_format)
2922
_SetVerboseLevel(verbosity)
2923
_SetFilters(filters)
2929
filenames = ParseArguments(sys.argv[1:])
2931
# Change stderr to write with replacement characters so we don't die
2932
# if we try to print something containing non-ASCII characters.
2933
sys.stderr = codecs.StreamReaderWriter(sys.stderr,
2934
codecs.getreader('utf8'),
2935
codecs.getwriter('utf8'),
2938
_cpplint_state.ResetErrorCount()
2939
for filename in filenames:
2940
ProcessFile(filename, _cpplint_state.verbose_level)
2941
_cpplint_state.finished()
2942
sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count)
2943
sys.exit(_cpplint_state.error_count > 0)
2946
if __name__ == '__main__':