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
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] [--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
Specify a comma-separated list of category-filters to apply: only
105
error messages whose category names pass the filters will be printed.
106
(Category names are printed with the message and look like
107
"[whitespace/indent]".) Filters are evaluated left to right.
108
"-FOO" and "FOO" means "do not print categories that start with FOO".
109
"+FOO" means "do print categories that start with FOO".
111
Examples: --filter=-whitespace,+whitespace/braces
112
--filter=whitespace,runtime/printf,+runtime/printf_format
113
--filter=-,+build/include_what_you_use
115
To see a list of all the categories used in cpplint, pass no arg:
119
# We categorize each error message we print. Here are the categories.
120
# We want an explicit list so we can list them all in cpplint --filter=.
121
# If you add a new error message with a new category, add it to the list
122
# here! cpplint_unittest.py should tell you if you forget to do this.
123
# \ used for clearer layout -- pylint: disable-msg=C6013
124
_ERROR_CATEGORIES = '''\
133
build/include_what_you_use
141
readability/constructors
144
readability/multiline_comment
145
readability/multiline_string
154
runtime/invalid_increment
157
runtime/printf_format
162
runtime/threadsafe_fn
164
whitespace/blank_line
168
whitespace/end_of_line
169
whitespace/ending_newline
172
whitespace/line_length
181
# The default state of the category filter. This is overrided by the --filter=
182
# flag. By default all errors are on, so only add here categories that should be
183
# off by default (i.e., categories that must be enabled by the --filter= flags).
184
# All entries here should start with a '-' or '+', as in the --filter= flag.
185
_DEFAULT_FILTERS = []
187
# We used to check for high-bit characters, but after much discussion we
188
# decided those were OK, as long as they were in UTF-8 and didn't represent
189
# hard-coded international strings, which belong in a seperate i18n file.
191
# Headers that we consider STL headers.
192
_STL_HEADERS = frozenset([
193
'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
194
'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
195
'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h',
196
'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
197
'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
198
'utility', 'vector', 'vector.h',
202
# Non-STL C++ system headers.
203
_CPP_HEADERS = frozenset([
204
'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
205
'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
206
'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
207
'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
208
'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
209
'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
210
'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h',
211
'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
212
'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h',
213
'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h',
214
'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
215
'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
216
'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
220
# Assertion macros. These are defined in base/logging.h and
221
# testing/base/gunit.h. Note that the _M versions need to come first
222
# for substring matching to work.
225
'EXPECT_TRUE_M', 'EXPECT_TRUE',
226
'ASSERT_TRUE_M', 'ASSERT_TRUE',
227
'EXPECT_FALSE_M', 'EXPECT_FALSE',
228
'ASSERT_FALSE_M', 'ASSERT_FALSE',
231
# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
232
_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
234
for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
235
('>=', 'GE'), ('>', 'GT'),
236
('<=', 'LE'), ('<', 'LT')]:
237
_CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
238
_CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
239
_CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
240
_CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
241
_CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
242
_CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
244
for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
245
('>=', 'LT'), ('>', 'LE'),
246
('<=', 'GT'), ('<', 'GE')]:
247
_CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
248
_CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
249
_CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
250
_CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
253
# These constants define types of headers for use with
254
# _IncludeState.CheckNextIncludeOrder().
257
_LIKELY_MY_HEADER = 3
258
_POSSIBLE_MY_HEADER = 4
262
_regexp_compile_cache = {}
265
def Match(pattern, s):
266
"""Matches the string with the pattern, caching the compiled regexp."""
267
# The regexp compilation caching is inlined in both Match and Search for
268
# performance reasons; factoring it out into a separate function turns out
269
# to be noticeably expensive.
270
if not pattern in _regexp_compile_cache:
271
_regexp_compile_cache[pattern] = sre_compile.compile(pattern)
272
return _regexp_compile_cache[pattern].match(s)
275
def Search(pattern, s):
276
"""Searches the string for the pattern, caching the compiled regexp."""
277
if not pattern in _regexp_compile_cache:
278
_regexp_compile_cache[pattern] = sre_compile.compile(pattern)
279
return _regexp_compile_cache[pattern].search(s)
282
class _IncludeState(dict):
283
"""Tracks line numbers for includes, and the order in which includes appear.
285
As a dict, an _IncludeState object serves as a mapping between include
286
filename and line number on which that file was included.
288
Call CheckNextIncludeOrder() once for each header in the file, passing
289
in the type constants defined above. Calls in an illegal order will
290
raise an _IncludeError with an appropriate error message.
293
# self._section will move monotonically through this set. If it ever
294
# needs to move backwards, CheckNextIncludeOrder will raise an error.
302
_C_SYS_HEADER: 'C system header',
303
_CPP_SYS_HEADER: 'C++ system header',
304
_LIKELY_MY_HEADER: 'header this file implements',
305
_POSSIBLE_MY_HEADER: 'header this file may implement',
306
_OTHER_HEADER: 'other header',
309
_INITIAL_SECTION: "... nothing. (This can't be an error.)",
310
_MY_H_SECTION: 'a header this file implements',
311
_C_SECTION: 'C system header',
312
_CPP_SECTION: 'C++ system header',
313
_OTHER_H_SECTION: 'other header',
318
self._section = self._INITIAL_SECTION
320
def CheckNextIncludeOrder(self, header_type):
321
"""Returns a non-empty error message if the next header is out of order.
323
This function also updates the internal state to be ready to check
327
header_type: One of the _XXX_HEADER constants defined above.
330
The empty string if the header is in the right order, or an
331
error message describing what's wrong.
334
error_message = ('Found %s after %s' %
335
(self._TYPE_NAMES[header_type],
336
self._SECTION_NAMES[self._section]))
338
if header_type == _C_SYS_HEADER:
339
if self._section <= self._C_SECTION:
340
self._section = self._C_SECTION
343
elif header_type == _CPP_SYS_HEADER:
344
if self._section <= self._CPP_SECTION:
345
self._section = self._CPP_SECTION
348
elif header_type == _LIKELY_MY_HEADER:
349
if self._section <= self._MY_H_SECTION:
350
self._section = self._MY_H_SECTION
352
self._section = self._OTHER_H_SECTION
353
elif header_type == _POSSIBLE_MY_HEADER:
354
if self._section <= self._MY_H_SECTION:
355
self._section = self._MY_H_SECTION
357
# This will always be the fallback because we're not sure
358
# enough that the header is associated with this file.
359
self._section = self._OTHER_H_SECTION
361
assert header_type == _OTHER_HEADER
362
self._section = self._OTHER_H_SECTION
367
class _CppLintState(object):
368
"""Maintains module-wide state.."""
371
self.verbose_level = 1 # global setting.
372
self.error_count = 0 # global count of reported errors
373
# filters to apply when emitting error messages
374
self.filters = _DEFAULT_FILTERS[:]
377
# "emacs" - format that emacs can parse (default)
378
# "vs7" - format that Microsoft Visual Studio 7 can parse
379
self.output_format = 'emacs'
381
def SetOutputFormat(self, output_format):
382
"""Sets the output format for errors."""
383
self.output_format = output_format
385
def SetVerboseLevel(self, level):
386
"""Sets the module's verbosity, and returns the previous setting."""
387
last_verbose_level = self.verbose_level
388
self.verbose_level = level
389
return last_verbose_level
391
def SetFilters(self, filters):
392
"""Sets the error-message filters.
394
These filters are applied when deciding whether to emit a given
398
filters: A string of comma-separated filters (eg "+whitespace/indent").
399
Each filter should start with + or -; else we die.
402
ValueError: The comma-separated filters did not all start with '+' or '-'.
403
E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
405
# Default filters always have less priority than the flag ones.
406
self.filters = _DEFAULT_FILTERS[:]
407
for filt in filters.split(','):
408
clean_filt = filt.strip()
410
self.filters.append(clean_filt)
411
for filt in self.filters:
412
if not (filt.startswith('+') or filt.startswith('-')):
413
raise ValueError('Every filter in --filters must start with + or -'
414
' (%s does not)' % filt)
416
def ResetErrorCount(self):
417
"""Sets the module's error statistic back to zero."""
420
def IncrementErrorCount(self):
421
"""Bumps the module's error statistic."""
422
self.error_count += 1
425
_cpplint_state = _CppLintState()
429
"""Gets the module's output format."""
430
return _cpplint_state.output_format
433
def _SetOutputFormat(output_format):
434
"""Sets the module's output format."""
435
_cpplint_state.SetOutputFormat(output_format)
439
"""Returns the module's verbosity setting."""
440
return _cpplint_state.verbose_level
443
def _SetVerboseLevel(level):
444
"""Sets the module's verbosity, and returns the previous setting."""
445
return _cpplint_state.SetVerboseLevel(level)
449
"""Returns the module's list of output filters, as a list."""
450
return _cpplint_state.filters
453
def _SetFilters(filters):
454
"""Sets the module's error-message filters.
456
These filters are applied when deciding whether to emit a given
460
filters: A string of comma-separated filters (eg "whitespace/indent").
461
Each filter should start with + or -; else we die.
463
_cpplint_state.SetFilters(filters)
466
class _FunctionState(object):
467
"""Tracks current function name and the number of lines in its body."""
469
_NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc.
470
_TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER.
473
self.in_a_function = False
474
self.lines_in_function = 0
475
self.current_function = ''
477
def Begin(self, function_name):
478
"""Start analyzing function body.
481
function_name: The name of the function being tracked.
483
self.in_a_function = True
484
self.lines_in_function = 0
485
self.current_function = function_name
488
"""Count line in current function body."""
489
if self.in_a_function:
490
self.lines_in_function += 1
492
def Check(self, error, filename, linenum):
493
"""Report if too many lines in function body.
496
error: The function to call with any errors found.
497
filename: The name of the current file.
498
linenum: The number of the line to check.
500
if Match(r'T(EST|est)', self.current_function):
501
base_trigger = self._TEST_TRIGGER
503
base_trigger = self._NORMAL_TRIGGER
504
trigger = base_trigger * 2**_VerboseLevel()
506
if self.lines_in_function > trigger:
507
error_level = int(math.log(self.lines_in_function / base_trigger, 2))
508
# 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
511
error(filename, linenum, 'readability/fn_size', error_level,
512
'Small and focused functions are preferred:'
513
' %s has %d non-comment lines'
514
' (error triggered by exceeding %d lines).' % (
515
self.current_function, self.lines_in_function, trigger))
518
"""Stop analizing function body."""
519
self.in_a_function = False
522
class _IncludeError(Exception):
523
"""Indicates a problem with the include order in a file."""
528
"""Provides utility functions for filenames.
530
FileInfo provides easy access to the components of a file's path
531
relative to the project root.
534
def __init__(self, filename):
535
self._filename = filename
538
"""Make Windows paths like Unix."""
539
return os.path.abspath(self._filename).replace('\\', '/')
541
def RepositoryName(self):
542
"""FullName after removing the local path to the repository.
544
If we have a real absolute path name here we can try to do something smart:
545
detecting the root of the checkout and truncating /path/to/checkout from
546
the name so that we get header guards that don't include things like
547
"C:\Documents and Settings\..." or "/home/username/..." in them and thus
548
people on different computers who have checked the source out to different
549
locations won't see bogus errors.
551
fullname = self.FullName()
553
if os.path.exists(fullname):
554
project_dir = os.path.dirname(fullname)
556
root_dir = os.path.dirname(fullname)
557
while (root_dir != os.path.dirname(root_dir) and
558
not (os.path.exists(os.path.join(root_dir, ".bzr"))
560
os.path.exists(os.path.join(root_dir, "_build")))):
561
root_dir = os.path.dirname(root_dir)
562
if (os.path.exists(os.path.join(root_dir, ".bzr")) or
563
os.path.exists(os.path.join(root_dir, "_build"))):
564
prefix = os.path.commonprefix([root_dir, project_dir])
565
return fullname[len(prefix) + 1:]
567
# Don't know what to do; header guard warnings may be wrong...
571
"""Splits the file into the directory, basename, and extension.
573
For 'chrome/browser/browser.cc', Split() would
574
return ('chrome/browser', 'browser', '.cc')
577
A tuple of (directory, basename, extension).
580
googlename = self.RepositoryName()
581
project, rest = os.path.split(googlename)
582
return (project,) + os.path.splitext(rest)
585
"""File base name - text after the final slash, before the final period."""
586
return self.Split()[1]
589
"""File extension - text following the final period."""
590
return self.Split()[2]
592
def NoExtension(self):
593
"""File has no source file extension."""
594
return '/'.join(self.Split()[0:2])
597
"""File has a source file extension."""
598
return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
601
def _ShouldPrintError(category, confidence):
602
"""Returns true iff confidence >= verbose, and category passes filter."""
603
# There are two ways we might decide not to print an error message:
604
# the verbosity level isn't high enough, or the filters filter it out.
605
if confidence < _cpplint_state.verbose_level:
609
for one_filter in _Filters():
610
if one_filter.startswith('-'):
611
if category.startswith(one_filter[1:]):
613
elif one_filter.startswith('+'):
614
if category.startswith(one_filter[1:]):
617
assert False # should have been checked for in SetFilter.
624
def Error(filename, linenum, category, confidence, message):
625
"""Logs the fact we've found a lint error.
627
We log where the error was found, and also our confidence in the error,
628
that is, how certain we are this is a legitimate style regression, and
629
not a misidentification or a use that's sometimes justified.
632
filename: The name of the file containing the error.
633
linenum: The number of the line containing the error.
634
category: A string used to describe the "category" this bug
635
falls under: "whitespace", say, or "runtime". Categories
636
may have a hierarchy separated by slashes: "whitespace/indent".
637
confidence: A number from 1-5 representing a confidence score for
638
the error, with 5 meaning that we are certain of the problem,
639
and 1 meaning that it could be a legitimate construct.
640
message: The error message.
642
# There are two ways we might decide not to print an error message:
643
# the verbosity level isn't high enough, or the filters filter it out.
644
if _ShouldPrintError(category, confidence):
645
_cpplint_state.IncrementErrorCount()
646
if _cpplint_state.output_format == 'vs7':
647
sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
648
filename, linenum, message, category, confidence))
650
sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
651
filename, linenum, message, category, confidence))
654
# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
655
_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
656
r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
657
# Matches strings. Escape codes should already be removed by ESCAPES.
658
_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
659
# Matches characters. Escape codes should already be removed by ESCAPES.
660
_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
661
# Matches multi-line C++ comments.
662
# This RE is a little bit more complicated than one might expect, because we
663
# have to take care of space removals tools so we can handle comments inside
665
# The current rule is: We only clear spaces from both sides when we're at the
666
# end of the line. Otherwise, we try to remove spaces from the right side,
667
# if this doesn't work we try on left side but only if there's a non-character
669
_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
670
r"""(\s*/\*.*\*/\s*$|
673
/\*.*\*/)""", re.VERBOSE)
676
def IsCppString(line):
677
"""Does line terminate so, that the next symbol is in string constant.
679
This function does not consider single-line nor multi-line comments.
682
line: is a partial line of code starting from the 0..n.
685
True, if next character appended to 'line' is inside a
689
line = line.replace(r'\\', 'XX') # after this, \\" does not match to \"
690
return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
693
def FindNextMultiLineCommentStart(lines, lineix):
694
"""Find the beginning marker for a multiline comment."""
695
while lineix < len(lines):
696
if lines[lineix].strip().startswith('/*'):
697
# Only return this marker if the comment goes beyond this line
698
if lines[lineix].strip().find('*/', 2) < 0:
704
def FindNextMultiLineCommentEnd(lines, lineix):
705
"""We are inside a comment, find the end marker."""
706
while lineix < len(lines):
707
if lines[lineix].strip().endswith('*/'):
713
def RemoveMultiLineCommentsFromRange(lines, begin, end):
714
"""Clears a range of lines for multi-line comments."""
715
# Having // dummy comments makes the lines non-empty, so we will not get
716
# unnecessary blank line warnings later in the code.
717
for i in range(begin, end):
718
lines[i] = '// dummy'
721
def RemoveMultiLineComments(filename, lines, error):
722
"""Removes multiline (c-style) comments from lines."""
724
while lineix < len(lines):
725
lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
726
if lineix_begin >= len(lines):
728
lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
729
if lineix_end >= len(lines):
730
error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
731
'Could not find end of multi-line comment')
733
RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
734
lineix = lineix_end + 1
737
def CleanseComments(line):
738
"""Removes //-comments and single-line C-style /* */ comments.
741
line: A line of C++ source.
744
The line with single-line comments removed.
746
commentpos = line.find('//')
747
if commentpos != -1 and not IsCppString(line[:commentpos]):
748
line = line[:commentpos]
749
# get rid of /* ... */
750
return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
753
class CleansedLines(object):
754
"""Holds 3 copies of all lines with different preprocessing applied to them.
756
1) elided member contains lines without strings and comments,
757
2) lines member contains lines without comments, and
758
3) raw member contains all the lines without processing.
759
All these three members are of <type 'list'>, and of the same length.
762
def __init__(self, lines):
765
self.raw_lines = lines
766
self.num_lines = len(lines)
767
for linenum in range(len(lines)):
768
self.lines.append(CleanseComments(lines[linenum]))
769
elided = self._CollapseStrings(lines[linenum])
770
self.elided.append(CleanseComments(elided))
773
"""Returns the number of lines represented."""
774
return self.num_lines
777
def _CollapseStrings(elided):
778
"""Collapses strings and chars on a line to simple "" or '' blocks.
780
We nix strings first so we're not fooled by text like '"http://"'
783
elided: The line being processed.
786
The line with collapsed strings.
788
if not _RE_PATTERN_INCLUDE.match(elided):
789
# Remove escaped characters first to make quote/single quote collapsing
790
# basic. Things that look like escaped characters shouldn't occur
791
# outside of strings and chars.
792
elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
793
elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
794
elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
798
def CloseExpression(clean_lines, linenum, pos):
799
"""If input points to ( or { or [, finds the position that closes it.
801
If lines[linenum][pos] points to a '(' or '{' or '[', finds the the
802
linenum/pos that correspond to the closing of the expression.
805
clean_lines: A CleansedLines instance containing the file.
806
linenum: The number of the line to check.
807
pos: A position on the line.
810
A tuple (line, linenum, pos) pointer *past* the closing brace, or
811
(line, len(lines), -1) if we never find a close. Note we ignore
812
strings and comments when matching; and the line we return is the
813
'cleansed' line at linenum.
816
line = clean_lines.elided[linenum]
817
startchar = line[pos]
818
if startchar not in '({[':
819
return (line, clean_lines.NumLines(), -1)
820
if startchar == '(': endchar = ')'
821
if startchar == '[': endchar = ']'
822
if startchar == '{': endchar = '}'
824
num_open = line.count(startchar) - line.count(endchar)
825
while linenum < clean_lines.NumLines() and num_open > 0:
827
line = clean_lines.elided[linenum]
828
num_open += line.count(startchar) - line.count(endchar)
829
# OK, now find the endchar that actually got us back to even
832
endpos = line.rfind(')', 0, endpos)
833
num_open -= 1 # chopped off another )
834
return (line, linenum, endpos + 1)
837
def CheckForCopyright(filename, lines, error):
838
"""Logs an error if no Copyright message appears at the top of the file."""
840
# We'll say it should occur by line 10. Don't forget there's a
841
# dummy line at the front.
842
for line in xrange(1, min(len(lines), 11)):
843
if re.search(r'Copyright', lines[line], re.I): break
844
else: # means no copyright line was found
845
error(filename, 0, 'legal/copyright', 5,
846
'No copyright message found. '
847
'You should have a line: "Copyright [year] <Copyright Owner>"')
850
def GetHeaderGuardCPPVariable(filename):
851
"""Returns the CPP variable that should be used as a header guard.
854
filename: The name of a C++ header file.
857
The CPP variable that should be used as a header guard in the
862
fileinfo = FileInfo(filename)
863
return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper()
866
def CheckForHeaderGuard(filename, lines, error):
867
"""Checks that the file contains a header guard.
869
Logs an error if no #ifndef header guard is present. For other
870
headers, checks that the full pathname is used.
873
filename: The name of the C++ header file.
874
lines: An array of strings, each representing a line of the file.
875
error: The function to call with any errors found.
878
cppvar = GetHeaderGuardCPPVariable(filename)
885
for linenum, line in enumerate(lines):
886
linesplit = line.split()
887
if len(linesplit) >= 2:
888
# find the first occurrence of #ifndef and #define, save arg
889
if not ifndef and linesplit[0] == '#ifndef':
890
# set ifndef to the header guard presented on the #ifndef line.
891
ifndef = linesplit[1]
892
ifndef_linenum = linenum
893
if not define and linesplit[0] == '#define':
894
define = linesplit[1]
895
# find the last occurrence of #endif, save entire line
896
if line.startswith('#endif'):
898
endif_linenum = linenum
900
if not ifndef or not define or ifndef != define:
901
error(filename, 0, 'build/header_guard', 5,
902
'No #ifndef header guard found, suggested CPP variable is: %s' %
906
# The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
907
# for backward compatibility.
910
if ifndef != cppvar + '_':
913
error(filename, ifndef_linenum, 'build/header_guard', error_level,
914
'#ifndef header guard has wrong style, please use: %s' % cppvar)
916
if endif != ('#endif /* %s */' % cppvar):
918
if endif != ('#endif /* %s */' % (cppvar + '_')):
921
error(filename, endif_linenum, 'build/header_guard', error_level,
922
'#endif line should be "#endif /* %s */"' % cppvar)
925
def CheckForUnicodeReplacementCharacters(filename, lines, error):
926
"""Logs an error for each line containing Unicode replacement characters.
928
These indicate that either the file contained invalid UTF-8 (likely)
929
or Unicode replacement characters (which it shouldn't). Note that
930
it's possible for this to throw off line numbering if the invalid
931
UTF-8 occurred adjacent to a newline.
934
filename: The name of the current file.
935
lines: An array of strings, each representing a line of the file.
936
error: The function to call with any errors found.
938
for linenum, line in enumerate(lines):
939
if u'\ufffd' in line:
940
error(filename, linenum, 'readability/utf8', 5,
941
'Line contains invalid UTF-8 (or Unicode replacement character).')
944
def CheckForNewlineAtEOF(filename, lines, error):
945
"""Logs an error if there is no newline char at the end of the file.
948
filename: The name of the current file.
949
lines: An array of strings, each representing a line of the file.
950
error: The function to call with any errors found.
953
# The array lines() was created by adding two newlines to the
954
# original file (go figure), then splitting on \n.
955
# To verify that the file ends in \n, we just have to make sure the
956
# last-but-two element of lines() exists and is empty.
957
if len(lines) < 3 or lines[-2]:
958
error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
959
'Could not find a newline character at the end of the file.')
962
def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
963
"""Logs an error if we see /* ... */ or "..." that extend past one line.
965
/* ... */ comments are legit inside macros, for one line.
966
Otherwise, we prefer // comments, so it's ok to warn about the
967
other. Likewise, it's ok for strings to extend across multiple
968
lines, as long as a line continuation character (backslash)
969
terminates each line. Although not currently prohibited by the C++
970
style guide, it's ugly and unnecessary. We don't do well with either
971
in this lint program, so we warn about both.
974
filename: The name of the current file.
975
clean_lines: A CleansedLines instance containing the file.
976
linenum: The number of the line to check.
977
error: The function to call with any errors found.
979
line = clean_lines.elided[linenum]
981
# Remove all \\ (escaped backslashes) from the line. They are OK, and the
982
# second (escaped) slash may trigger later \" detection erroneously.
983
line = line.replace('\\\\', '')
985
if line.count('/*') > line.count('*/'):
986
error(filename, linenum, 'readability/multiline_comment', 5,
987
'Complex multi-line /*...*/-style comment found. '
988
'Lint may give bogus warnings. '
989
'Consider replacing these with //-style comments, '
990
'with #if 0...#endif, '
991
'or with more clearly structured multi-line comments.')
993
if (line.count('"') - line.count('\\"')) % 2:
994
error(filename, linenum, 'readability/multiline_string', 5,
995
'Multi-line string ("...") found. This lint script doesn\'t '
996
'do well with such strings, and may give bogus warnings. They\'re '
997
'ugly and unnecessary, and you should use concatenation instead".')
1001
('asctime(', 'asctime_r('),
1002
('ctime(', 'ctime_r('),
1003
('getgrgid(', 'getgrgid_r('),
1004
('getgrnam(', 'getgrnam_r('),
1005
('getlogin(', 'getlogin_r('),
1006
('getpwnam(', 'getpwnam_r('),
1007
('getpwuid(', 'getpwuid_r('),
1008
('gmtime(', 'gmtime_r('),
1009
('localtime(', 'localtime_r('),
1010
('rand(', 'rand_r('),
1011
('readdir(', 'readdir_r('),
1012
('strtok(', 'strtok_r('),
1013
('ttyname(', 'ttyname_r('),
1017
def CheckPosixThreading(filename, clean_lines, linenum, error):
1018
"""Checks for calls to thread-unsafe functions.
1020
Much code has been originally written without consideration of
1021
multi-threading. Also, engineers are relying on their old experience;
1022
they have learned posix before threading extensions were added. These
1023
tests guide the engineers to use thread-safe functions (when using
1027
filename: The name of the current file.
1028
clean_lines: A CleansedLines instance containing the file.
1029
linenum: The number of the line to check.
1030
error: The function to call with any errors found.
1032
line = clean_lines.elided[linenum]
1033
for single_thread_function, multithread_safe_function in threading_list:
1034
ix = line.find(single_thread_function)
1035
# Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1036
if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
1037
line[ix - 1] not in ('_', '.', '>'))):
1038
error(filename, linenum, 'runtime/threadsafe_fn', 2,
1039
'Consider using ' + multithread_safe_function +
1040
'...) instead of ' + single_thread_function +
1041
'...) for improved thread safety.')
1044
# Matches invalid increment: *count++, which moves pointer insead of
1045
# incrementing a value.
1046
_RE_PATTERN_IVALID_INCREMENT = re.compile(
1047
r'^\s*\*\w+(\+\+|--);')
1050
def CheckInvalidIncrement(filename, clean_lines, linenum, error):
1051
"""Checks for invalud increment *count++.
1053
For example following function:
1054
void increment_counter(int* count) {
1057
is invalid, because it effectively does count++, moving pointer, and should
1058
be replaced with ++*count, (*count)++ or *count += 1.
1061
filename: The name of the current file.
1062
clean_lines: A CleansedLines instance containing the file.
1063
linenum: The number of the line to check.
1064
error: The function to call with any errors found.
1066
line = clean_lines.elided[linenum]
1067
if _RE_PATTERN_IVALID_INCREMENT.match(line):
1068
error(filename, linenum, 'runtime/invalid_increment', 5,
1069
'Changing pointer instead of value (or unused value of operator*).')
1072
class _ClassInfo(object):
1073
"""Stores information about a class."""
1075
def __init__(self, name, linenum):
1077
self.linenum = linenum
1078
self.seen_open_brace = False
1079
self.is_derived = False
1080
self.virtual_method_linenumber = None
1081
self.has_virtual_destructor = False
1082
self.brace_depth = 0
1085
class _ClassState(object):
1086
"""Holds the current state of the parse relating to class declarations.
1088
It maintains a stack of _ClassInfos representing the parser's guess
1089
as to the current nesting of class declarations. The innermost class
1090
is at the top (back) of the stack. Typically, the stack will either
1091
be empty or have exactly one entry.
1095
self.classinfo_stack = []
1097
def CheckFinished(self, filename, error):
1098
"""Checks that all classes have been completely parsed.
1100
Call this when all lines in a file have been processed.
1102
filename: The name of the current file.
1103
error: The function to call with any errors found.
1105
if self.classinfo_stack:
1106
# Note: This test can result in false positives if #ifdef constructs
1107
# get in the way of brace matching. See the testBuildClass test in
1108
# cpplint_unittest.py for an example of this.
1109
error(filename, self.classinfo_stack[0].linenum, 'build/class', 5,
1110
'Failed to find complete declaration of class %s' %
1111
self.classinfo_stack[0].name)
1114
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
1115
class_state, error):
1116
"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
1118
Complain about several constructs which gcc-2 accepts, but which are
1119
not standard C++. Warning about these in lint is one way to ease the
1120
transition to new compilers.
1121
- put storage class first (e.g. "static const" instead of "const static").
1122
- "%lld" instead of %qd" in printf-type functions.
1123
- "%1$d" is non-standard in printf-type functions.
1124
- "\%" is an undefined character escape sequence.
1125
- text after #endif is not allowed.
1126
- invalid inner-style forward declaration.
1127
- >? and <? operators, and their >?= and <?= cousins.
1128
- classes with virtual methods need virtual destructors (compiler warning
1129
available, but not turned on yet.)
1131
Additionally, check for constructor/destructor style violations as it
1132
is very convenient to do so while checking for gcc-2 compliance.
1135
filename: The name of the current file.
1136
clean_lines: A CleansedLines instance containing the file.
1137
linenum: The number of the line to check.
1138
class_state: A _ClassState instance which maintains information about
1139
the current stack of nested class declarations being parsed.
1140
error: A callable to which errors are reported, which takes 4 arguments:
1141
filename, line number, error level, and message
1144
# Remove comments from the line, but leave in strings for now.
1145
line = clean_lines.lines[linenum]
1147
if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
1148
error(filename, linenum, 'runtime/printf_format', 3,
1149
'%q in format strings is deprecated. Use %ll instead.')
1151
if Search(r'printf\s*\(.*".*%\d+\$', line):
1152
error(filename, linenum, 'runtime/printf_format', 2,
1153
'%N$ formats are unconventional. Try rewriting to avoid them.')
1155
# Remove escaped backslashes before looking for undefined escapes.
1156
line = line.replace('\\\\', '')
1158
if Search(r'("|\').*\\(%|\[|\(|{)', line):
1159
error(filename, linenum, 'build/printf_format', 3,
1160
'%, [, (, and { are undefined character escapes. Unescape them.')
1162
# For the rest, work with both comments and strings removed.
1163
line = clean_lines.elided[linenum]
1165
if Search(r'\b(const|volatile|void|char|short|int|long'
1166
r'|float|double|signed|unsigned'
1167
r'|schar|u?int8|u?int16|u?int32|u?int64)'
1168
r'\s+(auto|register|static|extern|typedef)\b',
1170
error(filename, linenum, 'build/storage_class', 5,
1171
'Storage class (static, extern, typedef, etc) should be first.')
1173
if Match(r'\s*#\s*endif\s*[^/\s]+', line):
1174
error(filename, linenum, 'build/endif_comment', 5,
1175
'Uncommented text after #endif is non-standard. Use a comment.')
1177
if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
1178
error(filename, linenum, 'build/forward_decl', 5,
1179
'Inner-style forward declarations are invalid. Remove this line.')
1181
if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
1183
error(filename, linenum, 'build/deprecated', 3,
1184
'>? and <? (max and min) operators are non-standard and deprecated.')
1186
# Track class entry and exit, and attempt to find cases within the
1187
# class declaration that don't meet the C++ style
1188
# guidelines. Tracking is very dependent on the code matching Google
1189
# style guidelines, but it seems to perform well enough in testing
1190
# to be a worthwhile addition to the checks.
1191
classinfo_stack = class_state.classinfo_stack
1192
# Look for a class declaration
1193
class_decl_match = Match(
1194
r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line)
1195
if class_decl_match:
1196
classinfo_stack.append(_ClassInfo(class_decl_match.group(3), linenum))
1198
# Everything else in this function uses the top of the stack if it's
1200
if not classinfo_stack:
1203
classinfo = classinfo_stack[-1]
1205
# If the opening brace hasn't been seen look for it and also
1206
# parent class declarations.
1207
if not classinfo.seen_open_brace:
1208
# If the line has a ';' in it, assume it's a forward declaration or
1209
# a single-line class declaration, which we won't process.
1210
if line.find(';') != -1:
1211
classinfo_stack.pop()
1213
classinfo.seen_open_brace = (line.find('{') != -1)
1214
# Look for a bare ':'
1215
if Search('(^|[^:]):($|[^:])', line):
1216
classinfo.is_derived = True
1217
if not classinfo.seen_open_brace:
1218
return # Everything else in this function is for after open brace
1220
# The class may have been declared with namespace or classname qualifiers.
1221
# The constructor and destructor will not have those qualifiers.
1222
base_classname = classinfo.name.split('::')[-1]
1224
# Look for single-argument constructors that aren't marked explicit.
1225
# Technically a valid construct, but against style.
1226
args = Match(r'(?<!explicit)\s+%s\s*\(([^,()]+)\)'
1227
% re.escape(base_classname),
1230
args.group(1) != 'void' and
1231
not Match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
1232
args.group(1).strip())):
1233
error(filename, linenum, 'runtime/explicit', 5,
1234
'Single-argument constructors should be marked explicit.')
1236
# Look for methods declared virtual.
1237
if Search(r'\bvirtual\b', line):
1238
classinfo.virtual_method_linenumber = linenum
1239
# Only look for a destructor declaration on the same line. It would
1240
# be extremely unlikely for the destructor declaration to occupy
1241
# more than one line.
1242
if Search(r'~%s\s*\(' % base_classname, line):
1243
classinfo.has_virtual_destructor = True
1245
# Look for class end.
1246
brace_depth = classinfo.brace_depth
1247
brace_depth = brace_depth + line.count('{') - line.count('}')
1248
if brace_depth <= 0:
1249
classinfo = classinfo_stack.pop()
1250
# Try to detect missing virtual destructor declarations.
1251
# For now, only warn if a non-derived class with virtual methods lacks
1252
# a virtual destructor. This is to make it less likely that people will
1253
# declare derived virtual destructors without declaring the base
1254
# destructor virtual.
1255
if ((classinfo.virtual_method_linenumber is not None) and
1256
(not classinfo.has_virtual_destructor) and
1257
(not classinfo.is_derived)): # Only warn for base classes
1258
error(filename, classinfo.linenum, 'runtime/virtual', 4,
1259
'The class %s probably needs a virtual destructor due to '
1260
'having virtual method(s), one declared at line %d.'
1261
% (classinfo.name, classinfo.virtual_method_linenumber))
1263
classinfo.brace_depth = brace_depth
1266
def CheckSpacingForFunctionCall(filename, line, linenum, error):
1267
"""Checks for the correctness of various spacing around function calls.
1270
filename: The name of the current file.
1271
line: The text of the line to check.
1272
linenum: The number of the line to check.
1273
error: The function to call with any errors found.
1276
# Since function calls often occur inside if/for/while/switch
1277
# expressions - which have their own, more liberal conventions - we
1278
# first see if we should be looking inside such an expression for a
1279
# function call, to which we can apply more strict standards.
1280
fncall = line # if there's no control flow construct, look at whole line
1281
for pattern in (r'\bif\s*\((.*)\)\s*{',
1282
r'\bfor\s*\((.*)\)\s*{',
1283
r'\bwhile\s*\((.*)\)\s*[{;]',
1284
r'\bswitch\s*\((.*)\)\s*{'):
1285
match = Search(pattern, line)
1287
fncall = match.group(1) # look inside the parens for function calls
1290
# Except in if/for/while/switch, there should never be space
1291
# immediately inside parens (eg "f( 3, 4 )"). We make an exception
1292
# for nested parens ( (a+b) + c ). Likewise, there should never be
1293
# a space before a ( when it's a function argument. I assume it's a
1294
# function argument when the char before the whitespace is legal in
1295
# a function name (alnum + _) and we're not starting a macro. Also ignore
1296
# pointers and references to arrays and functions coz they're too tricky:
1297
# we use a very simple way to recognize these:
1298
# " (something)(maybe-something)" or
1299
# " (something)(maybe-something," or
1300
# " (something)[something]"
1301
# Note that we assume the contents of [] to be short enough that
1302
# they'll never need to wrap.
1303
if ( # Ignore control structures.
1304
not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and
1305
# Ignore pointers/references to functions.
1306
not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
1307
# Ignore pointers/references to arrays.
1308
not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
1309
if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
1310
error(filename, linenum, 'whitespace/parens', 4,
1311
'Extra space after ( in function call')
1312
elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
1313
error(filename, linenum, 'whitespace/parens', 2,
1314
'Extra space after (')
1315
if (Search(r'\w\s+\(', fncall) and
1316
not Search(r'#\s*define|typedef', fncall)):
1317
error(filename, linenum, 'whitespace/parens', 4,
1318
'Extra space before ( in function call')
1319
# If the ) is followed only by a newline or a { + newline, assume it's
1320
# part of a control statement (if/while/etc), and don't complain
1321
if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
1322
error(filename, linenum, 'whitespace/parens', 2,
1323
'Extra space before )')
1326
def IsBlankLine(line):
1327
"""Returns true if the given line is blank.
1329
We consider a line to be blank if the line is empty or consists of
1333
line: A line of a string.
1336
True, if the given line is blank.
1338
return not line or line.isspace()
1341
def CheckForFunctionLengths(filename, clean_lines, linenum,
1342
function_state, error):
1343
"""Reports for long function bodies.
1345
For an overview why this is done, see:
1346
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
1348
Uses a simplistic algorithm assuming other style guidelines
1349
(especially spacing) are followed.
1350
Only checks unindented functions, so class members are unchecked.
1351
Trivial bodies are unchecked, so constructors with huge initializer lists
1353
Blank/comment lines are not counted so as to avoid encouraging the removal
1354
of vertical space and commments just to get through a lint check.
1355
NOLINT *on the last line of a function* disables this check.
1358
filename: The name of the current file.
1359
clean_lines: A CleansedLines instance containing the file.
1360
linenum: The number of the line to check.
1361
function_state: Current function name and lines in body so far.
1362
error: The function to call with any errors found.
1364
lines = clean_lines.lines
1365
line = lines[linenum]
1366
raw = clean_lines.raw_lines
1367
raw_line = raw[linenum]
1370
starting_func = False
1371
regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ...
1372
match_result = Match(regexp, line)
1374
# If the name is all caps and underscores, figure it's a macro and
1375
# ignore it, unless it's TEST or TEST_F.
1376
function_name = match_result.group(1).split()[-1]
1377
if function_name == 'TEST' or function_name == 'TEST_F' or (
1378
not Match(r'[A-Z_]+$', function_name)):
1379
starting_func = True
1383
for start_linenum in xrange(linenum, clean_lines.NumLines()):
1384
start_line = lines[start_linenum]
1385
joined_line += ' ' + start_line.lstrip()
1386
if Search(r'(;|})', start_line): # Declarations and trivial functions
1389
elif Search(r'{', start_line):
1391
function = Search(r'((\w|:)*)\(', line).group(1)
1392
if Match(r'TEST', function): # Handle TEST... macros
1393
parameter_regexp = Search(r'(\(.*\))', joined_line)
1394
if parameter_regexp: # Ignore bad syntax
1395
function += parameter_regexp.group(1)
1398
function_state.Begin(function)
1401
# No body for the function (or evidence of a non-function) was found.
1402
error(filename, linenum, 'readability/fn_size', 5,
1403
'Lint failed to find start of function body.')
1404
elif Match(r'^\}\s*$', line): # function end
1405
if not Search(r'\bNOLINT\b', raw_line):
1406
function_state.Check(error, filename, linenum)
1407
function_state.End()
1408
elif not Match(r'^\s*$', line):
1409
function_state.Count() # Count non-blank/non-comment lines.
1412
_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
1415
def CheckComment(comment, filename, linenum, error):
1416
"""Checks for common mistakes in TODO comments.
1419
comment: The text of the comment from the line in question.
1420
filename: The name of the current file.
1421
linenum: The number of the line to check.
1422
error: The function to call with any errors found.
1424
match = _RE_PATTERN_TODO.match(comment)
1426
# One whitespace is correct; zero whitespace is handled elsewhere.
1427
leading_whitespace = match.group(1)
1428
if len(leading_whitespace) > 1:
1429
error(filename, linenum, 'whitespace/todo', 2,
1430
'Too many spaces before TODO')
1432
username = match.group(2)
1434
error(filename, linenum, 'readability/todo', 2,
1435
'Missing username in TODO; it should look like '
1436
'"// TODO(my_username): Stuff."')
1438
middle_whitespace = match.group(3)
1439
# Comparisons made explicit for correctness -- pylint: disable-msg=C6403
1440
if middle_whitespace != ' ' and middle_whitespace != '':
1441
error(filename, linenum, 'whitespace/todo', 2,
1442
'TODO(my_username) should be followed by a space')
1445
def CheckSpacing(filename, clean_lines, linenum, error):
1446
"""Checks for the correctness of various spacing issues in the code.
1448
Things we check for: spaces around operators, spaces after
1449
if/for/while/switch, no spaces around parens in function calls, two
1450
spaces between code and comment, don't start a block with a blank
1451
line, don't end a function with a blank line, don't have too many
1452
blank lines in a row.
1455
filename: The name of the current file.
1456
clean_lines: A CleansedLines instance containing the file.
1457
linenum: The number of the line to check.
1458
error: The function to call with any errors found.
1461
raw = clean_lines.raw_lines
1464
# Before nixing comments, check if the line is blank for no good
1465
# reason. This includes the first line after a block is opened, and
1466
# blank lines at the end of a function (ie, right before a line like '}'
1467
if IsBlankLine(line):
1468
elided = clean_lines.elided
1469
prev_line = elided[linenum - 1]
1470
prevbrace = prev_line.rfind('{')
1471
# TODO(unknown): Don't complain if line before blank line, and line after,
1472
# both start with alnums and are indented the same amount.
1473
# This ignores whitespace at the start of a namespace block
1474
# because those are not usually indented.
1475
if (prevbrace != -1 and prev_line[prevbrace:].find('}') == -1
1476
and prev_line[:prevbrace].find('namespace') == -1):
1477
# OK, we have a blank line at the start of a code block. Before we
1478
# complain, we check if it is an exception to the rule: The previous
1479
# non-empty line has the paramters of a function header that are indented
1480
# 4 spaces (because they did not fit in a 80 column line when placed on
1481
# the same line as the function name). We also check for the case where
1482
# the previous line is indented 6 spaces, which may happen when the
1483
# initializers of a constructor do not fit into a 80 column line.
1485
if Match(r' {6}\w', prev_line): # Initializer list?
1486
# We are looking for the opening column of initializer list, which
1487
# should be indented 4 spaces to cause 6 space indentation afterwards.
1488
search_position = linenum-2
1489
while (search_position >= 0
1490
and Match(r' {6}\w', elided[search_position])):
1491
search_position -= 1
1492
exception = (search_position >= 0
1493
and elided[search_position][:5] == ' :')
1495
# Search for the function arguments or an initializer list. We use a
1496
# simple heuristic here: If the line is indented 4 spaces; and we have a
1497
# closing paren, without the opening paren, followed by an opening brace
1498
# or colon (for initializer lists) we assume that it is the last line of
1499
# a function header. If we have a colon indented 4 spaces, it is an
1501
exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
1503
or Match(r' {4}:', prev_line))
1506
error(filename, linenum, 'whitespace/blank_line', 2,
1507
'Blank line at the start of a code block. Is this needed?')
1508
# This doesn't ignore whitespace at the end of a namespace block
1509
# because that is too hard without pairing open/close braces;
1510
# however, a special exception is made for namespace closing
1511
# brackets which have a comment containing "namespace".
1513
# Also, ignore blank lines at the end of a block in a long if-else
1516
# // Something followed by a blank line
1518
# } else if (condition2) {
1521
if linenum + 1 < clean_lines.NumLines():
1522
next_line = raw[linenum + 1]
1524
and Match(r'\s*}', next_line)
1525
and next_line.find('namespace') == -1
1526
and next_line.find('} else ') == -1):
1527
error(filename, linenum, 'whitespace/blank_line', 3,
1528
'Blank line at the end of a code block. Is this needed?')
1530
# Next, we complain if there's a comment too near the text
1531
commentpos = line.find('//')
1532
if commentpos != -1:
1533
# Check if the // may be in quotes. If so, ignore it
1534
# Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1535
if (line.count('"', 0, commentpos) -
1536
line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
1537
# Allow one space for new scopes, two spaces otherwise:
1538
if (not Match(r'^\s*{ //', line) and
1539
((commentpos >= 1 and
1540
line[commentpos-1] not in string.whitespace) or
1541
(commentpos >= 2 and
1542
line[commentpos-2] not in string.whitespace))):
1543
error(filename, linenum, 'whitespace/comments', 2,
1544
'At least two spaces is best between code and comments')
1545
# There should always be a space between the // and the comment
1546
commentend = commentpos + 2
1547
if commentend < len(line) and not line[commentend] == ' ':
1548
# but some lines are exceptions -- e.g. if they're big
1549
# comment delimiters like:
1550
# //----------------------------------------------------------
1551
# or they begin with multiple slashes followed by a space:
1552
# //////// Header comment
1553
match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
1554
Search(r'^/+ ', line[commentend:]))
1556
error(filename, linenum, 'whitespace/comments', 4,
1557
'Should have a space between // and comment')
1558
CheckComment(line[commentpos:], filename, linenum, error)
1560
line = clean_lines.elided[linenum] # get rid of comments and strings
1562
# Don't try to do spacing checks for operator methods
1563
line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
1565
# = should have no space before and should always have a space after.
1566
if Search(r'[\s.]=[^=]', line):
1567
error(filename, linenum, 'whitespace/operators', 4,
1568
'Space found before =')
1569
if Search(r'=[\w.]', line):
1570
error(filename, linenum, 'whitespace/operators', 4,
1571
'Missing space after =')
1573
# It's ok not to have spaces around binary operators like + - * /, but if
1574
# there's too little whitespace, we get concerned. It's hard to tell,
1575
# though, so we punt on this one for now. TODO.
1577
# You should always have whitespace around binary operators.
1578
# Alas, we can't test < or > because they're legitimately used sans spaces
1579
# (a->b, vector<int> a). The only time we can tell is a < with no >, and
1580
# only if it's not template params list spilling into the next line.
1581
match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
1583
# Note that while it seems that the '<[^<]*' term in the following
1584
# regexp could be simplified to '<.*', which would indeed match
1585
# the same class of strings, the [^<] means that searching for the
1586
# regexp takes linear rather than quadratic time.
1587
if not Search(r'<[^<]*,\s*$', line): # template params spill
1588
match = Search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line)
1590
error(filename, linenum, 'whitespace/operators', 3,
1591
'Missing spaces around %s' % match.group(1))
1592
# We allow no-spaces around << and >> when used like this: 10<<20, but
1593
# not otherwise (particularly, not when used as streams)
1594
match = Search(r'[^0-9\s](<<|>>)[^0-9\s]', line)
1596
error(filename, linenum, 'whitespace/operators', 3,
1597
'Missing spaces around %s' % match.group(1))
1599
# There shouldn't be space around unary operators
1600
match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
1602
error(filename, linenum, 'whitespace/operators', 4,
1603
'Extra space for operator %s' % match.group(1))
1605
# A pet peeve of mine: no spaces after an if, while, switch, or for
1606
match = Search(r' (if\(|for\(|while\(|switch\()', line)
1608
error(filename, linenum, 'whitespace/parens', 5,
1609
'Missing space before ( in %s' % match.group(1))
1611
# For if/for/while/switch, the left and right parens should be
1612
# consistent about how many spaces are inside the parens, and
1613
# there should either be zero or one spaces inside the parens.
1614
# We don't want: "if ( foo)" or "if ( foo )".
1615
# Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
1616
match = Search(r'\b(if|for|while|switch)\s*'
1617
r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
1620
if len(match.group(2)) != len(match.group(4)):
1621
if not (match.group(3) == ';' and
1622
len(match.group(2)) == 1 + len(match.group(4)) or
1623
not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
1624
error(filename, linenum, 'whitespace/parens', 5,
1625
'Mismatching spaces inside () in %s' % match.group(1))
1626
if not len(match.group(2)) in [0, 1]:
1627
error(filename, linenum, 'whitespace/parens', 5,
1628
'Should have zero or one spaces inside ( and ) in %s' %
1631
# You should always have a space after a comma (either as fn arg or operator)
1632
if Search(r',[^\s]', line):
1633
error(filename, linenum, 'whitespace/comma', 3,
1634
'Missing space after ,')
1636
# Next we will look for issues with function calls.
1637
CheckSpacingForFunctionCall(filename, line, linenum, error)
1639
# Except after an opening paren, you should have spaces before your braces.
1640
# And since you should never have braces at the beginning of a line, this is
1642
if Search(r'[^ (]{', line):
1643
error(filename, linenum, 'whitespace/braces', 5,
1644
'Missing space before {')
1646
# Make sure '} else {' has spaces.
1647
if Search(r'}else', line):
1648
error(filename, linenum, 'whitespace/braces', 5,
1649
'Missing space before else')
1651
# You shouldn't have spaces before your brackets, except maybe after
1652
# 'delete []' or 'new char * []'.
1653
if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
1654
error(filename, linenum, 'whitespace/braces', 5,
1655
'Extra space before [')
1657
# You shouldn't have a space before a semicolon at the end of the line.
1658
# There's a special case for "for" since the style guide allows space before
1659
# the semicolon there.
1660
if Search(r':\s*;\s*$', line):
1661
error(filename, linenum, 'whitespace/semicolon', 5,
1662
'Semicolon defining empty statement. Use { } instead.')
1663
elif Search(r'^\s*;\s*$', line):
1664
error(filename, linenum, 'whitespace/semicolon', 5,
1665
'Line contains only semicolon. If this should be an empty statement, '
1667
elif (Search(r'\s+;\s*$', line) and
1668
not Search(r'\bfor\b', line)):
1669
error(filename, linenum, 'whitespace/semicolon', 5,
1670
'Extra space before last semicolon. If this should be an empty '
1671
'statement, use { } instead.')
1674
def GetPreviousNonBlankLine(clean_lines, linenum):
1675
"""Return the most recent non-blank line and its line number.
1678
clean_lines: A CleansedLines instance containing the file contents.
1679
linenum: The number of the line to check.
1682
A tuple with two elements. The first element is the contents of the last
1683
non-blank line before the current line, or the empty string if this is the
1684
first non-blank line. The second is the line number of that line, or -1
1685
if this is the first non-blank line.
1688
prevlinenum = linenum - 1
1689
while prevlinenum >= 0:
1690
prevline = clean_lines.elided[prevlinenum]
1691
if not IsBlankLine(prevline): # if not a blank line...
1692
return (prevline, prevlinenum)
1697
def CheckBraces(filename, clean_lines, linenum, error):
1698
"""Looks for misplaced braces (e.g. at the end of line).
1701
filename: The name of the current file.
1702
clean_lines: A CleansedLines instance containing the file.
1703
linenum: The number of the line to check.
1704
error: The function to call with any errors found.
1707
line = clean_lines.elided[linenum] # get rid of comments and strings
1709
if Match(r'\s*{\s*$', line):
1710
# We allow an open brace to start a line in the case where someone
1711
# is using braces in a block to explicitly create a new scope,
1712
# which is commonly used to control the lifetime of
1713
# stack-allocated variables. We don't detect this perfectly: we
1714
# just don't complain if the last non-whitespace character on the
1715
# previous non-blank line is ';', ':', '{', or '}'.
1716
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
1717
if not Search(r'[;:}{]\s*$', prevline):
1718
error(filename, linenum, 'whitespace/braces', 4,
1719
'{ should almost always be at the end of the previous line')
1721
# An else clause should be on the same line as the preceding closing brace.
1722
if Match(r'\s*else\s*', line):
1723
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
1724
if Match(r'\s*}\s*$', prevline):
1725
error(filename, linenum, 'whitespace/newline', 4,
1726
'An else should appear on the same line as the preceding }')
1728
# If braces come on one side of an else, they should be on both.
1729
# However, we have to worry about "else if" that spans multiple lines!
1730
if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
1731
if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if
1732
# find the ( after the if
1733
pos = line.find('else if')
1734
pos = line.find('(', pos)
1736
(endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
1737
if endline[endpos:].find('{') == -1: # must be brace after if
1738
error(filename, linenum, 'readability/braces', 5,
1739
'If an else has a brace on one side, it should have it on both')
1740
else: # common case: else not followed by a multi-line if
1741
error(filename, linenum, 'readability/braces', 5,
1742
'If an else has a brace on one side, it should have it on both')
1744
# Likewise, an else should never have the else clause on the same line
1745
if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
1746
error(filename, linenum, 'whitespace/newline', 4,
1747
'Else clause should never be on same line as else (use 2 lines)')
1749
# In the same way, a do/while should never be on one line
1750
if Match(r'\s*do [^\s{]', line):
1751
error(filename, linenum, 'whitespace/newline', 4,
1752
'do/while clauses should not be on a single line')
1754
# Braces shouldn't be followed by a ; unless they're defining a struct
1755
# or initializing an array.
1756
# We can't tell in general, but we can for some common cases.
1757
prevlinenum = linenum
1759
(prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum)
1760
if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'):
1761
line = prevline + line
1764
if (Search(r'{.*}\s*;', line) and
1765
line.count('{') == line.count('}') and
1766
not Search(r'struct|class|enum|\s*=\s*{', line)):
1767
error(filename, linenum, 'readability/braces', 4,
1768
"You don't need a ; after a }")
1771
def ReplaceableCheck(operator, macro, line):
1772
"""Determine whether a basic CHECK can be replaced with a more specific one.
1774
For example suggest using CHECK_EQ instead of CHECK(a == b) and
1775
similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
1778
operator: The C++ operator used in the CHECK.
1779
macro: The CHECK or EXPECT macro being called.
1780
line: The current source line.
1783
True if the CHECK can be replaced with a more specific one.
1786
# This matches decimal and hex integers, strings, and chars (in that order).
1787
match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
1789
# Expression to match two sides of the operator with something that
1790
# looks like a literal, since CHECK(x == iterator) won't compile.
1791
# This means we can't catch all the cases where a more specific
1792
# CHECK is possible, but it's less annoying than dealing with
1793
# extraneous warnings.
1794
match_this = (r'\s*' + macro + r'\((\s*' +
1795
match_constant + r'\s*' + operator + r'[^<>].*|'
1796
r'.*[^<>]' + operator + r'\s*' + match_constant +
1799
# Don't complain about CHECK(x == NULL) or similar because
1800
# CHECK_EQ(x, NULL) won't compile (requires a cast).
1801
# Also, don't complain about more complex boolean expressions
1802
# involving && or || such as CHECK(a == b || c == d).
1803
return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line)
1806
def CheckCheck(filename, clean_lines, linenum, error):
1807
"""Checks the use of CHECK and EXPECT macros.
1810
filename: The name of the current file.
1811
clean_lines: A CleansedLines instance containing the file.
1812
linenum: The number of the line to check.
1813
error: The function to call with any errors found.
1816
# Decide the set of replacement macros that should be suggested
1817
raw_lines = clean_lines.raw_lines
1819
for macro in _CHECK_MACROS:
1820
if raw_lines[linenum].find(macro) >= 0:
1821
current_macro = macro
1823
if not current_macro:
1824
# Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
1827
line = clean_lines.elided[linenum] # get rid of comments and strings
1829
# Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.
1830
for operator in ['==', '!=', '>=', '>', '<=', '<']:
1831
if ReplaceableCheck(operator, current_macro, line):
1832
error(filename, linenum, 'readability/check', 2,
1833
'Consider using %s instead of %s(a %s b)' % (
1834
_CHECK_REPLACEMENT[current_macro][operator],
1835
current_macro, operator))
1839
def GetLineWidth(line):
1840
"""Determines the width of the line in column positions.
1843
line: A string, which may be a Unicode string.
1846
The width of the line in column positions, accounting for Unicode
1847
combining characters and wide characters.
1849
if isinstance(line, unicode):
1851
for c in unicodedata.normalize('NFC', line):
1852
if unicodedata.east_asian_width(c) in ('W', 'F'):
1854
elif not unicodedata.combining(c):
1861
def CheckStyle(filename, clean_lines, linenum, file_extension, error):
1862
"""Checks rules from the 'C++ style rules' section of cppguide.html.
1864
Most of these rules are hard to test (naming, comment style), but we
1865
do what we can. In particular we check for 2-space indents, line lengths,
1866
tab usage, spaces inside code, etc.
1869
filename: The name of the current file.
1870
clean_lines: A CleansedLines instance containing the file.
1871
linenum: The number of the line to check.
1872
file_extension: The extension (without the dot) of the filename.
1873
error: The function to call with any errors found.
1876
raw_lines = clean_lines.raw_lines
1877
line = raw_lines[linenum]
1879
if line.find('\t') != -1:
1880
error(filename, linenum, 'whitespace/tab', 1,
1881
'Tab found; better to use spaces')
1883
# One or three blank spaces at the beginning of the line is weird; it's
1884
# hard to reconcile that with 2-space indents.
1885
# NOTE: here are the conditions rob pike used for his tests. Mine aren't
1886
# as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
1887
# if(RLENGTH > 20) complain = 0;
1888
# if(match($0, " +(error|private|public|protected):")) complain = 0;
1889
# if(match(prev, "&& *$")) complain = 0;
1890
# if(match(prev, "\\|\\| *$")) complain = 0;
1891
# if(match(prev, "[\",=><] *$")) complain = 0;
1892
# if(match($0, " <<")) complain = 0;
1893
# if(match(prev, " +for \\(")) complain = 0;
1894
# if(prevodd && match(prevprev, " +for \\(")) complain = 0;
1896
cleansed_line = clean_lines.elided[linenum]
1897
while initial_spaces < len(line) and line[initial_spaces] == ' ':
1899
if line and line[-1].isspace():
1900
error(filename, linenum, 'whitespace/end_of_line', 4,
1901
'Line ends in whitespace. Consider deleting these extra spaces.')
1902
# There are certain situations we allow one space, notably for labels
1903
elif ((initial_spaces == 1 or initial_spaces == 3) and
1904
not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
1905
error(filename, linenum, 'whitespace/indent', 3,
1906
'Weird number of spaces at line-start. '
1907
'Are you using a 2-space indent?')
1908
# Labels should always be indented at least one space.
1909
elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
1911
error(filename, linenum, 'whitespace/labels', 4,
1912
'Labels should always be indented at least one space. '
1913
'If this is a member-initializer list in a constructor, '
1914
'the colon should be on the line after the definition header.')
1916
# Check if the line is a header guard.
1917
is_header_guard = False
1918
if file_extension == 'h':
1919
cppvar = GetHeaderGuardCPPVariable(filename)
1920
if (line.startswith('#ifndef %s' % cppvar) or
1921
line.startswith('#define %s' % cppvar) or
1922
line.startswith('#endif // %s' % cppvar)):
1923
is_header_guard = True
1924
# #include lines and header guards can be long, since there's no clean way to
1927
# URLs can be long too. It's possible to split these, but it makes them
1928
# harder to cut&paste.
1929
if (not line.startswith('#include') and not is_header_guard and
1930
not Match(r'^\s*//.*http(s?)://\S*$', line)):
1931
line_width = GetLineWidth(line)
1932
if line_width > 100:
1933
error(filename, linenum, 'whitespace/line_length', 4,
1934
'Lines should very rarely be longer than 100 characters')
1935
elif line_width > 80:
1936
error(filename, linenum, 'whitespace/line_length', 2,
1937
'Lines should be <= 80 characters long')
1939
if (cleansed_line.count(';') > 1 and
1940
# for loops are allowed two ;'s (and may run over two lines).
1941
cleansed_line.find('for') == -1 and
1942
(GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
1943
GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
1944
# It's ok to have many commands in a switch case that fits in 1 line
1945
not ((cleansed_line.find('case ') != -1 or
1946
cleansed_line.find('default:') != -1) and
1947
cleansed_line.find('break;') != -1)):
1948
error(filename, linenum, 'whitespace/newline', 4,
1949
'More than one command on the same line')
1951
# Some more style checks
1952
CheckBraces(filename, clean_lines, linenum, error)
1953
CheckSpacing(filename, clean_lines, linenum, error)
1954
CheckCheck(filename, clean_lines, linenum, error)
1957
_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
1958
_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
1959
# Matches the first component of a filename delimited by -s and _s. That is:
1960
# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
1961
# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
1962
# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
1963
# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
1964
_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
1967
def _DropCommonSuffixes(filename):
1968
"""Drops common suffixes like _test.cc or -inl.h from filename.
1971
>>> _DropCommonSuffixes('foo/foo-inl.h')
1973
>>> _DropCommonSuffixes('foo/bar/foo.cc')
1975
>>> _DropCommonSuffixes('foo/foo_internal.h')
1977
>>> _DropCommonSuffixes('foo/foo_unusualinternal.h')
1978
'foo/foo_unusualinternal'
1981
filename: The input filename.
1984
The filename with the common suffix removed.
1986
for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
1987
'inl.h', 'impl.h', 'internal.h'):
1988
if (filename.endswith(suffix) and len(filename) > len(suffix) and
1989
filename[-len(suffix) - 1] in ('-', '_')):
1990
return filename[:-len(suffix) - 1]
1991
return os.path.splitext(filename)[0]
1994
def _IsTestFilename(filename):
1995
"""Determines if the given filename has a suffix that identifies it as a test.
1998
filename: The input filename.
2001
True if 'filename' looks like a test, False otherwise.
2003
if (filename.endswith('_test.cc') or
2004
filename.endswith('_unittest.cc') or
2005
filename.endswith('_regtest.cc')):
2011
def _ClassifyInclude(fileinfo, include, is_system):
2012
"""Figures out what kind of header 'include' is.
2015
fileinfo: The current file cpplint is running over. A FileInfo instance.
2016
include: The path to a #included file.
2017
is_system: True if the #include used <> rather than "".
2020
One of the _XXX_HEADER constants.
2023
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
2025
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
2027
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
2029
>>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
2030
... 'bar/foo_other_ext.h', False)
2032
>>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
2035
# This is a list of all standard c++ header files, except
2036
# those already checked for above.
2037
is_stl_h = include in _STL_HEADERS
2038
is_cpp_h = is_stl_h or include in _CPP_HEADERS
2042
return _CPP_SYS_HEADER
2044
return _C_SYS_HEADER
2046
# If the target file and the include we're checking share a
2047
# basename when we drop common extensions, and the include
2048
# lives in . , then it's likely to be owned by the target file.
2049
target_dir, target_base = (
2050
os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
2051
include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
2052
if target_base == include_base and (
2053
include_dir == target_dir or
2054
include_dir == os.path.normpath(target_dir + '/../public')):
2055
return _LIKELY_MY_HEADER
2057
# If the target and include share some initial basename
2058
# component, it's possible the target is implementing the
2059
# include, so it's allowed to be first, but we'll never
2060
# complain if it's not there.
2061
target_first_component = _RE_FIRST_COMPONENT.match(target_base)
2062
include_first_component = _RE_FIRST_COMPONENT.match(include_base)
2063
if (target_first_component and include_first_component and
2064
target_first_component.group(0) ==
2065
include_first_component.group(0)):
2066
return _POSSIBLE_MY_HEADER
2068
return _OTHER_HEADER
2072
def CheckGlobalInclude(filename, clean_lines, linenum, include_state, error):
2073
"""Check rules that are applicable to #include lines.
2075
global.h, config.h and server_includes.h should NEVER be included in headers
2076
unless those headers end in _priv and therefore are private headers.
2079
filename: The name of the current file.
2080
clean_lines: A CleansedLines instance containing the file.
2081
linenum: The number of the line to check.
2082
include_state: An _IncludeState instance in which the headers are inserted.
2083
error: The function to call with any errors found.
2085
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"):
2088
fileinfo = FileInfo(filename)
2090
line = clean_lines.lines[linenum]
2092
match = _RE_PATTERN_INCLUDE.search(line)
2094
include = match.group(2)
2095
if Match(r'(config|global|server_includes|_priv)\.h$', include):
2096
error(filename, linenum, 'build/include_config', 4,
2097
'Do not include config.h or files that include config.h in .h files')
2099
def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
2100
"""Check rules that are applicable to #include lines.
2102
Strings on #include lines are NOT removed from elided line, to make
2103
certain tasks easier. However, to prevent false positives, checks
2104
applicable to #include lines in CheckLanguage must be put here.
2107
filename: The name of the current file.
2108
clean_lines: A CleansedLines instance containing the file.
2109
linenum: The number of the line to check.
2110
include_state: An _IncludeState instance in which the headers are inserted.
2111
error: The function to call with any errors found.
2113
fileinfo = FileInfo(filename)
2115
line = clean_lines.lines[linenum]
2117
# "include" should use the new style "foo/bar.h" instead of just "bar.h"
2118
if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
2119
error(filename, linenum, 'build/include', 4,
2120
'Include the directory when naming .h files')
2122
# we shouldn't include a file more than once. actually, there are a
2123
# handful of instances where doing so is okay, but in general it's
2125
match = _RE_PATTERN_INCLUDE.search(line)
2127
include = match.group(2)
2128
is_system = (match.group(1) == '<')
2129
if include in include_state:
2130
error(filename, linenum, 'build/include', 4,
2131
'"%s" already included at %s:%s' %
2132
(include, filename, include_state[include]))
2134
include_state[include] = linenum
2136
# We want to ensure that headers appear in the right order:
2137
# 1) for foo.cc, foo.h (preferred location)
2139
# 3) cpp system files
2140
# 4) for foo.cc, foo.h (deprecated location)
2141
# 5) other google headers
2143
# We classify each include statement as one of those 5 types
2144
# using a number of techniques. The include_state object keeps
2145
# track of the highest type seen, and complains if we see a
2146
# lower type after that.
2147
error_message = include_state.CheckNextIncludeOrder(
2148
_ClassifyInclude(fileinfo, include, is_system))
2150
error(filename, linenum, 'build/include_order', 4,
2151
'%s. Should be: %s.h, c system, c++ system, other.' %
2152
(error_message, fileinfo.BaseName()))
2154
# Look for any of the stream classes that are part of standard C++.
2155
match = _RE_PATTERN_INCLUDE.match(line)
2157
include = match.group(2)
2158
if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
2159
# Many unit tests use cout, so we exempt them.
2160
if not _IsTestFilename(filename):
2161
error(filename, linenum, 'readability/streams', 3,
2162
'Streams are highly discouraged.')
2164
def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state,
2166
"""Checks rules from the 'C++ language rules' section of cppguide.html.
2168
Some of these rules are hard to test (function overloading, using
2169
uint32 inappropriately), but we do the best we can.
2172
filename: The name of the current file.
2173
clean_lines: A CleansedLines instance containing the file.
2174
linenum: The number of the line to check.
2175
file_extension: The extension (without the dot) of the filename.
2176
include_state: An _IncludeState instance in which the headers are inserted.
2177
error: The function to call with any errors found.
2179
# If the line is empty or consists of entirely a comment, no need to
2181
line = clean_lines.elided[linenum]
2185
match = _RE_PATTERN_INCLUDE.search(line)
2187
CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
2188
CheckGlobalInclude(filename, clean_lines, linenum, include_state, error)
2191
# Create an extended_line, which is the concatenation of the current and
2192
# next lines, for more effective checking of code that may span more than one
2194
if linenum + 1 < clean_lines.NumLines():
2195
extended_line = line + clean_lines.elided[linenum + 1]
2197
extended_line = line
2199
# Make Windows paths like Unix.
2200
fullname = os.path.abspath(filename).replace('\\', '/')
2202
# TODO(unknown): figure out if they're using default arguments in fn proto.
2204
# Check to see if they're using an conversion function cast.
2205
# I just try to capture the most common basic types, though there are more.
2206
# Parameterless conversion functions, such as bool(), are allowed as they are
2207
# probably a member operator declaration or default constructor.
2209
r'\b(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
2211
# gMock methods are defined using some variant of MOCK_METHODx(name, type)
2212
# where type may be float(), int(string), etc. Without context they are
2213
# virtually indistinguishable from int(x) casts.
2214
if not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line):
2215
error(filename, linenum, 'readability/casting', 4,
2216
'Using deprecated casting style. '
2217
'Use static_cast<%s>(...) instead' %
2220
CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2222
r'\((int|float|double|bool|char|u?int(16|32|64))\)',
2224
# This doesn't catch all cases. Consider (const char * const)"hello".
2225
CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2226
'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
2228
# In addition, we look for people taking the address of a cast. This
2229
# is dangerous -- casts can assign to temporaries, so the pointer doesn't
2230
# point where you think.
2232
r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
2233
error(filename, linenum, 'runtime/casting', 4,
2234
('Are you taking an address of a cast? '
2235
'This is dangerous: could be a temp var. '
2236
'Take the address before doing the cast, rather than after'))
2238
# Check for people declaring static/global STL strings at the top level.
2239
# This is dangerous because the C++ language does not guarantee that
2240
# globals with constructors are initialized before the first access.
2242
r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
2244
# Make sure it's not a function.
2245
# Function template specialization looks like: "string foo<Type>(...".
2246
# Class template definitions look like: "string Foo<Type>::Method(...".
2247
if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)',
2249
error(filename, linenum, 'runtime/string', 4,
2250
'For a static/global string constant, use a C style string instead: '
2252
(match.group(1), match.group(2)))
2254
# Check that we're not using RTTI outside of testing code.
2255
if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename):
2256
error(filename, linenum, 'runtime/rtti', 5,
2257
'Do not use dynamic_cast<>. If you need to cast within a class '
2258
"hierarchy, use static_cast<> to upcast. Google doesn't support "
2261
if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
2262
error(filename, linenum, 'runtime/init', 4,
2263
'You seem to be initializing a member variable with itself.')
2265
if file_extension == 'h':
2266
# TODO(unknown): check that 1-arg constructors are explicit.
2267
# How to tell it's a constructor?
2268
# (handled in CheckForNonStandardConstructs for now)
2269
# TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
2273
# Check if people are using the verboten C basic types. The only exception
2274
# we regularly allow is "unsigned short port" for port.
2275
if Search(r'\bshort port\b', line):
2276
if not Search(r'\bunsigned short port\b', line):
2277
error(filename, linenum, 'runtime/int', 4,
2278
'Use "unsigned short" for ports, not "short"')
2280
match = Search(r'\b(short|long(?! +double)|long long)\b', line)
2282
error(filename, linenum, 'runtime/int', 4,
2283
'Use int16/int64/etc, rather than the C type %s' % match.group(1))
2285
# When snprintf is used, the second argument shouldn't be a literal.
2286
match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
2288
error(filename, linenum, 'runtime/printf', 3,
2289
'If you can, use sizeof(%s) instead of %s as the 2nd arg '
2290
'to snprintf.' % (match.group(1), match.group(2)))
2292
# Check if some verboten C functions are being used.
2293
if Search(r'\bsprintf\b', line):
2294
error(filename, linenum, 'runtime/printf', 5,
2295
'Never use sprintf. Use snprintf instead.')
2296
match = Search(r'\b(strcpy|strcat)\b', line)
2298
error(filename, linenum, 'runtime/printf', 4,
2299
'Almost always, snprintf is better than %s' % match.group(1))
2301
if Search(r'\bsscanf\b', line):
2302
error(filename, linenum, 'runtime/printf', 1,
2303
'sscanf can be ok, but is slow and can overflow buffers.')
2305
# Check for suspicious usage of "if" like
2307
if Search(r'\}\s*if\s*\(', line):
2308
error(filename, linenum, 'readability/braces', 4,
2309
'Did you mean "else if"? If not, start a new line for "if".')
2311
# Check for potential format string bugs like printf(foo).
2312
# We constrain the pattern not to pick things like DocidForPrintf(foo).
2313
# Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
2314
match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I)
2316
error(filename, linenum, 'runtime/printf', 4,
2317
'Potential format string bug. Do %s("%%s", %s) instead.'
2318
% (match.group(1), match.group(2)))
2320
# Check for potential memset bugs like memset(buf, sizeof(buf), 0).
2321
match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
2322
if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
2323
error(filename, linenum, 'runtime/memset', 4,
2324
'Did you mean "memset(%s, 0, %s)"?'
2325
% (match.group(1), match.group(2)))
2327
if Search(r'\busing namespace\b', line) and filename.endswith(".h"):
2328
error(filename, linenum, 'build/namespaces', 5,
2329
'Do not use namespace using-directives in headers. ')
2331
# Detect variable-length arrays.
2332
match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
2333
if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
2334
match.group(3).find(']') == -1):
2335
# Split the size using space and arithmetic operators as delimiters.
2336
# If any of the resulting tokens are not compile time constants then
2338
tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
2346
if Search(r'sizeof\(.+\)', tok): continue
2347
if Search(r'arraysize\(\w+\)', tok): continue
2349
tok = tok.lstrip('(')
2350
tok = tok.rstrip(')')
2351
if not tok: continue
2352
if Match(r'\d+', tok): continue
2353
if Match(r'0[xX][0-9a-fA-F]+', tok): continue
2354
if Match(r'k[A-Z0-9]\w*', tok): continue
2355
if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
2356
if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
2357
# A catch all for tricky sizeof cases, including 'sizeof expression',
2358
# 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
2359
# requires skipping the next token becasue we split on ' ' and '*'.
2360
if tok.startswith('sizeof'):
2366
error(filename, linenum, 'runtime/arrays', 1,
2367
'Do not use variable-length arrays. Use an appropriately named '
2368
"('k' followed by CamelCase) compile-time constant for the size.")
2370
# If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or
2371
# DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing
2372
# in the class declaration.
2375
r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'
2378
if match and linenum + 1 < clean_lines.NumLines():
2379
next_line = clean_lines.elided[linenum + 1]
2380
if not Search(r'^\s*};', next_line):
2381
error(filename, linenum, 'readability/constructors', 3,
2382
match.group(1) + ' should be the last thing in the class')
2384
# Check for use of unnamed namespaces in header files. Registration
2385
# macros are typically OK, so we allow use of "namespace {" on lines
2386
# that end with backslashes.
2387
if (file_extension == 'h'
2388
and Search(r'\bnamespace\s*{', line)
2389
and line[-1] != '\\'):
2390
error(filename, linenum, 'build/namespaces', 4,
2391
'Do not use unnamed namespaces in header files. See '
2392
'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2393
' for more information.')
2396
def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
2398
"""Checks for a C-style cast by looking for the pattern.
2400
This also handles sizeof(type) warnings, due to similarity of content.
2403
filename: The name of the current file.
2404
linenum: The number of the line to check.
2405
line: The line of code to check.
2406
raw_line: The raw line of code to check, with comments.
2407
cast_type: The string for the C++ cast to recommend. This is either
2408
reinterpret_cast or static_cast, depending.
2409
pattern: The regular expression used to find C-style casts.
2410
error: The function to call with any errors found.
2412
match = Search(pattern, line)
2417
sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
2419
error(filename, linenum, 'runtime/sizeof', 1,
2420
'Using sizeof(type). Use sizeof(varname) instead if possible')
2423
remainder = line[match.end(0):]
2425
# The close paren is for function pointers as arguments to a function.
2426
# eg, void foo(void (*bar)(int));
2427
# The semicolon check is a more basic function check; also possibly a
2428
# function pointer typedef.
2429
# eg, void foo(int); or void foo(int) const;
2430
# The equals check is for function pointer assignment.
2431
# eg, void *(*foo)(int) = ...
2433
# Right now, this will only catch cases where there's a single argument, and
2434
# it's unnamed. It should probably be expanded to check for multiple
2435
# arguments with some unnamed.
2436
function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder)
2438
if (not function_match.group(3) or
2439
function_match.group(3) == ';' or
2440
raw_line.find('/*') < 0):
2441
error(filename, linenum, 'readability/function', 3,
2442
'All parameters should be named in a function')
2445
# At this point, all that should be left is actual casts.
2446
error(filename, linenum, 'readability/casting', 4,
2447
'Using C-style cast. Use %s<%s>(...) instead' %
2448
(cast_type, match.group(1)))
2451
_HEADERS_CONTAINING_TEMPLATES = (
2452
('<deque>', ('deque',)),
2453
('<functional>', ('unary_function', 'binary_function',
2454
'plus', 'minus', 'multiplies', 'divides', 'modulus',
2456
'equal_to', 'not_equal_to', 'greater', 'less',
2457
'greater_equal', 'less_equal',
2458
'logical_and', 'logical_or', 'logical_not',
2459
'unary_negate', 'not1', 'binary_negate', 'not2',
2460
'bind1st', 'bind2nd',
2461
'pointer_to_unary_function',
2462
'pointer_to_binary_function',
2464
'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
2466
'const_mem_fun_t', 'const_mem_fun1_t',
2467
'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
2470
('<limits>', ('numeric_limits',)),
2471
('<list>', ('list',)),
2472
('<map>', ('map', 'multimap',)),
2473
('<memory>', ('allocator',)),
2474
('<queue>', ('queue', 'priority_queue',)),
2475
('<set>', ('set', 'multiset',)),
2476
('<stack>', ('stack',)),
2477
('<string>', ('char_traits', 'basic_string',)),
2478
('<utility>', ('pair',)),
2479
('<vector>', ('vector',)),
2482
# Note: std::hash is their hash, ::hash is our hash
2483
('<hash_map>', ('hash_map', 'hash_multimap',)),
2484
('<hash_set>', ('hash_set', 'hash_multiset',)),
2485
('<slist>', ('slist',)),
2488
_HEADERS_ACCEPTED_BUT_NOT_PROMOTED = {
2489
# We can trust with reasonable confidence that map gives us pair<>, too.
2490
'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap')
2493
_RE_PATTERN_STRING = re.compile(r'\bstring\b')
2495
_re_pattern_algorithm_header = []
2496
for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
2498
# Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
2500
_re_pattern_algorithm_header.append(
2501
(re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
2505
_re_pattern_templates = []
2506
for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
2507
for _template in _templates:
2508
_re_pattern_templates.append(
2509
(re.compile(r'(\<|\b)' + _template + r'\s*\<'),
2514
def FilesBelongToSameModule(filename_cc, filename_h):
2515
"""Check if these two filenames belong to the same module.
2517
The concept of a 'module' here is a as follows:
2518
foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the
2519
same 'module' if they are in the same directory.
2520
some/path/public/xyzzy and some/path/internal/xyzzy are also considered
2521
to belong to the same module here.
2523
If the filename_cc contains a longer path than the filename_h, for example,
2524
'/absolute/path/to/base/sysinfo.cc', and this file would include
2525
'base/sysinfo.h', this function also produces the prefix needed to open the
2526
header. This is used by the caller of this function to more robustly open the
2527
header file. We don't have access to the real include paths in this context,
2528
so we need this guesswork here.
2530
Known bugs: tools/base/bar.cc and base/bar.h belong to the same module
2531
according to this implementation. Because of this, this function gives
2532
some false positives. This should be sufficiently rare in practice.
2535
filename_cc: is the path for the .cc file
2536
filename_h: is the path for the header path
2539
Tuple with a bool and a string:
2540
bool: True if filename_cc and filename_h belong to the same module.
2541
string: the additional prefix needed to open the header file.
2544
if not filename_cc.endswith('.cc'):
2546
filename_cc = filename_cc[:-len('.cc')]
2547
if filename_cc.endswith('_unittest'):
2548
filename_cc = filename_cc[:-len('_unittest')]
2549
elif filename_cc.endswith('_test'):
2550
filename_cc = filename_cc[:-len('_test')]
2551
filename_cc = filename_cc.replace('/public/', '/')
2552
filename_cc = filename_cc.replace('/internal/', '/')
2554
if not filename_h.endswith('.h'):
2556
filename_h = filename_h[:-len('.h')]
2557
if filename_h.endswith('-inl'):
2558
filename_h = filename_h[:-len('-inl')]
2559
filename_h = filename_h.replace('/public/', '/')
2560
filename_h = filename_h.replace('/internal/', '/')
2562
files_belong_to_same_module = filename_cc.endswith(filename_h)
2564
if files_belong_to_same_module:
2565
common_path = filename_cc[:-len(filename_h)]
2566
return files_belong_to_same_module, common_path
2569
def UpdateIncludeState(filename, include_state, io=codecs):
2570
"""Fill up the include_state with new includes found from the file.
2573
filename: the name of the header to read.
2574
include_state: an _IncludeState instance in which the headers are inserted.
2575
io: The io factory to use to read the file. Provided for testability.
2578
True if a header was succesfully added. False otherwise.
2582
headerfile = io.open(filename, 'r', 'utf8', 'replace')
2586
for line in headerfile:
2588
clean_line = CleanseComments(line)
2589
match = _RE_PATTERN_INCLUDE.search(clean_line)
2591
include = match.group(2)
2592
# The value formatting is cute, but not really used right now.
2593
# What matters here is that the key is in include_state.
2594
include_state.setdefault(include, '%s:%d' % (filename, linenum))
2598
def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
2600
"""Reports for missing stl includes.
2602
This function will output warnings to make sure you are including the headers
2603
necessary for the stl containers and functions that you use. We only give one
2604
reason to include a header. For example, if you use both equal_to<> and
2605
less<> in a .h file, only one (the latter in the file) of these will be
2606
reported as a reason to include the <functional>.
2609
filename: The name of the current file.
2610
clean_lines: A CleansedLines instance containing the file.
2611
include_state: An _IncludeState instance.
2612
error: The function to call with any errors found.
2613
io: The IO factory to use to read the header file. Provided for unittest
2616
required = {} # A map of header name to linenumber and the template entity.
2617
# Example of required: { '<functional>': (1219, 'less<>') }
2619
for linenum in xrange(clean_lines.NumLines()):
2620
line = clean_lines.elided[linenum]
2621
if not line or line[0] == '#':
2624
# String is special -- it is a non-templatized type in STL.
2625
if _RE_PATTERN_STRING.search(line):
2626
required['<string>'] = (linenum, 'string')
2628
for pattern, template, header in _re_pattern_algorithm_header:
2629
if pattern.search(line):
2630
required[header] = (linenum, template)
2632
# The following function is just a speed up, no semantics are changed.
2633
if not '<' in line: # Reduces the cpu time usage by skipping lines.
2636
for pattern, template, header in _re_pattern_templates:
2637
if pattern.search(line):
2638
required[header] = (linenum, template)
2640
# The policy is that if you #include something in foo.h you don't need to
2641
# include it again in foo.cc. Here, we will look at possible includes.
2642
# Let's copy the include_state so it is only messed up within this function.
2643
include_state = include_state.copy()
2645
# Did we find the header for this file (if any) and succesfully load it?
2646
header_found = False
2648
# Use the absolute path so that matching works properly.
2649
abs_filename = os.path.abspath(filename)
2651
# For Emacs's flymake.
2652
# If cpplint is invoked from Emacs's flymake, a temporary file is generated
2653
# by flymake and that file name might end with '_flymake.cc'. In that case,
2654
# restore original file name here so that the corresponding header file can be
2656
# e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
2657
# instead of 'foo_flymake.h'
2658
emacs_flymake_suffix = '_flymake.cc'
2659
if abs_filename.endswith(emacs_flymake_suffix):
2660
abs_filename = abs_filename[:-len(emacs_flymake_suffix)] + '.cc'
2662
# include_state is modified during iteration, so we iterate over a copy of
2664
for header in include_state.keys(): #NOLINT
2665
(same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
2666
fullpath = common_path + header
2667
if same_module and UpdateIncludeState(fullpath, include_state, io):
2670
# If we can't find the header file for a .cc, assume it's because we don't
2671
# know where to look. In that case we'll give up as we're not sure they
2672
# didn't include it in the .h file.
2673
# TODO(unknown): Do a better job of finding .h files so we are confident that
2674
# not having the .h file means there isn't one.
2675
if filename.endswith('.cc') and not header_found:
2678
# All the lines have been processed, report the errors found.
2679
for required_header_unstripped in required:
2680
template = required[required_header_unstripped][1]
2681
if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED:
2682
headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template]
2683
if [True for header in headers if header in include_state]:
2685
if required_header_unstripped.strip('<>"') not in include_state:
2686
error(filename, required[required_header_unstripped][0],
2687
'build/include_what_you_use', 4,
2688
'Add #include ' + required_header_unstripped + ' for ' + template)
2691
def ProcessLine(filename, file_extension,
2692
clean_lines, line, include_state, function_state,
2693
class_state, error):
2694
"""Processes a single line in the file.
2697
filename: Filename of the file that is being processed.
2698
file_extension: The extension (dot not included) of the file.
2699
clean_lines: An array of strings, each representing a line of the file,
2700
with comments stripped.
2701
line: Number of line being processed.
2702
include_state: An _IncludeState instance in which the headers are inserted.
2703
function_state: A _FunctionState instance which counts function lines, etc.
2704
class_state: A _ClassState instance which maintains information about
2705
the current stack of nested class declarations being parsed.
2706
error: A callable to which errors are reported, which takes 4 arguments:
2707
filename, line number, error level, and message
2710
raw_lines = clean_lines.raw_lines
2711
CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
2712
if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines
2714
CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
2715
CheckStyle(filename, clean_lines, line, file_extension, error)
2716
CheckLanguage(filename, clean_lines, line, file_extension, include_state,
2718
CheckForNonStandardConstructs(filename, clean_lines, line,
2720
CheckPosixThreading(filename, clean_lines, line, error)
2721
CheckInvalidIncrement(filename, clean_lines, line, error)
2724
def ProcessFileData(filename, file_extension, lines, error):
2725
"""Performs lint checks and reports any errors to the given error function.
2728
filename: Filename of the file that is being processed.
2729
file_extension: The extension (dot not included) of the file.
2730
lines: An array of strings, each representing a line of the file, with the
2731
last element being empty if the file is termined with a newline.
2732
error: A callable to which errors are reported, which takes 4 arguments:
2734
lines = (['// marker so line numbers and indices both start at 1'] + lines +
2735
['// marker so line numbers end in a known way'])
2737
include_state = _IncludeState()
2738
function_state = _FunctionState()
2739
class_state = _ClassState()
2741
CheckForCopyright(filename, lines, error)
2743
if file_extension == 'h':
2744
CheckForHeaderGuard(filename, lines, error)
2746
RemoveMultiLineComments(filename, lines, error)
2747
clean_lines = CleansedLines(lines)
2748
for line in xrange(clean_lines.NumLines()):
2749
ProcessLine(filename, file_extension, clean_lines, line,
2750
include_state, function_state, class_state, error)
2751
class_state.CheckFinished(filename, error)
2753
CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
2755
# We check here rather than inside ProcessLine so that we see raw
2756
# lines rather than "cleaned" lines.
2757
CheckForUnicodeReplacementCharacters(filename, lines, error)
2759
CheckForNewlineAtEOF(filename, lines, error)
2762
def ProcessFile(filename, vlevel):
2763
"""Does google-lint on a single file.
2766
filename: The name of the file to parse.
2768
vlevel: The level of errors to report. Every error of confidence
2769
>= verbose_level will be reported. 0 is a good default.
2772
_SetVerboseLevel(vlevel)
2775
# Support the UNIX convention of using "-" for stdin. Note that
2776
# we are not opening the file with universal newline support
2777
# (which codecs doesn't support anyway), so the resulting lines do
2778
# contain trailing '\r' characters if we are reading a file that
2780
# If after the split a trailing '\r' is present, it is removed
2781
# below. If it is not expected to be present (i.e. os.linesep !=
2782
# '\r\n' as in Windows), a warning is issued below if this file
2786
lines = codecs.StreamReaderWriter(sys.stdin,
2787
codecs.getreader('utf8'),
2788
codecs.getwriter('utf8'),
2789
'replace').read().split('\n')
2791
lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
2793
carriage_return_found = False
2794
# Remove trailing '\r'.
2795
for linenum in range(len(lines)):
2796
if lines[linenum].endswith('\r'):
2797
lines[linenum] = lines[linenum].rstrip('\r')
2798
carriage_return_found = True
2802
"Skipping input '%s': Can't open for reading\n" % filename)
2805
# Note, if no dot is found, this will give the entire filename as the ext.
2806
file_extension = filename[filename.rfind('.') + 1:]
2808
# When reading from stdin, the extension is unknown, so no cpplint tests
2809
# should rely on the extension.
2810
if (filename != '-' and file_extension != 'cc' and file_extension != 'h'
2811
and file_extension != 'cpp'):
2812
sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename)
2814
ProcessFileData(filename, file_extension, lines, Error)
2815
if carriage_return_found and os.linesep != '\r\n':
2816
# Use 0 for linenum since outputing only one error for potentially
2818
Error(filename, 0, 'whitespace/newline', 1,
2819
'One or more unexpected \\r (^M) found;'
2820
'better to use only a \\n')
2822
sys.stderr.write('Done processing %s\n' % filename)
2825
def PrintUsage(message):
2826
"""Prints a brief usage string and exits, optionally with an error message.
2829
message: The optional error message.
2831
sys.stderr.write(_USAGE)
2833
sys.exit('\nFATAL ERROR: ' + message)
2838
def PrintCategories():
2839
"""Prints a list of all the error-categories used by error messages.
2841
These are the categories used to filter messages via --filter.
2843
sys.stderr.write(_ERROR_CATEGORIES)
2847
def ParseArguments(args):
2848
"""Parses the command line arguments.
2850
This may set the output format and verbosity level as side-effects.
2853
args: The command line arguments:
2856
The list of filenames to lint.
2859
(opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
2861
except getopt.GetoptError:
2862
PrintUsage('Invalid arguments.')
2864
verbosity = _VerboseLevel()
2865
output_format = _OutputFormat()
2868
for (opt, val) in opts:
2871
elif opt == '--output':
2872
if not val in ('emacs', 'vs7'):
2873
PrintUsage('The only allowed output formats are emacs and vs7.')
2875
elif opt == '--verbose':
2876
verbosity = int(val)
2877
elif opt == '--filter':
2883
PrintUsage('No files were specified.')
2885
_SetOutputFormat(output_format)
2886
_SetVerboseLevel(verbosity)
2887
_SetFilters(filters)
2893
filenames = ParseArguments(sys.argv[1:])
2895
# Change stderr to write with replacement characters so we don't die
2896
# if we try to print something containing non-ASCII characters.
2897
sys.stderr = codecs.StreamReaderWriter(sys.stderr,
2898
codecs.getreader('utf8'),
2899
codecs.getwriter('utf8'),
2902
_cpplint_state.ResetErrorCount()
2903
for filename in filenames:
2904
ProcessFile(filename, _cpplint_state.verbose_level)
2905
sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count)
2906
sys.exit(_cpplint_state.error_count > 0)
2909
if __name__ == '__main__':