blob: 8bd90c2c30b083cf493e15df3d72878776db9289 [file] [log] [blame]
erg@chromium.orgd528f8b2012-05-11 17:31:08 +00001#!/usr/bin/env python
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002#
erg@google.com26970fa2009-11-17 18:07:32 +00003# Copyright (c) 2009 Google Inc. All rights reserved.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004#
erg@google.com26970fa2009-11-17 18:07:32 +00005# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00008#
erg@google.com26970fa2009-11-17 18:07:32 +00009# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000018#
erg@google.com26970fa2009-11-17 18:07:32 +000019# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000030
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000031"""Does google-lint on c++ files.
32
33The goal of this script is to identify places in the code that *may*
34be in non-compliance with google style. It does not attempt to fix
35up these problems -- the point is to educate. It does also not
36attempt to find all problems, or to ensure that everything it does
37find is legitimately a problem.
38
39In particular, we can get very confused by /* and // inside strings!
40We do a small hack, which is to ignore //'s with "'s after them on the
41same line, but it is far from perfect (in either direction).
42"""
43
44import codecs
mazda@chromium.org3fffcec2013-06-07 01:04:53 +000045import copy
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000046import getopt
47import math # for log
48import os
49import re
50import sre_compile
51import string
52import sys
53import unicodedata
54
55
56_USAGE = """
57Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +000058 [--counting=total|toplevel|detailed] [--root=subdir]
59 [--linelength=digits]
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000060 <file> [file] ...
61
62 The style guidelines this tries to follow are those in
63 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
64
65 Every problem is given a confidence score from 1-5, with 5 meaning we are
66 certain of the problem, and 1 meaning it could be a legitimate construct.
67 This will miss some errors, and is not a substitute for a code review.
68
erg@google.com35589e62010-11-17 18:58:16 +000069 To suppress false-positive errors of a certain category, add a
70 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*)
71 suppresses errors of all categories on that line.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000072
73 The files passed in will be linted; at least one file must be provided.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +000074 Default linted extensions are .cc, .cpp, .cu, .cuh and .h. Change the
75 extensions with the --extensions flag.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +000076
77 Flags:
78
79 output=vs7
80 By default, the output is formatted to ease emacs parsing. Visual Studio
81 compatible output (vs7) may also be used. Other formats are unsupported.
82
83 verbose=#
84 Specify a number 0-5 to restrict errors to certain verbosity levels.
85
86 filter=-x,+y,...
87 Specify a comma-separated list of category-filters to apply: only
88 error messages whose category names pass the filters will be printed.
89 (Category names are printed with the message and look like
90 "[whitespace/indent]".) Filters are evaluated left to right.
91 "-FOO" and "FOO" means "do not print categories that start with FOO".
92 "+FOO" means "do print categories that start with FOO".
93
94 Examples: --filter=-whitespace,+whitespace/braces
95 --filter=whitespace,runtime/printf,+runtime/printf_format
96 --filter=-,+build/include_what_you_use
97
98 To see a list of all the categories used in cpplint, pass no arg:
99 --filter=
erg@google.com26970fa2009-11-17 18:07:32 +0000100
101 counting=total|toplevel|detailed
102 The total number of errors found is always printed. If
103 'toplevel' is provided, then the count of errors in each of
104 the top-level categories like 'build' and 'whitespace' will
105 also be printed. If 'detailed' is provided, then a count
106 is provided for each category like 'build/class'.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000107
108 root=subdir
109 The root directory used for deriving header guard CPP variable.
110 By default, the header guard CPP variable is calculated as the relative
111 path to the directory that contains .git, .hg, or .svn. When this flag
112 is specified, the relative path is calculated from the specified
113 directory. If the specified directory does not exist, this flag is
114 ignored.
115
116 Examples:
117 Assuing that src/.git exists, the header guard CPP variables for
118 src/chrome/browser/ui/browser.h are:
119
120 No flag => CHROME_BROWSER_UI_BROWSER_H_
121 --root=chrome => BROWSER_UI_BROWSER_H_
122 --root=chrome/browser => UI_BROWSER_H_
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000123
124 linelength=digits
125 This is the allowed line length for the project. The default value is
126 80 characters.
127
128 Examples:
129 --linelength=120
130
131 extensions=extension,extension,...
132 The allowed file extensions that cpplint will check
133
134 Examples:
135 --extensions=hpp,cpp
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000136"""
137
138# We categorize each error message we print. Here are the categories.
139# We want an explicit list so we can list them all in cpplint --filter=.
140# If you add a new error message with a new category, add it to the list
141# here! cpplint_unittest.py should tell you if you forget to do this.
erg@google.com35589e62010-11-17 18:58:16 +0000142_ERROR_CATEGORIES = [
143 'build/class',
144 'build/deprecated',
145 'build/endif_comment',
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000146 'build/explicit_make_pair',
erg@google.com35589e62010-11-17 18:58:16 +0000147 'build/forward_decl',
148 'build/header_guard',
149 'build/include',
150 'build/include_alpha',
151 'build/include_order',
152 'build/include_what_you_use',
153 'build/namespaces',
154 'build/printf_format',
155 'build/storage_class',
156 'legal/copyright',
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000157 'readability/alt_tokens',
erg@google.com35589e62010-11-17 18:58:16 +0000158 'readability/braces',
159 'readability/casting',
160 'readability/check',
161 'readability/constructors',
162 'readability/fn_size',
163 'readability/function',
164 'readability/multiline_comment',
165 'readability/multiline_string',
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000166 'readability/namespace',
erg@google.com35589e62010-11-17 18:58:16 +0000167 'readability/nolint',
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000168 'readability/nul',
erg@google.com35589e62010-11-17 18:58:16 +0000169 'readability/streams',
170 'readability/todo',
171 'readability/utf8',
172 'runtime/arrays',
173 'runtime/casting',
174 'runtime/explicit',
175 'runtime/int',
176 'runtime/init',
177 'runtime/invalid_increment',
178 'runtime/member_string_references',
179 'runtime/memset',
180 'runtime/operator',
181 'runtime/printf',
182 'runtime/printf_format',
183 'runtime/references',
erg@google.com35589e62010-11-17 18:58:16 +0000184 'runtime/string',
185 'runtime/threadsafe_fn',
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000186 'runtime/vlog',
erg@google.com35589e62010-11-17 18:58:16 +0000187 'whitespace/blank_line',
188 'whitespace/braces',
189 'whitespace/comma',
190 'whitespace/comments',
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000191 'whitespace/empty_conditional_body',
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000192 'whitespace/empty_loop_body',
erg@google.com35589e62010-11-17 18:58:16 +0000193 'whitespace/end_of_line',
194 'whitespace/ending_newline',
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000195 'whitespace/forcolon',
erg@google.com35589e62010-11-17 18:58:16 +0000196 'whitespace/indent',
erg@google.com35589e62010-11-17 18:58:16 +0000197 'whitespace/line_length',
198 'whitespace/newline',
199 'whitespace/operators',
200 'whitespace/parens',
201 'whitespace/semicolon',
202 'whitespace/tab',
203 'whitespace/todo'
204 ]
erg@google.com6317a9c2009-06-25 00:28:19 +0000205
206# The default state of the category filter. This is overrided by the --filter=
207# flag. By default all errors are on, so only add here categories that should be
208# off by default (i.e., categories that must be enabled by the --filter= flags).
209# All entries here should start with a '-' or '+', as in the --filter= flag.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000210_DEFAULT_FILTERS = ['-build/include_alpha']
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000211
212# We used to check for high-bit characters, but after much discussion we
213# decided those were OK, as long as they were in UTF-8 and didn't represent
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000214# hard-coded international strings, which belong in a separate i18n file.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000215
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000216
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000217# C++ headers
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000218_CPP_HEADERS = frozenset([
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000219 # Legacy
220 'algobase.h',
221 'algo.h',
222 'alloc.h',
223 'builtinbuf.h',
224 'bvector.h',
225 'complex.h',
226 'defalloc.h',
227 'deque.h',
228 'editbuf.h',
229 'fstream.h',
230 'function.h',
231 'hash_map',
232 'hash_map.h',
233 'hash_set',
234 'hash_set.h',
235 'hashtable.h',
236 'heap.h',
237 'indstream.h',
238 'iomanip.h',
239 'iostream.h',
240 'istream.h',
241 'iterator.h',
242 'list.h',
243 'map.h',
244 'multimap.h',
245 'multiset.h',
246 'ostream.h',
247 'pair.h',
248 'parsestream.h',
249 'pfstream.h',
250 'procbuf.h',
251 'pthread_alloc',
252 'pthread_alloc.h',
253 'rope',
254 'rope.h',
255 'ropeimpl.h',
256 'set.h',
257 'slist',
258 'slist.h',
259 'stack.h',
260 'stdiostream.h',
261 'stl_alloc.h',
262 'stl_relops.h',
263 'streambuf.h',
264 'stream.h',
265 'strfile.h',
266 'strstream.h',
267 'tempbuf.h',
268 'tree.h',
269 'type_traits.h',
270 'vector.h',
271 # 17.6.1.2 C++ library headers
272 'algorithm',
273 'array',
274 'atomic',
275 'bitset',
276 'chrono',
277 'codecvt',
278 'complex',
279 'condition_variable',
280 'deque',
281 'exception',
282 'forward_list',
283 'fstream',
284 'functional',
285 'future',
286 'initializer_list',
287 'iomanip',
288 'ios',
289 'iosfwd',
290 'iostream',
291 'istream',
292 'iterator',
293 'limits',
294 'list',
295 'locale',
296 'map',
297 'memory',
298 'mutex',
299 'new',
300 'numeric',
301 'ostream',
302 'queue',
303 'random',
304 'ratio',
305 'regex',
306 'set',
307 'sstream',
308 'stack',
309 'stdexcept',
310 'streambuf',
311 'string',
312 'strstream',
313 'system_error',
314 'thread',
315 'tuple',
316 'typeindex',
317 'typeinfo',
318 'type_traits',
319 'unordered_map',
320 'unordered_set',
321 'utility',
322 'valarray',
323 'vector',
324 # 17.6.1.2 C++ headers for C library facilities
325 'cassert',
326 'ccomplex',
327 'cctype',
328 'cerrno',
329 'cfenv',
330 'cfloat',
331 'cinttypes',
332 'ciso646',
333 'climits',
334 'clocale',
335 'cmath',
336 'csetjmp',
337 'csignal',
338 'cstdalign',
339 'cstdarg',
340 'cstdbool',
341 'cstddef',
342 'cstdint',
343 'cstdio',
344 'cstdlib',
345 'cstring',
346 'ctgmath',
347 'ctime',
348 'cuchar',
349 'cwchar',
350 'cwctype',
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000351 ])
352
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000353# Assertion macros. These are defined in base/logging.h and
354# testing/base/gunit.h. Note that the _M versions need to come first
355# for substring matching to work.
356_CHECK_MACROS = [
erg@google.com6317a9c2009-06-25 00:28:19 +0000357 'DCHECK', 'CHECK',
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000358 'EXPECT_TRUE_M', 'EXPECT_TRUE',
359 'ASSERT_TRUE_M', 'ASSERT_TRUE',
360 'EXPECT_FALSE_M', 'EXPECT_FALSE',
361 'ASSERT_FALSE_M', 'ASSERT_FALSE',
362 ]
363
erg@google.com6317a9c2009-06-25 00:28:19 +0000364# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000365_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
366
367for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
368 ('>=', 'GE'), ('>', 'GT'),
369 ('<=', 'LE'), ('<', 'LT')]:
erg@google.com6317a9c2009-06-25 00:28:19 +0000370 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000371 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
372 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
373 _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
374 _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
375 _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
376
377for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
378 ('>=', 'LT'), ('>', 'LE'),
379 ('<=', 'GT'), ('<', 'GE')]:
380 _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
381 _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
382 _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
383 _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
384
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000385# Alternative tokens and their replacements. For full list, see section 2.5
386# Alternative tokens [lex.digraph] in the C++ standard.
387#
388# Digraphs (such as '%:') are not included here since it's a mess to
389# match those on a word boundary.
390_ALT_TOKEN_REPLACEMENT = {
391 'and': '&&',
392 'bitor': '|',
393 'or': '||',
394 'xor': '^',
395 'compl': '~',
396 'bitand': '&',
397 'and_eq': '&=',
398 'or_eq': '|=',
399 'xor_eq': '^=',
400 'not': '!',
401 'not_eq': '!='
402 }
403
404# Compile regular expression that matches all the above keywords. The "[ =()]"
405# bit is meant to avoid matching these keywords outside of boolean expressions.
406#
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000407# False positives include C-style multi-line comments and multi-line strings
408# but those have always been troublesome for cpplint.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000409_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile(
410 r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)')
411
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000412
413# These constants define types of headers for use with
414# _IncludeState.CheckNextIncludeOrder().
415_C_SYS_HEADER = 1
416_CPP_SYS_HEADER = 2
417_LIKELY_MY_HEADER = 3
418_POSSIBLE_MY_HEADER = 4
419_OTHER_HEADER = 5
420
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000421# These constants define the current inline assembly state
422_NO_ASM = 0 # Outside of inline assembly block
423_INSIDE_ASM = 1 # Inside inline assembly block
424_END_ASM = 2 # Last line of inline assembly block
425_BLOCK_ASM = 3 # The whole block is an inline assembly block
426
427# Match start of assembly blocks
428_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)'
429 r'(?:\s+(volatile|__volatile__))?'
430 r'\s*[{(]')
431
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000432
433_regexp_compile_cache = {}
434
erg@google.com35589e62010-11-17 18:58:16 +0000435# Finds occurrences of NOLINT or NOLINT(...).
436_RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?')
437
438# {str, set(int)}: a map from error categories to sets of linenumbers
439# on which those errors are expected and should be suppressed.
440_error_suppressions = {}
441
mazda@chromium.org3fffcec2013-06-07 01:04:53 +0000442# The root directory used for deriving header guard CPP variable.
443# This is set by --root flag.
444_root = None
445
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000446# The allowed line length of files.
447# This is set by --linelength flag.
448_line_length = 80
449
450# The allowed extensions for file names
451# This is set by --extensions flag.
452_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh'])
453
erg@google.com35589e62010-11-17 18:58:16 +0000454def ParseNolintSuppressions(filename, raw_line, linenum, error):
455 """Updates the global list of error-suppressions.
456
457 Parses any NOLINT comments on the current line, updating the global
458 error_suppressions store. Reports an error if the NOLINT comment
459 was malformed.
460
461 Args:
462 filename: str, the name of the input file.
463 raw_line: str, the line of input text, with comments.
464 linenum: int, the number of the current line.
465 error: function, an error handler.
466 """
467 # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*).
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000468 matched = _RE_SUPPRESSION.search(raw_line)
469 if matched:
470 category = matched.group(1)
erg@google.com35589e62010-11-17 18:58:16 +0000471 if category in (None, '(*)'): # => "suppress all"
472 _error_suppressions.setdefault(None, set()).add(linenum)
473 else:
474 if category.startswith('(') and category.endswith(')'):
475 category = category[1:-1]
476 if category in _ERROR_CATEGORIES:
477 _error_suppressions.setdefault(category, set()).add(linenum)
478 else:
479 error(filename, linenum, 'readability/nolint', 5,
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000480 'Unknown NOLINT error category: %s' % category)
erg@google.com35589e62010-11-17 18:58:16 +0000481
482
483def ResetNolintSuppressions():
484 "Resets the set of NOLINT suppressions to empty."
485 _error_suppressions.clear()
486
487
488def IsErrorSuppressedByNolint(category, linenum):
489 """Returns true if the specified error category is suppressed on this line.
490
491 Consults the global error_suppressions map populated by
492 ParseNolintSuppressions/ResetNolintSuppressions.
493
494 Args:
495 category: str, the category of the error.
496 linenum: int, the current line number.
497 Returns:
498 bool, True iff the error should be suppressed due to a NOLINT comment.
499 """
500 return (linenum in _error_suppressions.get(category, set()) or
501 linenum in _error_suppressions.get(None, set()))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000502
503def Match(pattern, s):
504 """Matches the string with the pattern, caching the compiled regexp."""
505 # The regexp compilation caching is inlined in both Match and Search for
506 # performance reasons; factoring it out into a separate function turns out
507 # to be noticeably expensive.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000508 if pattern not in _regexp_compile_cache:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000509 _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
510 return _regexp_compile_cache[pattern].match(s)
511
512
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000513def ReplaceAll(pattern, rep, s):
514 """Replaces instances of pattern in a string with a replacement.
515
516 The compiled regex is kept in a cache shared by Match and Search.
517
518 Args:
519 pattern: regex pattern
520 rep: replacement text
521 s: search string
522
523 Returns:
524 string with replacements made (or original string if no replacements)
525 """
526 if pattern not in _regexp_compile_cache:
527 _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
528 return _regexp_compile_cache[pattern].sub(rep, s)
529
530
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000531def Search(pattern, s):
532 """Searches the string for the pattern, caching the compiled regexp."""
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000533 if pattern not in _regexp_compile_cache:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000534 _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
535 return _regexp_compile_cache[pattern].search(s)
536
537
538class _IncludeState(dict):
539 """Tracks line numbers for includes, and the order in which includes appear.
540
541 As a dict, an _IncludeState object serves as a mapping between include
542 filename and line number on which that file was included.
543
544 Call CheckNextIncludeOrder() once for each header in the file, passing
545 in the type constants defined above. Calls in an illegal order will
546 raise an _IncludeError with an appropriate error message.
547
548 """
549 # self._section will move monotonically through this set. If it ever
550 # needs to move backwards, CheckNextIncludeOrder will raise an error.
551 _INITIAL_SECTION = 0
552 _MY_H_SECTION = 1
553 _C_SECTION = 2
554 _CPP_SECTION = 3
555 _OTHER_H_SECTION = 4
556
557 _TYPE_NAMES = {
558 _C_SYS_HEADER: 'C system header',
559 _CPP_SYS_HEADER: 'C++ system header',
560 _LIKELY_MY_HEADER: 'header this file implements',
561 _POSSIBLE_MY_HEADER: 'header this file may implement',
562 _OTHER_HEADER: 'other header',
563 }
564 _SECTION_NAMES = {
565 _INITIAL_SECTION: "... nothing. (This can't be an error.)",
566 _MY_H_SECTION: 'a header this file implements',
567 _C_SECTION: 'C system header',
568 _CPP_SECTION: 'C++ system header',
569 _OTHER_H_SECTION: 'other header',
570 }
571
572 def __init__(self):
573 dict.__init__(self)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000574 self.ResetSection()
575
576 def ResetSection(self):
erg@google.com26970fa2009-11-17 18:07:32 +0000577 # The name of the current section.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000578 self._section = self._INITIAL_SECTION
erg@google.com26970fa2009-11-17 18:07:32 +0000579 # The path of last found header.
580 self._last_header = ''
581
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000582 def SetLastHeader(self, header_path):
583 self._last_header = header_path
584
erg@google.com26970fa2009-11-17 18:07:32 +0000585 def CanonicalizeAlphabeticalOrder(self, header_path):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000586 """Returns a path canonicalized for alphabetical comparison.
erg@google.com26970fa2009-11-17 18:07:32 +0000587
588 - replaces "-" with "_" so they both cmp the same.
589 - removes '-inl' since we don't require them to be after the main header.
590 - lowercase everything, just in case.
591
592 Args:
593 header_path: Path to be canonicalized.
594
595 Returns:
596 Canonicalized path.
597 """
598 return header_path.replace('-inl.h', '.h').replace('-', '_').lower()
599
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000600 def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path):
erg@google.com26970fa2009-11-17 18:07:32 +0000601 """Check if a header is in alphabetical order with the previous header.
602
603 Args:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000604 clean_lines: A CleansedLines instance containing the file.
605 linenum: The number of the line to check.
606 header_path: Canonicalized header to be checked.
erg@google.com26970fa2009-11-17 18:07:32 +0000607
608 Returns:
609 Returns true if the header is in alphabetical order.
610 """
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +0000611 # If previous section is different from current section, _last_header will
612 # be reset to empty string, so it's always less than current header.
613 #
614 # If previous line was a blank line, assume that the headers are
615 # intentionally sorted the way they are.
616 if (self._last_header > header_path and
617 not Match(r'^\s*$', clean_lines.elided[linenum - 1])):
erg@google.com26970fa2009-11-17 18:07:32 +0000618 return False
erg@google.com26970fa2009-11-17 18:07:32 +0000619 return True
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000620
621 def CheckNextIncludeOrder(self, header_type):
622 """Returns a non-empty error message if the next header is out of order.
623
624 This function also updates the internal state to be ready to check
625 the next include.
626
627 Args:
628 header_type: One of the _XXX_HEADER constants defined above.
629
630 Returns:
631 The empty string if the header is in the right order, or an
632 error message describing what's wrong.
633
634 """
635 error_message = ('Found %s after %s' %
636 (self._TYPE_NAMES[header_type],
637 self._SECTION_NAMES[self._section]))
638
erg@google.com26970fa2009-11-17 18:07:32 +0000639 last_section = self._section
640
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000641 if header_type == _C_SYS_HEADER:
642 if self._section <= self._C_SECTION:
643 self._section = self._C_SECTION
644 else:
erg@google.com26970fa2009-11-17 18:07:32 +0000645 self._last_header = ''
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000646 return error_message
647 elif header_type == _CPP_SYS_HEADER:
648 if self._section <= self._CPP_SECTION:
649 self._section = self._CPP_SECTION
650 else:
erg@google.com26970fa2009-11-17 18:07:32 +0000651 self._last_header = ''
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000652 return error_message
653 elif header_type == _LIKELY_MY_HEADER:
654 if self._section <= self._MY_H_SECTION:
655 self._section = self._MY_H_SECTION
656 else:
657 self._section = self._OTHER_H_SECTION
658 elif header_type == _POSSIBLE_MY_HEADER:
659 if self._section <= self._MY_H_SECTION:
660 self._section = self._MY_H_SECTION
661 else:
662 # This will always be the fallback because we're not sure
663 # enough that the header is associated with this file.
664 self._section = self._OTHER_H_SECTION
665 else:
666 assert header_type == _OTHER_HEADER
667 self._section = self._OTHER_H_SECTION
668
erg@google.com26970fa2009-11-17 18:07:32 +0000669 if last_section != self._section:
670 self._last_header = ''
671
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000672 return ''
673
674
675class _CppLintState(object):
676 """Maintains module-wide state.."""
677
678 def __init__(self):
679 self.verbose_level = 1 # global setting.
680 self.error_count = 0 # global count of reported errors
erg@google.com6317a9c2009-06-25 00:28:19 +0000681 # filters to apply when emitting error messages
682 self.filters = _DEFAULT_FILTERS[:]
erg@google.com26970fa2009-11-17 18:07:32 +0000683 self.counting = 'total' # In what way are we counting errors?
684 self.errors_by_category = {} # string to int dict storing error counts
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000685
686 # output format:
687 # "emacs" - format that emacs can parse (default)
688 # "vs7" - format that Microsoft Visual Studio 7 can parse
689 self.output_format = 'emacs'
690
691 def SetOutputFormat(self, output_format):
692 """Sets the output format for errors."""
693 self.output_format = output_format
694
695 def SetVerboseLevel(self, level):
696 """Sets the module's verbosity, and returns the previous setting."""
697 last_verbose_level = self.verbose_level
698 self.verbose_level = level
699 return last_verbose_level
700
erg@google.com26970fa2009-11-17 18:07:32 +0000701 def SetCountingStyle(self, counting_style):
702 """Sets the module's counting options."""
703 self.counting = counting_style
704
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000705 def SetFilters(self, filters):
706 """Sets the error-message filters.
707
708 These filters are applied when deciding whether to emit a given
709 error message.
710
711 Args:
712 filters: A string of comma-separated filters (eg "+whitespace/indent").
713 Each filter should start with + or -; else we die.
erg@google.com6317a9c2009-06-25 00:28:19 +0000714
715 Raises:
716 ValueError: The comma-separated filters did not all start with '+' or '-'.
717 E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000718 """
erg@google.com6317a9c2009-06-25 00:28:19 +0000719 # Default filters always have less priority than the flag ones.
720 self.filters = _DEFAULT_FILTERS[:]
721 for filt in filters.split(','):
722 clean_filt = filt.strip()
723 if clean_filt:
724 self.filters.append(clean_filt)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000725 for filt in self.filters:
726 if not (filt.startswith('+') or filt.startswith('-')):
727 raise ValueError('Every filter in --filters must start with + or -'
728 ' (%s does not)' % filt)
729
erg@google.com26970fa2009-11-17 18:07:32 +0000730 def ResetErrorCounts(self):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000731 """Sets the module's error statistic back to zero."""
732 self.error_count = 0
erg@google.com26970fa2009-11-17 18:07:32 +0000733 self.errors_by_category = {}
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000734
erg@google.com26970fa2009-11-17 18:07:32 +0000735 def IncrementErrorCount(self, category):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000736 """Bumps the module's error statistic."""
737 self.error_count += 1
erg@google.com26970fa2009-11-17 18:07:32 +0000738 if self.counting in ('toplevel', 'detailed'):
739 if self.counting != 'detailed':
740 category = category.split('/')[0]
741 if category not in self.errors_by_category:
742 self.errors_by_category[category] = 0
743 self.errors_by_category[category] += 1
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000744
erg@google.com26970fa2009-11-17 18:07:32 +0000745 def PrintErrorCounts(self):
746 """Print a summary of errors by category, and the total."""
747 for category, count in self.errors_by_category.iteritems():
748 sys.stderr.write('Category \'%s\' errors found: %d\n' %
749 (category, count))
750 sys.stderr.write('Total errors found: %d\n' % self.error_count)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000751
752_cpplint_state = _CppLintState()
753
754
755def _OutputFormat():
756 """Gets the module's output format."""
757 return _cpplint_state.output_format
758
759
760def _SetOutputFormat(output_format):
761 """Sets the module's output format."""
762 _cpplint_state.SetOutputFormat(output_format)
763
764
765def _VerboseLevel():
766 """Returns the module's verbosity setting."""
767 return _cpplint_state.verbose_level
768
769
770def _SetVerboseLevel(level):
771 """Sets the module's verbosity, and returns the previous setting."""
772 return _cpplint_state.SetVerboseLevel(level)
773
774
erg@google.com26970fa2009-11-17 18:07:32 +0000775def _SetCountingStyle(level):
776 """Sets the module's counting options."""
777 _cpplint_state.SetCountingStyle(level)
778
779
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000780def _Filters():
781 """Returns the module's list of output filters, as a list."""
782 return _cpplint_state.filters
783
784
785def _SetFilters(filters):
786 """Sets the module's error-message filters.
787
788 These filters are applied when deciding whether to emit a given
789 error message.
790
791 Args:
792 filters: A string of comma-separated filters (eg "whitespace/indent").
793 Each filter should start with + or -; else we die.
794 """
795 _cpplint_state.SetFilters(filters)
796
797
798class _FunctionState(object):
799 """Tracks current function name and the number of lines in its body."""
800
801 _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc.
802 _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER.
803
804 def __init__(self):
805 self.in_a_function = False
806 self.lines_in_function = 0
807 self.current_function = ''
808
809 def Begin(self, function_name):
810 """Start analyzing function body.
811
812 Args:
813 function_name: The name of the function being tracked.
814 """
815 self.in_a_function = True
816 self.lines_in_function = 0
817 self.current_function = function_name
818
819 def Count(self):
820 """Count line in current function body."""
821 if self.in_a_function:
822 self.lines_in_function += 1
823
824 def Check(self, error, filename, linenum):
825 """Report if too many lines in function body.
826
827 Args:
828 error: The function to call with any errors found.
829 filename: The name of the current file.
830 linenum: The number of the line to check.
831 """
832 if Match(r'T(EST|est)', self.current_function):
833 base_trigger = self._TEST_TRIGGER
834 else:
835 base_trigger = self._NORMAL_TRIGGER
836 trigger = base_trigger * 2**_VerboseLevel()
837
838 if self.lines_in_function > trigger:
839 error_level = int(math.log(self.lines_in_function / base_trigger, 2))
840 # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
841 if error_level > 5:
842 error_level = 5
843 error(filename, linenum, 'readability/fn_size', error_level,
844 'Small and focused functions are preferred:'
845 ' %s has %d non-comment lines'
846 ' (error triggered by exceeding %d lines).' % (
847 self.current_function, self.lines_in_function, trigger))
848
849 def End(self):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000850 """Stop analyzing function body."""
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000851 self.in_a_function = False
852
853
854class _IncludeError(Exception):
855 """Indicates a problem with the include order in a file."""
856 pass
857
858
859class FileInfo:
860 """Provides utility functions for filenames.
861
862 FileInfo provides easy access to the components of a file's path
863 relative to the project root.
864 """
865
866 def __init__(self, filename):
867 self._filename = filename
868
869 def FullName(self):
870 """Make Windows paths like Unix."""
871 return os.path.abspath(self._filename).replace('\\', '/')
872
873 def RepositoryName(self):
874 """FullName after removing the local path to the repository.
875
876 If we have a real absolute path name here we can try to do something smart:
877 detecting the root of the checkout and truncating /path/to/checkout from
878 the name so that we get header guards that don't include things like
879 "C:\Documents and Settings\..." or "/home/username/..." in them and thus
880 people on different computers who have checked the source out to different
881 locations won't see bogus errors.
882 """
883 fullname = self.FullName()
884
885 if os.path.exists(fullname):
886 project_dir = os.path.dirname(fullname)
887
888 if os.path.exists(os.path.join(project_dir, ".svn")):
889 # If there's a .svn file in the current directory, we recursively look
890 # up the directory tree for the top of the SVN checkout
891 root_dir = project_dir
892 one_up_dir = os.path.dirname(root_dir)
893 while os.path.exists(os.path.join(one_up_dir, ".svn")):
894 root_dir = os.path.dirname(root_dir)
895 one_up_dir = os.path.dirname(one_up_dir)
896
897 prefix = os.path.commonprefix([root_dir, project_dir])
898 return fullname[len(prefix) + 1:]
899
erg@chromium.org7956a872011-11-30 01:44:03 +0000900 # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by
901 # searching up from the current path.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000902 root_dir = os.path.dirname(fullname)
903 while (root_dir != os.path.dirname(root_dir) and
erg@google.com35589e62010-11-17 18:58:16 +0000904 not os.path.exists(os.path.join(root_dir, ".git")) and
erg@chromium.org7956a872011-11-30 01:44:03 +0000905 not os.path.exists(os.path.join(root_dir, ".hg")) and
906 not os.path.exists(os.path.join(root_dir, ".svn"))):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000907 root_dir = os.path.dirname(root_dir)
erg@google.com35589e62010-11-17 18:58:16 +0000908
909 if (os.path.exists(os.path.join(root_dir, ".git")) or
erg@chromium.org7956a872011-11-30 01:44:03 +0000910 os.path.exists(os.path.join(root_dir, ".hg")) or
911 os.path.exists(os.path.join(root_dir, ".svn"))):
erg@google.com35589e62010-11-17 18:58:16 +0000912 prefix = os.path.commonprefix([root_dir, project_dir])
913 return fullname[len(prefix) + 1:]
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000914
915 # Don't know what to do; header guard warnings may be wrong...
916 return fullname
917
918 def Split(self):
919 """Splits the file into the directory, basename, and extension.
920
921 For 'chrome/browser/browser.cc', Split() would
922 return ('chrome/browser', 'browser', '.cc')
923
924 Returns:
925 A tuple of (directory, basename, extension).
926 """
927
928 googlename = self.RepositoryName()
929 project, rest = os.path.split(googlename)
930 return (project,) + os.path.splitext(rest)
931
932 def BaseName(self):
933 """File base name - text after the final slash, before the final period."""
934 return self.Split()[1]
935
936 def Extension(self):
937 """File extension - text following the final period."""
938 return self.Split()[2]
939
940 def NoExtension(self):
941 """File has no source file extension."""
942 return '/'.join(self.Split()[0:2])
943
944 def IsSource(self):
945 """File has a source file extension."""
946 return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
947
948
erg@google.com35589e62010-11-17 18:58:16 +0000949def _ShouldPrintError(category, confidence, linenum):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +0000950 """If confidence >= verbose, category passes filter and is not suppressed."""
erg@google.com35589e62010-11-17 18:58:16 +0000951
952 # There are three ways we might decide not to print an error message:
953 # a "NOLINT(category)" comment appears in the source,
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000954 # the verbosity level isn't high enough, or the filters filter it out.
erg@google.com35589e62010-11-17 18:58:16 +0000955 if IsErrorSuppressedByNolint(category, linenum):
956 return False
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000957 if confidence < _cpplint_state.verbose_level:
958 return False
959
960 is_filtered = False
961 for one_filter in _Filters():
962 if one_filter.startswith('-'):
963 if category.startswith(one_filter[1:]):
964 is_filtered = True
965 elif one_filter.startswith('+'):
966 if category.startswith(one_filter[1:]):
967 is_filtered = False
968 else:
969 assert False # should have been checked for in SetFilter.
970 if is_filtered:
971 return False
972
973 return True
974
975
976def Error(filename, linenum, category, confidence, message):
977 """Logs the fact we've found a lint error.
978
979 We log where the error was found, and also our confidence in the error,
980 that is, how certain we are this is a legitimate style regression, and
981 not a misidentification or a use that's sometimes justified.
982
erg@google.com35589e62010-11-17 18:58:16 +0000983 False positives can be suppressed by the use of
984 "cpplint(category)" comments on the offending line. These are
985 parsed into _error_suppressions.
986
maruel@google.comfb2b8eb2009-04-23 21:03:42 +0000987 Args:
988 filename: The name of the file containing the error.
989 linenum: The number of the line containing the error.
990 category: A string used to describe the "category" this bug
991 falls under: "whitespace", say, or "runtime". Categories
992 may have a hierarchy separated by slashes: "whitespace/indent".
993 confidence: A number from 1-5 representing a confidence score for
994 the error, with 5 meaning that we are certain of the problem,
995 and 1 meaning that it could be a legitimate construct.
996 message: The error message.
997 """
erg@google.com35589e62010-11-17 18:58:16 +0000998 if _ShouldPrintError(category, confidence, linenum):
erg@google.com26970fa2009-11-17 18:07:32 +0000999 _cpplint_state.IncrementErrorCount(category)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001000 if _cpplint_state.output_format == 'vs7':
1001 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
1002 filename, linenum, message, category, confidence))
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001003 elif _cpplint_state.output_format == 'eclipse':
1004 sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
1005 filename, linenum, message, category, confidence))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001006 else:
1007 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
1008 filename, linenum, message, category, confidence))
1009
1010
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001011# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001012_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
1013 r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
1014# Matches strings. Escape codes should already be removed by ESCAPES.
1015_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
1016# Matches characters. Escape codes should already be removed by ESCAPES.
1017_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
1018# Matches multi-line C++ comments.
1019# This RE is a little bit more complicated than one might expect, because we
1020# have to take care of space removals tools so we can handle comments inside
1021# statements better.
1022# The current rule is: We only clear spaces from both sides when we're at the
1023# end of the line. Otherwise, we try to remove spaces from the right side,
1024# if this doesn't work we try on left side but only if there's a non-character
1025# on the right.
1026_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
1027 r"""(\s*/\*.*\*/\s*$|
1028 /\*.*\*/\s+|
1029 \s+/\*.*\*/(?=\W)|
1030 /\*.*\*/)""", re.VERBOSE)
1031
1032
1033def IsCppString(line):
1034 """Does line terminate so, that the next symbol is in string constant.
1035
1036 This function does not consider single-line nor multi-line comments.
1037
1038 Args:
1039 line: is a partial line of code starting from the 0..n.
1040
1041 Returns:
1042 True, if next character appended to 'line' is inside a
1043 string constant.
1044 """
1045
1046 line = line.replace(r'\\', 'XX') # after this, \\" does not match to \"
1047 return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
1048
1049
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001050def CleanseRawStrings(raw_lines):
1051 """Removes C++11 raw strings from lines.
1052
1053 Before:
1054 static const char kData[] = R"(
1055 multi-line string
1056 )";
1057
1058 After:
1059 static const char kData[] = ""
1060 (replaced by blank line)
1061 "";
1062
1063 Args:
1064 raw_lines: list of raw lines.
1065
1066 Returns:
1067 list of lines with C++11 raw strings replaced by empty strings.
1068 """
1069
1070 delimiter = None
1071 lines_without_raw_strings = []
1072 for line in raw_lines:
1073 if delimiter:
1074 # Inside a raw string, look for the end
1075 end = line.find(delimiter)
1076 if end >= 0:
1077 # Found the end of the string, match leading space for this
1078 # line and resume copying the original lines, and also insert
1079 # a "" on the last line.
1080 leading_space = Match(r'^(\s*)\S', line)
1081 line = leading_space.group(1) + '""' + line[end + len(delimiter):]
1082 delimiter = None
1083 else:
1084 # Haven't found the end yet, append a blank line.
1085 line = ''
1086
1087 else:
1088 # Look for beginning of a raw string.
1089 # See 2.14.15 [lex.string] for syntax.
1090 matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line)
1091 if matched:
1092 delimiter = ')' + matched.group(2) + '"'
1093
1094 end = matched.group(3).find(delimiter)
1095 if end >= 0:
1096 # Raw string ended on same line
1097 line = (matched.group(1) + '""' +
1098 matched.group(3)[end + len(delimiter):])
1099 delimiter = None
1100 else:
1101 # Start of a multi-line raw string
1102 line = matched.group(1) + '""'
1103
1104 lines_without_raw_strings.append(line)
1105
1106 # TODO(unknown): if delimiter is not None here, we might want to
1107 # emit a warning for unterminated string.
1108 return lines_without_raw_strings
1109
1110
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001111def FindNextMultiLineCommentStart(lines, lineix):
1112 """Find the beginning marker for a multiline comment."""
1113 while lineix < len(lines):
1114 if lines[lineix].strip().startswith('/*'):
1115 # Only return this marker if the comment goes beyond this line
1116 if lines[lineix].strip().find('*/', 2) < 0:
1117 return lineix
1118 lineix += 1
1119 return len(lines)
1120
1121
1122def FindNextMultiLineCommentEnd(lines, lineix):
1123 """We are inside a comment, find the end marker."""
1124 while lineix < len(lines):
1125 if lines[lineix].strip().endswith('*/'):
1126 return lineix
1127 lineix += 1
1128 return len(lines)
1129
1130
1131def RemoveMultiLineCommentsFromRange(lines, begin, end):
1132 """Clears a range of lines for multi-line comments."""
1133 # Having // dummy comments makes the lines non-empty, so we will not get
1134 # unnecessary blank line warnings later in the code.
1135 for i in range(begin, end):
1136 lines[i] = '// dummy'
1137
1138
1139def RemoveMultiLineComments(filename, lines, error):
1140 """Removes multiline (c-style) comments from lines."""
1141 lineix = 0
1142 while lineix < len(lines):
1143 lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
1144 if lineix_begin >= len(lines):
1145 return
1146 lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
1147 if lineix_end >= len(lines):
1148 error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
1149 'Could not find end of multi-line comment')
1150 return
1151 RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
1152 lineix = lineix_end + 1
1153
1154
1155def CleanseComments(line):
1156 """Removes //-comments and single-line C-style /* */ comments.
1157
1158 Args:
1159 line: A line of C++ source.
1160
1161 Returns:
1162 The line with single-line comments removed.
1163 """
1164 commentpos = line.find('//')
1165 if commentpos != -1 and not IsCppString(line[:commentpos]):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00001166 line = line[:commentpos].rstrip()
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001167 # get rid of /* ... */
1168 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
1169
1170
erg@google.com6317a9c2009-06-25 00:28:19 +00001171class CleansedLines(object):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001172 """Holds 3 copies of all lines with different preprocessing applied to them.
1173
1174 1) elided member contains lines without strings and comments,
1175 2) lines member contains lines without comments, and
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001176 3) raw_lines member contains all the lines without processing.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001177 All these three members are of <type 'list'>, and of the same length.
1178 """
1179
1180 def __init__(self, lines):
1181 self.elided = []
1182 self.lines = []
1183 self.raw_lines = lines
1184 self.num_lines = len(lines)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001185 self.lines_without_raw_strings = CleanseRawStrings(lines)
1186 for linenum in range(len(self.lines_without_raw_strings)):
1187 self.lines.append(CleanseComments(
1188 self.lines_without_raw_strings[linenum]))
1189 elided = self._CollapseStrings(self.lines_without_raw_strings[linenum])
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001190 self.elided.append(CleanseComments(elided))
1191
1192 def NumLines(self):
1193 """Returns the number of lines represented."""
1194 return self.num_lines
1195
1196 @staticmethod
1197 def _CollapseStrings(elided):
1198 """Collapses strings and chars on a line to simple "" or '' blocks.
1199
1200 We nix strings first so we're not fooled by text like '"http://"'
1201
1202 Args:
1203 elided: The line being processed.
1204
1205 Returns:
1206 The line with collapsed strings.
1207 """
1208 if not _RE_PATTERN_INCLUDE.match(elided):
1209 # Remove escaped characters first to make quote/single quote collapsing
1210 # basic. Things that look like escaped characters shouldn't occur
1211 # outside of strings and chars.
1212 elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
1213 elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
1214 elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
1215 return elided
1216
1217
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001218def FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar):
1219 """Find the position just after the matching endchar.
1220
1221 Args:
1222 line: a CleansedLines line.
1223 startpos: start searching at this position.
1224 depth: nesting level at startpos.
1225 startchar: expression opening character.
1226 endchar: expression closing character.
1227
1228 Returns:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001229 On finding matching endchar: (index just after matching endchar, 0)
1230 Otherwise: (-1, new depth at end of this line)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001231 """
1232 for i in xrange(startpos, len(line)):
1233 if line[i] == startchar:
1234 depth += 1
1235 elif line[i] == endchar:
1236 depth -= 1
1237 if depth == 0:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001238 return (i + 1, 0)
1239 return (-1, depth)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001240
1241
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001242def CloseExpression(clean_lines, linenum, pos):
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001243 """If input points to ( or { or [ or <, finds the position that closes it.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001244
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001245 If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001246 linenum/pos that correspond to the closing of the expression.
1247
1248 Args:
1249 clean_lines: A CleansedLines instance containing the file.
1250 linenum: The number of the line to check.
1251 pos: A position on the line.
1252
1253 Returns:
1254 A tuple (line, linenum, pos) pointer *past* the closing brace, or
1255 (line, len(lines), -1) if we never find a close. Note we ignore
1256 strings and comments when matching; and the line we return is the
1257 'cleansed' line at linenum.
1258 """
1259
1260 line = clean_lines.elided[linenum]
1261 startchar = line[pos]
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001262 if startchar not in '({[<':
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001263 return (line, clean_lines.NumLines(), -1)
1264 if startchar == '(': endchar = ')'
1265 if startchar == '[': endchar = ']'
1266 if startchar == '{': endchar = '}'
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001267 if startchar == '<': endchar = '>'
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001268
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001269 # Check first line
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001270 (end_pos, num_open) = FindEndOfExpressionInLine(
1271 line, pos, 0, startchar, endchar)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001272 if end_pos > -1:
1273 return (line, linenum, end_pos)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001274
1275 # Continue scanning forward
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001276 while linenum < clean_lines.NumLines() - 1:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001277 linenum += 1
1278 line = clean_lines.elided[linenum]
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001279 (end_pos, num_open) = FindEndOfExpressionInLine(
1280 line, 0, num_open, startchar, endchar)
1281 if end_pos > -1:
1282 return (line, linenum, end_pos)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001283
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001284 # Did not find endchar before end of file, give up
1285 return (line, clean_lines.NumLines(), -1)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001286
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001287
1288def FindStartOfExpressionInLine(line, endpos, depth, startchar, endchar):
1289 """Find position at the matching startchar.
1290
1291 This is almost the reverse of FindEndOfExpressionInLine, but note
1292 that the input position and returned position differs by 1.
1293
1294 Args:
1295 line: a CleansedLines line.
1296 endpos: start searching at this position.
1297 depth: nesting level at endpos.
1298 startchar: expression opening character.
1299 endchar: expression closing character.
1300
1301 Returns:
1302 On finding matching startchar: (index at matching startchar, 0)
1303 Otherwise: (-1, new depth at beginning of this line)
1304 """
1305 for i in xrange(endpos, -1, -1):
1306 if line[i] == endchar:
1307 depth += 1
1308 elif line[i] == startchar:
1309 depth -= 1
1310 if depth == 0:
1311 return (i, 0)
1312 return (-1, depth)
1313
1314
1315def ReverseCloseExpression(clean_lines, linenum, pos):
1316 """If input points to ) or } or ] or >, finds the position that opens it.
1317
1318 If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the
1319 linenum/pos that correspond to the opening of the expression.
1320
1321 Args:
1322 clean_lines: A CleansedLines instance containing the file.
1323 linenum: The number of the line to check.
1324 pos: A position on the line.
1325
1326 Returns:
1327 A tuple (line, linenum, pos) pointer *at* the opening brace, or
1328 (line, 0, -1) if we never find the matching opening brace. Note
1329 we ignore strings and comments when matching; and the line we
1330 return is the 'cleansed' line at linenum.
1331 """
1332 line = clean_lines.elided[linenum]
1333 endchar = line[pos]
1334 if endchar not in ')}]>':
1335 return (line, 0, -1)
1336 if endchar == ')': startchar = '('
1337 if endchar == ']': startchar = '['
1338 if endchar == '}': startchar = '{'
1339 if endchar == '>': startchar = '<'
1340
1341 # Check last line
1342 (start_pos, num_open) = FindStartOfExpressionInLine(
1343 line, pos, 0, startchar, endchar)
1344 if start_pos > -1:
1345 return (line, linenum, start_pos)
1346
1347 # Continue scanning backward
1348 while linenum > 0:
1349 linenum -= 1
1350 line = clean_lines.elided[linenum]
1351 (start_pos, num_open) = FindStartOfExpressionInLine(
1352 line, len(line) - 1, num_open, startchar, endchar)
1353 if start_pos > -1:
1354 return (line, linenum, start_pos)
1355
1356 # Did not find startchar before beginning of file, give up
1357 return (line, 0, -1)
1358
1359
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001360def CheckForCopyright(filename, lines, error):
1361 """Logs an error if no Copyright message appears at the top of the file."""
1362
1363 # We'll say it should occur by line 10. Don't forget there's a
1364 # dummy line at the front.
1365 for line in xrange(1, min(len(lines), 11)):
1366 if re.search(r'Copyright', lines[line], re.I): break
1367 else: # means no copyright line was found
1368 error(filename, 0, 'legal/copyright', 5,
1369 'No copyright message found. '
1370 'You should have a line: "Copyright [year] <Copyright Owner>"')
1371
1372
1373def GetHeaderGuardCPPVariable(filename):
1374 """Returns the CPP variable that should be used as a header guard.
1375
1376 Args:
1377 filename: The name of a C++ header file.
1378
1379 Returns:
1380 The CPP variable that should be used as a header guard in the
1381 named file.
1382
1383 """
1384
erg@google.com35589e62010-11-17 18:58:16 +00001385 # Restores original filename in case that cpplint is invoked from Emacs's
1386 # flymake.
1387 filename = re.sub(r'_flymake\.h$', '.h', filename)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001388 filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename)
erg@google.com35589e62010-11-17 18:58:16 +00001389
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001390 fileinfo = FileInfo(filename)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001391 file_path_from_root = fileinfo.RepositoryName()
1392 if _root:
1393 file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root)
1394 return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_'
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001395
1396
1397def CheckForHeaderGuard(filename, lines, error):
1398 """Checks that the file contains a header guard.
1399
erg@google.com6317a9c2009-06-25 00:28:19 +00001400 Logs an error if no #ifndef header guard is present. For other
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001401 headers, checks that the full pathname is used.
1402
1403 Args:
1404 filename: The name of the C++ header file.
1405 lines: An array of strings, each representing a line of the file.
1406 error: The function to call with any errors found.
1407 """
1408
1409 cppvar = GetHeaderGuardCPPVariable(filename)
1410
1411 ifndef = None
1412 ifndef_linenum = 0
1413 define = None
1414 endif = None
1415 endif_linenum = 0
1416 for linenum, line in enumerate(lines):
1417 linesplit = line.split()
1418 if len(linesplit) >= 2:
1419 # find the first occurrence of #ifndef and #define, save arg
1420 if not ifndef and linesplit[0] == '#ifndef':
1421 # set ifndef to the header guard presented on the #ifndef line.
1422 ifndef = linesplit[1]
1423 ifndef_linenum = linenum
1424 if not define and linesplit[0] == '#define':
1425 define = linesplit[1]
1426 # find the last occurrence of #endif, save entire line
1427 if line.startswith('#endif'):
1428 endif = line
1429 endif_linenum = linenum
1430
erg@chromium.orgc452fea2012-01-26 21:10:45 +00001431 if not ifndef:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001432 error(filename, 0, 'build/header_guard', 5,
1433 'No #ifndef header guard found, suggested CPP variable is: %s' %
1434 cppvar)
1435 return
1436
erg@chromium.orgc452fea2012-01-26 21:10:45 +00001437 if not define:
1438 error(filename, 0, 'build/header_guard', 5,
1439 'No #define header guard found, suggested CPP variable is: %s' %
1440 cppvar)
1441 return
1442
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001443 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
1444 # for backward compatibility.
erg@google.com35589e62010-11-17 18:58:16 +00001445 if ifndef != cppvar:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001446 error_level = 0
1447 if ifndef != cppvar + '_':
1448 error_level = 5
1449
erg@google.com35589e62010-11-17 18:58:16 +00001450 ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum,
1451 error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001452 error(filename, ifndef_linenum, 'build/header_guard', error_level,
1453 '#ifndef header guard has wrong style, please use: %s' % cppvar)
1454
erg@chromium.orgc452fea2012-01-26 21:10:45 +00001455 if define != ifndef:
1456 error(filename, 0, 'build/header_guard', 5,
1457 '#ifndef and #define don\'t match, suggested CPP variable is: %s' %
1458 cppvar)
1459 return
1460
erg@google.com35589e62010-11-17 18:58:16 +00001461 if endif != ('#endif // %s' % cppvar):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001462 error_level = 0
1463 if endif != ('#endif // %s' % (cppvar + '_')):
1464 error_level = 5
1465
erg@google.com35589e62010-11-17 18:58:16 +00001466 ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum,
1467 error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001468 error(filename, endif_linenum, 'build/header_guard', error_level,
1469 '#endif line should be "#endif // %s"' % cppvar)
1470
1471
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001472def CheckForBadCharacters(filename, lines, error):
1473 """Logs an error for each line containing bad characters.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001474
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001475 Two kinds of bad characters:
1476
1477 1. Unicode replacement characters: These indicate that either the file
1478 contained invalid UTF-8 (likely) or Unicode replacement characters (which
1479 it shouldn't). Note that it's possible for this to throw off line
1480 numbering if the invalid UTF-8 occurred adjacent to a newline.
1481
1482 2. NUL bytes. These are problematic for some tools.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001483
1484 Args:
1485 filename: The name of the current file.
1486 lines: An array of strings, each representing a line of the file.
1487 error: The function to call with any errors found.
1488 """
1489 for linenum, line in enumerate(lines):
1490 if u'\ufffd' in line:
1491 error(filename, linenum, 'readability/utf8', 5,
1492 'Line contains invalid UTF-8 (or Unicode replacement character).')
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001493 if '\0' in line:
1494 error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001495
1496
1497def CheckForNewlineAtEOF(filename, lines, error):
1498 """Logs an error if there is no newline char at the end of the file.
1499
1500 Args:
1501 filename: The name of the current file.
1502 lines: An array of strings, each representing a line of the file.
1503 error: The function to call with any errors found.
1504 """
1505
1506 # The array lines() was created by adding two newlines to the
1507 # original file (go figure), then splitting on \n.
1508 # To verify that the file ends in \n, we just have to make sure the
1509 # last-but-two element of lines() exists and is empty.
1510 if len(lines) < 3 or lines[-2]:
1511 error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
1512 'Could not find a newline character at the end of the file.')
1513
1514
1515def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
1516 """Logs an error if we see /* ... */ or "..." that extend past one line.
1517
1518 /* ... */ comments are legit inside macros, for one line.
1519 Otherwise, we prefer // comments, so it's ok to warn about the
1520 other. Likewise, it's ok for strings to extend across multiple
1521 lines, as long as a line continuation character (backslash)
1522 terminates each line. Although not currently prohibited by the C++
1523 style guide, it's ugly and unnecessary. We don't do well with either
1524 in this lint program, so we warn about both.
1525
1526 Args:
1527 filename: The name of the current file.
1528 clean_lines: A CleansedLines instance containing the file.
1529 linenum: The number of the line to check.
1530 error: The function to call with any errors found.
1531 """
1532 line = clean_lines.elided[linenum]
1533
1534 # Remove all \\ (escaped backslashes) from the line. They are OK, and the
1535 # second (escaped) slash may trigger later \" detection erroneously.
1536 line = line.replace('\\\\', '')
1537
1538 if line.count('/*') > line.count('*/'):
1539 error(filename, linenum, 'readability/multiline_comment', 5,
1540 'Complex multi-line /*...*/-style comment found. '
1541 'Lint may give bogus warnings. '
1542 'Consider replacing these with //-style comments, '
1543 'with #if 0...#endif, '
1544 'or with more clearly structured multi-line comments.')
1545
1546 if (line.count('"') - line.count('\\"')) % 2:
1547 error(filename, linenum, 'readability/multiline_string', 5,
1548 'Multi-line string ("...") found. This lint script doesn\'t '
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001549 'do well with such strings, and may give bogus warnings. '
1550 'Use C++11 raw strings or concatenation instead.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001551
1552
1553threading_list = (
1554 ('asctime(', 'asctime_r('),
1555 ('ctime(', 'ctime_r('),
1556 ('getgrgid(', 'getgrgid_r('),
1557 ('getgrnam(', 'getgrnam_r('),
1558 ('getlogin(', 'getlogin_r('),
1559 ('getpwnam(', 'getpwnam_r('),
1560 ('getpwuid(', 'getpwuid_r('),
1561 ('gmtime(', 'gmtime_r('),
1562 ('localtime(', 'localtime_r('),
1563 ('rand(', 'rand_r('),
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001564 ('strtok(', 'strtok_r('),
1565 ('ttyname(', 'ttyname_r('),
1566 )
1567
1568
1569def CheckPosixThreading(filename, clean_lines, linenum, error):
1570 """Checks for calls to thread-unsafe functions.
1571
1572 Much code has been originally written without consideration of
1573 multi-threading. Also, engineers are relying on their old experience;
1574 they have learned posix before threading extensions were added. These
1575 tests guide the engineers to use thread-safe functions (when using
1576 posix directly).
1577
1578 Args:
1579 filename: The name of the current file.
1580 clean_lines: A CleansedLines instance containing the file.
1581 linenum: The number of the line to check.
1582 error: The function to call with any errors found.
1583 """
1584 line = clean_lines.elided[linenum]
1585 for single_thread_function, multithread_safe_function in threading_list:
1586 ix = line.find(single_thread_function)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001587 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001588 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
1589 line[ix - 1] not in ('_', '.', '>'))):
1590 error(filename, linenum, 'runtime/threadsafe_fn', 2,
1591 'Consider using ' + multithread_safe_function +
1592 '...) instead of ' + single_thread_function +
1593 '...) for improved thread safety.')
1594
1595
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001596def CheckVlogArguments(filename, clean_lines, linenum, error):
1597 """Checks that VLOG() is only used for defining a logging level.
1598
1599 For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and
1600 VLOG(FATAL) are not.
1601
1602 Args:
1603 filename: The name of the current file.
1604 clean_lines: A CleansedLines instance containing the file.
1605 linenum: The number of the line to check.
1606 error: The function to call with any errors found.
1607 """
1608 line = clean_lines.elided[linenum]
1609 if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line):
1610 error(filename, linenum, 'runtime/vlog', 5,
1611 'VLOG() should be used with numeric verbosity level. '
1612 'Use LOG() if you want symbolic severity levels.')
1613
1614
erg@google.com26970fa2009-11-17 18:07:32 +00001615# Matches invalid increment: *count++, which moves pointer instead of
erg@google.com6317a9c2009-06-25 00:28:19 +00001616# incrementing a value.
erg@google.com26970fa2009-11-17 18:07:32 +00001617_RE_PATTERN_INVALID_INCREMENT = re.compile(
erg@google.com6317a9c2009-06-25 00:28:19 +00001618 r'^\s*\*\w+(\+\+|--);')
1619
1620
1621def CheckInvalidIncrement(filename, clean_lines, linenum, error):
erg@google.com26970fa2009-11-17 18:07:32 +00001622 """Checks for invalid increment *count++.
erg@google.com6317a9c2009-06-25 00:28:19 +00001623
1624 For example following function:
1625 void increment_counter(int* count) {
1626 *count++;
1627 }
1628 is invalid, because it effectively does count++, moving pointer, and should
1629 be replaced with ++*count, (*count)++ or *count += 1.
1630
1631 Args:
1632 filename: The name of the current file.
1633 clean_lines: A CleansedLines instance containing the file.
1634 linenum: The number of the line to check.
1635 error: The function to call with any errors found.
1636 """
1637 line = clean_lines.elided[linenum]
erg@google.com26970fa2009-11-17 18:07:32 +00001638 if _RE_PATTERN_INVALID_INCREMENT.match(line):
erg@google.com6317a9c2009-06-25 00:28:19 +00001639 error(filename, linenum, 'runtime/invalid_increment', 5,
1640 'Changing pointer instead of value (or unused value of operator*).')
1641
1642
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001643class _BlockInfo(object):
1644 """Stores information about a generic block of code."""
1645
1646 def __init__(self, seen_open_brace):
1647 self.seen_open_brace = seen_open_brace
1648 self.open_parentheses = 0
1649 self.inline_asm = _NO_ASM
1650
1651 def CheckBegin(self, filename, clean_lines, linenum, error):
1652 """Run checks that applies to text up to the opening brace.
1653
1654 This is mostly for checking the text after the class identifier
1655 and the "{", usually where the base class is specified. For other
1656 blocks, there isn't much to check, so we always pass.
1657
1658 Args:
1659 filename: The name of the current file.
1660 clean_lines: A CleansedLines instance containing the file.
1661 linenum: The number of the line to check.
1662 error: The function to call with any errors found.
1663 """
1664 pass
1665
1666 def CheckEnd(self, filename, clean_lines, linenum, error):
1667 """Run checks that applies to text after the closing brace.
1668
1669 This is mostly used for checking end of namespace comments.
1670
1671 Args:
1672 filename: The name of the current file.
1673 clean_lines: A CleansedLines instance containing the file.
1674 linenum: The number of the line to check.
1675 error: The function to call with any errors found.
1676 """
1677 pass
1678
1679
1680class _ClassInfo(_BlockInfo):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001681 """Stores information about a class."""
1682
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001683 def __init__(self, name, class_or_struct, clean_lines, linenum):
1684 _BlockInfo.__init__(self, False)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001685 self.name = name
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001686 self.starting_linenum = linenum
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001687 self.is_derived = False
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001688 if class_or_struct == 'struct':
1689 self.access = 'public'
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001690 self.is_struct = True
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001691 else:
1692 self.access = 'private'
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001693 self.is_struct = False
1694
1695 # Remember initial indentation level for this class. Using raw_lines here
1696 # instead of elided to account for leading comments.
1697 initial_indent = Match(r'^( *)\S', clean_lines.raw_lines[linenum])
1698 if initial_indent:
1699 self.class_indent = len(initial_indent.group(1))
1700 else:
1701 self.class_indent = 0
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001702
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00001703 # Try to find the end of the class. This will be confused by things like:
1704 # class A {
1705 # } *x = { ...
1706 #
1707 # But it's still good enough for CheckSectionSpacing.
1708 self.last_line = 0
1709 depth = 0
1710 for i in range(linenum, clean_lines.NumLines()):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001711 line = clean_lines.elided[i]
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00001712 depth += line.count('{') - line.count('}')
1713 if not depth:
1714 self.last_line = i
1715 break
1716
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001717 def CheckBegin(self, filename, clean_lines, linenum, error):
1718 # Look for a bare ':'
1719 if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]):
1720 self.is_derived = True
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001721
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001722 def CheckEnd(self, filename, clean_lines, linenum, error):
1723 # Check that closing brace is aligned with beginning of the class.
1724 # Only do this if the closing brace is indented by only whitespaces.
1725 # This means we will not check single-line class definitions.
1726 indent = Match(r'^( *)\}', clean_lines.elided[linenum])
1727 if indent and len(indent.group(1)) != self.class_indent:
1728 if self.is_struct:
1729 parent = 'struct ' + self.name
1730 else:
1731 parent = 'class ' + self.name
1732 error(filename, linenum, 'whitespace/indent', 3,
1733 'Closing brace should be aligned with beginning of %s' % parent)
1734
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001735
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001736class _NamespaceInfo(_BlockInfo):
1737 """Stores information about a namespace."""
1738
1739 def __init__(self, name, linenum):
1740 _BlockInfo.__init__(self, False)
1741 self.name = name or ''
1742 self.starting_linenum = linenum
1743
1744 def CheckEnd(self, filename, clean_lines, linenum, error):
1745 """Check end of namespace comments."""
1746 line = clean_lines.raw_lines[linenum]
1747
1748 # Check how many lines is enclosed in this namespace. Don't issue
1749 # warning for missing namespace comments if there aren't enough
1750 # lines. However, do apply checks if there is already an end of
1751 # namespace comment and it's incorrect.
1752 #
1753 # TODO(unknown): We always want to check end of namespace comments
1754 # if a namespace is large, but sometimes we also want to apply the
1755 # check if a short namespace contained nontrivial things (something
1756 # other than forward declarations). There is currently no logic on
1757 # deciding what these nontrivial things are, so this check is
1758 # triggered by namespace size only, which works most of the time.
1759 if (linenum - self.starting_linenum < 10
1760 and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)):
1761 return
1762
1763 # Look for matching comment at end of namespace.
1764 #
1765 # Note that we accept C style "/* */" comments for terminating
1766 # namespaces, so that code that terminate namespaces inside
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001767 # preprocessor macros can be cpplint clean.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001768 #
1769 # We also accept stuff like "// end of namespace <name>." with the
1770 # period at the end.
1771 #
1772 # Besides these, we don't accept anything else, otherwise we might
1773 # get false negatives when existing comment is a substring of the
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001774 # expected namespace.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001775 if self.name:
1776 # Named namespace
1777 if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) +
1778 r'[\*/\.\\\s]*$'),
1779 line):
1780 error(filename, linenum, 'readability/namespace', 5,
1781 'Namespace should be terminated with "// namespace %s"' %
1782 self.name)
1783 else:
1784 # Anonymous namespace
1785 if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line):
1786 error(filename, linenum, 'readability/namespace', 5,
1787 'Namespace should be terminated with "// namespace"')
1788
1789
1790class _PreprocessorInfo(object):
1791 """Stores checkpoints of nesting stacks when #if/#else is seen."""
1792
1793 def __init__(self, stack_before_if):
1794 # The entire nesting stack before #if
1795 self.stack_before_if = stack_before_if
1796
1797 # The entire nesting stack up to #else
1798 self.stack_before_else = []
1799
1800 # Whether we have already seen #else or #elif
1801 self.seen_else = False
1802
1803
1804class _NestingState(object):
1805 """Holds states related to parsing braces."""
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001806
1807 def __init__(self):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001808 # Stack for tracking all braces. An object is pushed whenever we
1809 # see a "{", and popped when we see a "}". Only 3 types of
1810 # objects are possible:
1811 # - _ClassInfo: a class or struct.
1812 # - _NamespaceInfo: a namespace.
1813 # - _BlockInfo: some other type of block.
1814 self.stack = []
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00001815
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001816 # Stack of _PreprocessorInfo objects.
1817 self.pp_stack = []
1818
1819 def SeenOpenBrace(self):
1820 """Check if we have seen the opening brace for the innermost block.
1821
1822 Returns:
1823 True if we have seen the opening brace, False if the innermost
1824 block is still expecting an opening brace.
1825 """
1826 return (not self.stack) or self.stack[-1].seen_open_brace
1827
1828 def InNamespaceBody(self):
1829 """Check if we are currently one level inside a namespace body.
1830
1831 Returns:
1832 True if top of the stack is a namespace block, False otherwise.
1833 """
1834 return self.stack and isinstance(self.stack[-1], _NamespaceInfo)
1835
1836 def UpdatePreprocessor(self, line):
1837 """Update preprocessor stack.
1838
1839 We need to handle preprocessors due to classes like this:
1840 #ifdef SWIG
1841 struct ResultDetailsPageElementExtensionPoint {
1842 #else
1843 struct ResultDetailsPageElementExtensionPoint : public Extension {
1844 #endif
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001845
1846 We make the following assumptions (good enough for most files):
1847 - Preprocessor condition evaluates to true from #if up to first
1848 #else/#elif/#endif.
1849
1850 - Preprocessor condition evaluates to false from #else/#elif up
1851 to #endif. We still perform lint checks on these lines, but
1852 these do not affect nesting stack.
1853
1854 Args:
1855 line: current line to check.
1856 """
1857 if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line):
1858 # Beginning of #if block, save the nesting stack here. The saved
1859 # stack will allow us to restore the parsing state in the #else case.
1860 self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack)))
1861 elif Match(r'^\s*#\s*(else|elif)\b', line):
1862 # Beginning of #else block
1863 if self.pp_stack:
1864 if not self.pp_stack[-1].seen_else:
1865 # This is the first #else or #elif block. Remember the
1866 # whole nesting stack up to this point. This is what we
1867 # keep after the #endif.
1868 self.pp_stack[-1].seen_else = True
1869 self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack)
1870
1871 # Restore the stack to how it was before the #if
1872 self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if)
1873 else:
1874 # TODO(unknown): unexpected #else, issue warning?
1875 pass
1876 elif Match(r'^\s*#\s*endif\b', line):
1877 # End of #if or #else blocks.
1878 if self.pp_stack:
1879 # If we saw an #else, we will need to restore the nesting
1880 # stack to its former state before the #else, otherwise we
1881 # will just continue from where we left off.
1882 if self.pp_stack[-1].seen_else:
1883 # Here we can just use a shallow copy since we are the last
1884 # reference to it.
1885 self.stack = self.pp_stack[-1].stack_before_else
1886 # Drop the corresponding #if
1887 self.pp_stack.pop()
1888 else:
1889 # TODO(unknown): unexpected #endif, issue warning?
1890 pass
1891
1892 def Update(self, filename, clean_lines, linenum, error):
1893 """Update nesting state with current line.
1894
1895 Args:
1896 filename: The name of the current file.
1897 clean_lines: A CleansedLines instance containing the file.
1898 linenum: The number of the line to check.
1899 error: The function to call with any errors found.
1900 """
1901 line = clean_lines.elided[linenum]
1902
1903 # Update pp_stack first
1904 self.UpdatePreprocessor(line)
1905
1906 # Count parentheses. This is to avoid adding struct arguments to
1907 # the nesting stack.
1908 if self.stack:
1909 inner_block = self.stack[-1]
1910 depth_change = line.count('(') - line.count(')')
1911 inner_block.open_parentheses += depth_change
1912
1913 # Also check if we are starting or ending an inline assembly block.
1914 if inner_block.inline_asm in (_NO_ASM, _END_ASM):
1915 if (depth_change != 0 and
1916 inner_block.open_parentheses == 1 and
1917 _MATCH_ASM.match(line)):
1918 # Enter assembly block
1919 inner_block.inline_asm = _INSIDE_ASM
1920 else:
1921 # Not entering assembly block. If previous line was _END_ASM,
1922 # we will now shift to _NO_ASM state.
1923 inner_block.inline_asm = _NO_ASM
1924 elif (inner_block.inline_asm == _INSIDE_ASM and
1925 inner_block.open_parentheses == 0):
1926 # Exit assembly block
1927 inner_block.inline_asm = _END_ASM
1928
1929 # Consume namespace declaration at the beginning of the line. Do
1930 # this in a loop so that we catch same line declarations like this:
1931 # namespace proto2 { namespace bridge { class MessageSet; } }
1932 while True:
1933 # Match start of namespace. The "\b\s*" below catches namespace
1934 # declarations even if it weren't followed by a whitespace, this
1935 # is so that we don't confuse our namespace checker. The
1936 # missing spaces will be flagged by CheckSpacing.
1937 namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line)
1938 if not namespace_decl_match:
1939 break
1940
1941 new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum)
1942 self.stack.append(new_namespace)
1943
1944 line = namespace_decl_match.group(2)
1945 if line.find('{') != -1:
1946 new_namespace.seen_open_brace = True
1947 line = line[line.find('{') + 1:]
1948
1949 # Look for a class declaration in whatever is left of the line
1950 # after parsing namespaces. The regexp accounts for decorated classes
1951 # such as in:
1952 # class LOCKABLE API Object {
1953 # };
1954 #
1955 # Templates with class arguments may confuse the parser, for example:
1956 # template <class T
1957 # class Comparator = less<T>,
1958 # class Vector = vector<T> >
1959 # class HeapQueue {
1960 #
1961 # Because this parser has no nesting state about templates, by the
1962 # time it saw "class Comparator", it may think that it's a new class.
1963 # Nested templates have a similar problem:
1964 # template <
1965 # typename ExportedType,
1966 # typename TupleType,
1967 # template <typename, typename> class ImplTemplate>
1968 #
1969 # To avoid these cases, we ignore classes that are followed by '=' or '>'
1970 class_decl_match = Match(
1971 r'\s*(template\s*<[\w\s<>,:]*>\s*)?'
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001972 r'(class|struct)\s+([A-Z_]+\s+)*(\w+(?:::\w+)*)'
1973 r'(([^=>]|<[^<>]*>|<[^<>]*<[^<>]*>\s*>)*)$', line)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001974 if (class_decl_match and
1975 (not self.stack or self.stack[-1].open_parentheses == 0)):
1976 self.stack.append(_ClassInfo(
1977 class_decl_match.group(4), class_decl_match.group(2),
1978 clean_lines, linenum))
1979 line = class_decl_match.group(5)
1980
1981 # If we have not yet seen the opening brace for the innermost block,
1982 # run checks here.
1983 if not self.SeenOpenBrace():
1984 self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)
1985
1986 # Update access control if we are inside a class/struct
1987 if self.stack and isinstance(self.stack[-1], _ClassInfo):
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001988 classinfo = self.stack[-1]
1989 access_match = Match(
1990 r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?'
1991 r':(?:[^:]|$)',
1992 line)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00001993 if access_match:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00001994 classinfo.access = access_match.group(2)
1995
1996 # Check that access keywords are indented +1 space. Skip this
1997 # check if the keywords are not preceded by whitespaces.
1998 indent = access_match.group(1)
1999 if (len(indent) != classinfo.class_indent + 1 and
2000 Match(r'^\s*$', indent)):
2001 if classinfo.is_struct:
2002 parent = 'struct ' + classinfo.name
2003 else:
2004 parent = 'class ' + classinfo.name
2005 slots = ''
2006 if access_match.group(3):
2007 slots = access_match.group(3)
2008 error(filename, linenum, 'whitespace/indent', 3,
2009 '%s%s: should be indented +1 space inside %s' % (
2010 access_match.group(2), slots, parent))
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002011
2012 # Consume braces or semicolons from what's left of the line
2013 while True:
2014 # Match first brace, semicolon, or closed parenthesis.
2015 matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line)
2016 if not matched:
2017 break
2018
2019 token = matched.group(1)
2020 if token == '{':
2021 # If namespace or class hasn't seen a opening brace yet, mark
2022 # namespace/class head as complete. Push a new block onto the
2023 # stack otherwise.
2024 if not self.SeenOpenBrace():
2025 self.stack[-1].seen_open_brace = True
2026 else:
2027 self.stack.append(_BlockInfo(True))
2028 if _MATCH_ASM.match(line):
2029 self.stack[-1].inline_asm = _BLOCK_ASM
2030 elif token == ';' or token == ')':
2031 # If we haven't seen an opening brace yet, but we already saw
2032 # a semicolon, this is probably a forward declaration. Pop
2033 # the stack for these.
2034 #
2035 # Similarly, if we haven't seen an opening brace yet, but we
2036 # already saw a closing parenthesis, then these are probably
2037 # function arguments with extra "class" or "struct" keywords.
2038 # Also pop these stack for these.
2039 if not self.SeenOpenBrace():
2040 self.stack.pop()
2041 else: # token == '}'
2042 # Perform end of block checks and pop the stack.
2043 if self.stack:
2044 self.stack[-1].CheckEnd(filename, clean_lines, linenum, error)
2045 self.stack.pop()
2046 line = matched.group(2)
2047
2048 def InnermostClass(self):
2049 """Get class info on the top of the stack.
2050
2051 Returns:
2052 A _ClassInfo object if we are inside a class, or None otherwise.
2053 """
2054 for i in range(len(self.stack), 0, -1):
2055 classinfo = self.stack[i - 1]
2056 if isinstance(classinfo, _ClassInfo):
2057 return classinfo
2058 return None
2059
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002060 def CheckCompletedBlocks(self, filename, error):
2061 """Checks that all classes and namespaces have been completely parsed.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002062
2063 Call this when all lines in a file have been processed.
2064 Args:
2065 filename: The name of the current file.
2066 error: The function to call with any errors found.
2067 """
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002068 # Note: This test can result in false positives if #ifdef constructs
2069 # get in the way of brace matching. See the testBuildClass test in
2070 # cpplint_unittest.py for an example of this.
2071 for obj in self.stack:
2072 if isinstance(obj, _ClassInfo):
2073 error(filename, obj.starting_linenum, 'build/class', 5,
2074 'Failed to find complete declaration of class %s' %
2075 obj.name)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002076 elif isinstance(obj, _NamespaceInfo):
2077 error(filename, obj.starting_linenum, 'build/namespaces', 5,
2078 'Failed to find complete declaration of namespace %s' %
2079 obj.name)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002080
2081
2082def CheckForNonStandardConstructs(filename, clean_lines, linenum,
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002083 nesting_state, error):
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002084 r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002085
2086 Complain about several constructs which gcc-2 accepts, but which are
2087 not standard C++. Warning about these in lint is one way to ease the
2088 transition to new compilers.
2089 - put storage class first (e.g. "static const" instead of "const static").
2090 - "%lld" instead of %qd" in printf-type functions.
2091 - "%1$d" is non-standard in printf-type functions.
2092 - "\%" is an undefined character escape sequence.
2093 - text after #endif is not allowed.
2094 - invalid inner-style forward declaration.
2095 - >? and <? operators, and their >?= and <?= cousins.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002096
erg@google.com26970fa2009-11-17 18:07:32 +00002097 Additionally, check for constructor/destructor style violations and reference
2098 members, as it is very convenient to do so while checking for
2099 gcc-2 compliance.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002100
2101 Args:
2102 filename: The name of the current file.
2103 clean_lines: A CleansedLines instance containing the file.
2104 linenum: The number of the line to check.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002105 nesting_state: A _NestingState instance which maintains information about
2106 the current stack of nested blocks being parsed.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002107 error: A callable to which errors are reported, which takes 4 arguments:
2108 filename, line number, error level, and message
2109 """
2110
2111 # Remove comments from the line, but leave in strings for now.
2112 line = clean_lines.lines[linenum]
2113
2114 if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
2115 error(filename, linenum, 'runtime/printf_format', 3,
2116 '%q in format strings is deprecated. Use %ll instead.')
2117
2118 if Search(r'printf\s*\(.*".*%\d+\$', line):
2119 error(filename, linenum, 'runtime/printf_format', 2,
2120 '%N$ formats are unconventional. Try rewriting to avoid them.')
2121
2122 # Remove escaped backslashes before looking for undefined escapes.
2123 line = line.replace('\\\\', '')
2124
2125 if Search(r'("|\').*\\(%|\[|\(|{)', line):
2126 error(filename, linenum, 'build/printf_format', 3,
2127 '%, [, (, and { are undefined character escapes. Unescape them.')
2128
2129 # For the rest, work with both comments and strings removed.
2130 line = clean_lines.elided[linenum]
2131
2132 if Search(r'\b(const|volatile|void|char|short|int|long'
2133 r'|float|double|signed|unsigned'
2134 r'|schar|u?int8|u?int16|u?int32|u?int64)'
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002135 r'\s+(register|static|extern|typedef)\b',
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002136 line):
2137 error(filename, linenum, 'build/storage_class', 5,
2138 'Storage class (static, extern, typedef, etc) should be first.')
2139
2140 if Match(r'\s*#\s*endif\s*[^/\s]+', line):
2141 error(filename, linenum, 'build/endif_comment', 5,
2142 'Uncommented text after #endif is non-standard. Use a comment.')
2143
2144 if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
2145 error(filename, linenum, 'build/forward_decl', 5,
2146 'Inner-style forward declarations are invalid. Remove this line.')
2147
2148 if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
2149 line):
2150 error(filename, linenum, 'build/deprecated', 3,
2151 '>? and <? (max and min) operators are non-standard and deprecated.')
2152
erg@google.com26970fa2009-11-17 18:07:32 +00002153 if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
2154 # TODO(unknown): Could it be expanded safely to arbitrary references,
2155 # without triggering too many false positives? The first
2156 # attempt triggered 5 warnings for mostly benign code in the regtest, hence
2157 # the restriction.
2158 # Here's the original regexp, for the reference:
2159 # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
2160 # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
2161 error(filename, linenum, 'runtime/member_string_references', 2,
2162 'const string& members are dangerous. It is much better to use '
2163 'alternatives, such as pointers or simple constants.')
2164
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002165 # Everything else in this function operates on class declarations.
2166 # Return early if the top of the nesting stack is not a class, or if
2167 # the class head is not completed yet.
2168 classinfo = nesting_state.InnermostClass()
2169 if not classinfo or not classinfo.seen_open_brace:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002170 return
2171
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002172 # The class may have been declared with namespace or classname qualifiers.
2173 # The constructor and destructor will not have those qualifiers.
2174 base_classname = classinfo.name.split('::')[-1]
2175
2176 # Look for single-argument constructors that aren't marked explicit.
2177 # Technically a valid construct, but against style.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002178 args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)'
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002179 % re.escape(base_classname),
2180 line)
2181 if (args and
2182 args.group(1) != 'void' and
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002183 not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&'
2184 % re.escape(base_classname), args.group(1).strip())):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002185 error(filename, linenum, 'runtime/explicit', 5,
2186 'Single-argument constructors should be marked explicit.')
2187
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002188
2189def CheckSpacingForFunctionCall(filename, line, linenum, error):
2190 """Checks for the correctness of various spacing around function calls.
2191
2192 Args:
2193 filename: The name of the current file.
2194 line: The text of the line to check.
2195 linenum: The number of the line to check.
2196 error: The function to call with any errors found.
2197 """
2198
2199 # Since function calls often occur inside if/for/while/switch
2200 # expressions - which have their own, more liberal conventions - we
2201 # first see if we should be looking inside such an expression for a
2202 # function call, to which we can apply more strict standards.
2203 fncall = line # if there's no control flow construct, look at whole line
2204 for pattern in (r'\bif\s*\((.*)\)\s*{',
2205 r'\bfor\s*\((.*)\)\s*{',
2206 r'\bwhile\s*\((.*)\)\s*[{;]',
2207 r'\bswitch\s*\((.*)\)\s*{'):
2208 match = Search(pattern, line)
2209 if match:
2210 fncall = match.group(1) # look inside the parens for function calls
2211 break
2212
2213 # Except in if/for/while/switch, there should never be space
2214 # immediately inside parens (eg "f( 3, 4 )"). We make an exception
2215 # for nested parens ( (a+b) + c ). Likewise, there should never be
2216 # a space before a ( when it's a function argument. I assume it's a
2217 # function argument when the char before the whitespace is legal in
2218 # a function name (alnum + _) and we're not starting a macro. Also ignore
2219 # pointers and references to arrays and functions coz they're too tricky:
2220 # we use a very simple way to recognize these:
2221 # " (something)(maybe-something)" or
2222 # " (something)(maybe-something," or
2223 # " (something)[something]"
2224 # Note that we assume the contents of [] to be short enough that
2225 # they'll never need to wrap.
2226 if ( # Ignore control structures.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002227 not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b',
2228 fncall) and
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002229 # Ignore pointers/references to functions.
2230 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
2231 # Ignore pointers/references to arrays.
2232 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
erg@google.com6317a9c2009-06-25 00:28:19 +00002233 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002234 error(filename, linenum, 'whitespace/parens', 4,
2235 'Extra space after ( in function call')
erg@google.com6317a9c2009-06-25 00:28:19 +00002236 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002237 error(filename, linenum, 'whitespace/parens', 2,
2238 'Extra space after (')
2239 if (Search(r'\w\s+\(', fncall) and
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002240 not Search(r'#\s*define|typedef', fncall) and
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002241 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002242 error(filename, linenum, 'whitespace/parens', 4,
2243 'Extra space before ( in function call')
2244 # If the ) is followed only by a newline or a { + newline, assume it's
2245 # part of a control statement (if/while/etc), and don't complain
2246 if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002247 # If the closing parenthesis is preceded by only whitespaces,
2248 # try to give a more descriptive error message.
2249 if Search(r'^\s+\)', fncall):
2250 error(filename, linenum, 'whitespace/parens', 2,
2251 'Closing ) should be moved to the previous line')
2252 else:
2253 error(filename, linenum, 'whitespace/parens', 2,
2254 'Extra space before )')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002255
2256
2257def IsBlankLine(line):
2258 """Returns true if the given line is blank.
2259
2260 We consider a line to be blank if the line is empty or consists of
2261 only white spaces.
2262
2263 Args:
2264 line: A line of a string.
2265
2266 Returns:
2267 True, if the given line is blank.
2268 """
2269 return not line or line.isspace()
2270
2271
2272def CheckForFunctionLengths(filename, clean_lines, linenum,
2273 function_state, error):
2274 """Reports for long function bodies.
2275
2276 For an overview why this is done, see:
2277 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
2278
2279 Uses a simplistic algorithm assuming other style guidelines
2280 (especially spacing) are followed.
2281 Only checks unindented functions, so class members are unchecked.
2282 Trivial bodies are unchecked, so constructors with huge initializer lists
2283 may be missed.
2284 Blank/comment lines are not counted so as to avoid encouraging the removal
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002285 of vertical space and comments just to get through a lint check.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002286 NOLINT *on the last line of a function* disables this check.
2287
2288 Args:
2289 filename: The name of the current file.
2290 clean_lines: A CleansedLines instance containing the file.
2291 linenum: The number of the line to check.
2292 function_state: Current function name and lines in body so far.
2293 error: The function to call with any errors found.
2294 """
2295 lines = clean_lines.lines
2296 line = lines[linenum]
2297 raw = clean_lines.raw_lines
2298 raw_line = raw[linenum]
2299 joined_line = ''
2300
2301 starting_func = False
erg@google.com6317a9c2009-06-25 00:28:19 +00002302 regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ...
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002303 match_result = Match(regexp, line)
2304 if match_result:
2305 # If the name is all caps and underscores, figure it's a macro and
2306 # ignore it, unless it's TEST or TEST_F.
2307 function_name = match_result.group(1).split()[-1]
2308 if function_name == 'TEST' or function_name == 'TEST_F' or (
2309 not Match(r'[A-Z_]+$', function_name)):
2310 starting_func = True
2311
2312 if starting_func:
2313 body_found = False
erg@google.com6317a9c2009-06-25 00:28:19 +00002314 for start_linenum in xrange(linenum, clean_lines.NumLines()):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002315 start_line = lines[start_linenum]
2316 joined_line += ' ' + start_line.lstrip()
2317 if Search(r'(;|})', start_line): # Declarations and trivial functions
2318 body_found = True
2319 break # ... ignore
2320 elif Search(r'{', start_line):
2321 body_found = True
2322 function = Search(r'((\w|:)*)\(', line).group(1)
2323 if Match(r'TEST', function): # Handle TEST... macros
2324 parameter_regexp = Search(r'(\(.*\))', joined_line)
2325 if parameter_regexp: # Ignore bad syntax
2326 function += parameter_regexp.group(1)
2327 else:
2328 function += '()'
2329 function_state.Begin(function)
2330 break
2331 if not body_found:
erg@google.com6317a9c2009-06-25 00:28:19 +00002332 # No body for the function (or evidence of a non-function) was found.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002333 error(filename, linenum, 'readability/fn_size', 5,
2334 'Lint failed to find start of function body.')
2335 elif Match(r'^\}\s*$', line): # function end
erg@google.com35589e62010-11-17 18:58:16 +00002336 function_state.Check(error, filename, linenum)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002337 function_state.End()
2338 elif not Match(r'^\s*$', line):
2339 function_state.Count() # Count non-blank/non-comment lines.
2340
2341
2342_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
2343
2344
2345def CheckComment(comment, filename, linenum, error):
2346 """Checks for common mistakes in TODO comments.
2347
2348 Args:
2349 comment: The text of the comment from the line in question.
2350 filename: The name of the current file.
2351 linenum: The number of the line to check.
2352 error: The function to call with any errors found.
2353 """
2354 match = _RE_PATTERN_TODO.match(comment)
2355 if match:
2356 # One whitespace is correct; zero whitespace is handled elsewhere.
2357 leading_whitespace = match.group(1)
2358 if len(leading_whitespace) > 1:
2359 error(filename, linenum, 'whitespace/todo', 2,
2360 'Too many spaces before TODO')
2361
2362 username = match.group(2)
2363 if not username:
2364 error(filename, linenum, 'readability/todo', 2,
2365 'Missing username in TODO; it should look like '
2366 '"// TODO(my_username): Stuff."')
2367
2368 middle_whitespace = match.group(3)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002369 # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002370 if middle_whitespace != ' ' and middle_whitespace != '':
2371 error(filename, linenum, 'whitespace/todo', 2,
2372 'TODO(my_username) should be followed by a space')
2373
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002374def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
2375 """Checks for improper use of DISALLOW* macros.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002376
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002377 Args:
2378 filename: The name of the current file.
2379 clean_lines: A CleansedLines instance containing the file.
2380 linenum: The number of the line to check.
2381 nesting_state: A _NestingState instance which maintains information about
2382 the current stack of nested blocks being parsed.
2383 error: The function to call with any errors found.
2384 """
2385 line = clean_lines.elided[linenum] # get rid of comments and strings
2386
2387 matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|'
2388 r'DISALLOW_EVIL_CONSTRUCTORS|'
2389 r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)
2390 if not matched:
2391 return
2392 if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):
2393 if nesting_state.stack[-1].access != 'private':
2394 error(filename, linenum, 'readability/constructors', 3,
2395 '%s must be in the private: section' % matched.group(1))
2396
2397 else:
2398 # Found DISALLOW* macro outside a class declaration, or perhaps it
2399 # was used inside a function when it should have been part of the
2400 # class declaration. We could issue a warning here, but it
2401 # probably resulted in a compiler error already.
2402 pass
2403
2404
2405def FindNextMatchingAngleBracket(clean_lines, linenum, init_suffix):
2406 """Find the corresponding > to close a template.
2407
2408 Args:
2409 clean_lines: A CleansedLines instance containing the file.
2410 linenum: Current line number.
2411 init_suffix: Remainder of the current line after the initial <.
2412
2413 Returns:
2414 True if a matching bracket exists.
2415 """
2416 line = init_suffix
2417 nesting_stack = ['<']
2418 while True:
2419 # Find the next operator that can tell us whether < is used as an
2420 # opening bracket or as a less-than operator. We only want to
2421 # warn on the latter case.
2422 #
2423 # We could also check all other operators and terminate the search
2424 # early, e.g. if we got something like this "a<b+c", the "<" is
2425 # most likely a less-than operator, but then we will get false
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002426 # positives for default arguments and other template expressions.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002427 match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line)
2428 if match:
2429 # Found an operator, update nesting stack
2430 operator = match.group(1)
2431 line = match.group(2)
2432
2433 if nesting_stack[-1] == '<':
2434 # Expecting closing angle bracket
2435 if operator in ('<', '(', '['):
2436 nesting_stack.append(operator)
2437 elif operator == '>':
2438 nesting_stack.pop()
2439 if not nesting_stack:
2440 # Found matching angle bracket
2441 return True
2442 elif operator == ',':
2443 # Got a comma after a bracket, this is most likely a template
2444 # argument. We have not seen a closing angle bracket yet, but
2445 # it's probably a few lines later if we look for it, so just
2446 # return early here.
2447 return True
2448 else:
2449 # Got some other operator.
2450 return False
2451
2452 else:
2453 # Expecting closing parenthesis or closing bracket
2454 if operator in ('<', '(', '['):
2455 nesting_stack.append(operator)
2456 elif operator in (')', ']'):
2457 # We don't bother checking for matching () or []. If we got
2458 # something like (] or [), it would have been a syntax error.
2459 nesting_stack.pop()
2460
2461 else:
2462 # Scan the next line
2463 linenum += 1
2464 if linenum >= len(clean_lines.elided):
2465 break
2466 line = clean_lines.elided[linenum]
2467
2468 # Exhausted all remaining lines and still no matching angle bracket.
2469 # Most likely the input was incomplete, otherwise we should have
2470 # seen a semicolon and returned early.
2471 return True
2472
2473
2474def FindPreviousMatchingAngleBracket(clean_lines, linenum, init_prefix):
2475 """Find the corresponding < that started a template.
2476
2477 Args:
2478 clean_lines: A CleansedLines instance containing the file.
2479 linenum: Current line number.
2480 init_prefix: Part of the current line before the initial >.
2481
2482 Returns:
2483 True if a matching bracket exists.
2484 """
2485 line = init_prefix
2486 nesting_stack = ['>']
2487 while True:
2488 # Find the previous operator
2489 match = Search(r'^(.*)([<>(),;\[\]])[^<>(),;\[\]]*$', line)
2490 if match:
2491 # Found an operator, update nesting stack
2492 operator = match.group(2)
2493 line = match.group(1)
2494
2495 if nesting_stack[-1] == '>':
2496 # Expecting opening angle bracket
2497 if operator in ('>', ')', ']'):
2498 nesting_stack.append(operator)
2499 elif operator == '<':
2500 nesting_stack.pop()
2501 if not nesting_stack:
2502 # Found matching angle bracket
2503 return True
2504 elif operator == ',':
2505 # Got a comma before a bracket, this is most likely a
2506 # template argument. The opening angle bracket is probably
2507 # there if we look for it, so just return early here.
2508 return True
2509 else:
2510 # Got some other operator.
2511 return False
2512
2513 else:
2514 # Expecting opening parenthesis or opening bracket
2515 if operator in ('>', ')', ']'):
2516 nesting_stack.append(operator)
2517 elif operator in ('(', '['):
2518 nesting_stack.pop()
2519
2520 else:
2521 # Scan the previous line
2522 linenum -= 1
2523 if linenum < 0:
2524 break
2525 line = clean_lines.elided[linenum]
2526
2527 # Exhausted all earlier lines and still no matching angle bracket.
2528 return False
2529
2530
2531def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002532 """Checks for the correctness of various spacing issues in the code.
2533
2534 Things we check for: spaces around operators, spaces after
2535 if/for/while/switch, no spaces around parens in function calls, two
2536 spaces between code and comment, don't start a block with a blank
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002537 line, don't end a function with a blank line, don't add a blank line
2538 after public/protected/private, don't have too many blank lines in a row.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002539
2540 Args:
2541 filename: The name of the current file.
2542 clean_lines: A CleansedLines instance containing the file.
2543 linenum: The number of the line to check.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002544 nesting_state: A _NestingState instance which maintains information about
2545 the current stack of nested blocks being parsed.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002546 error: The function to call with any errors found.
2547 """
2548
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002549 # Don't use "elided" lines here, otherwise we can't check commented lines.
2550 # Don't want to use "raw" either, because we don't want to check inside C++11
2551 # raw strings,
2552 raw = clean_lines.lines_without_raw_strings
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002553 line = raw[linenum]
2554
2555 # Before nixing comments, check if the line is blank for no good
2556 # reason. This includes the first line after a block is opened, and
2557 # blank lines at the end of a function (ie, right before a line like '}'
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002558 #
2559 # Skip all the blank line checks if we are immediately inside a
2560 # namespace body. In other words, don't issue blank line warnings
2561 # for this block:
2562 # namespace {
2563 #
2564 # }
2565 #
2566 # A warning about missing end of namespace comments will be issued instead.
2567 if IsBlankLine(line) and not nesting_state.InNamespaceBody():
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002568 elided = clean_lines.elided
2569 prev_line = elided[linenum - 1]
2570 prevbrace = prev_line.rfind('{')
2571 # TODO(unknown): Don't complain if line before blank line, and line after,
2572 # both start with alnums and are indented the same amount.
2573 # This ignores whitespace at the start of a namespace block
2574 # because those are not usually indented.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002575 if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002576 # OK, we have a blank line at the start of a code block. Before we
2577 # complain, we check if it is an exception to the rule: The previous
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002578 # non-empty line has the parameters of a function header that are indented
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002579 # 4 spaces (because they did not fit in a 80 column line when placed on
2580 # the same line as the function name). We also check for the case where
2581 # the previous line is indented 6 spaces, which may happen when the
2582 # initializers of a constructor do not fit into a 80 column line.
2583 exception = False
2584 if Match(r' {6}\w', prev_line): # Initializer list?
2585 # We are looking for the opening column of initializer list, which
2586 # should be indented 4 spaces to cause 6 space indentation afterwards.
2587 search_position = linenum-2
2588 while (search_position >= 0
2589 and Match(r' {6}\w', elided[search_position])):
2590 search_position -= 1
2591 exception = (search_position >= 0
2592 and elided[search_position][:5] == ' :')
2593 else:
2594 # Search for the function arguments or an initializer list. We use a
2595 # simple heuristic here: If the line is indented 4 spaces; and we have a
2596 # closing paren, without the opening paren, followed by an opening brace
2597 # or colon (for initializer lists) we assume that it is the last line of
2598 # a function header. If we have a colon indented 4 spaces, it is an
2599 # initializer list.
2600 exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
2601 prev_line)
2602 or Match(r' {4}:', prev_line))
2603
2604 if not exception:
2605 error(filename, linenum, 'whitespace/blank_line', 2,
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002606 'Redundant blank line at the start of a code block '
2607 'should be deleted.')
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002608 # Ignore blank lines at the end of a block in a long if-else
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002609 # chain, like this:
2610 # if (condition1) {
2611 # // Something followed by a blank line
2612 #
2613 # } else if (condition2) {
2614 # // Something else
2615 # }
2616 if linenum + 1 < clean_lines.NumLines():
2617 next_line = raw[linenum + 1]
2618 if (next_line
2619 and Match(r'\s*}', next_line)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002620 and next_line.find('} else ') == -1):
2621 error(filename, linenum, 'whitespace/blank_line', 3,
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002622 'Redundant blank line at the end of a code block '
2623 'should be deleted.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002624
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002625 matched = Match(r'\s*(public|protected|private):', prev_line)
2626 if matched:
2627 error(filename, linenum, 'whitespace/blank_line', 3,
2628 'Do not leave a blank line after "%s:"' % matched.group(1))
2629
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002630 # Next, we complain if there's a comment too near the text
2631 commentpos = line.find('//')
2632 if commentpos != -1:
2633 # Check if the // may be in quotes. If so, ignore it
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002634 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002635 if (line.count('"', 0, commentpos) -
2636 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
2637 # Allow one space for new scopes, two spaces otherwise:
2638 if (not Match(r'^\s*{ //', line) and
2639 ((commentpos >= 1 and
2640 line[commentpos-1] not in string.whitespace) or
2641 (commentpos >= 2 and
2642 line[commentpos-2] not in string.whitespace))):
2643 error(filename, linenum, 'whitespace/comments', 2,
2644 'At least two spaces is best between code and comments')
2645 # There should always be a space between the // and the comment
2646 commentend = commentpos + 2
2647 if commentend < len(line) and not line[commentend] == ' ':
2648 # but some lines are exceptions -- e.g. if they're big
2649 # comment delimiters like:
2650 # //----------------------------------------------------------
erg@google.com35589e62010-11-17 18:58:16 +00002651 # or are an empty C++ style Doxygen comment, like:
2652 # ///
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002653 # or C++ style Doxygen comments placed after the variable:
2654 # ///< Header comment
2655 # //!< Header comment
erg@google.com6317a9c2009-06-25 00:28:19 +00002656 # or they begin with multiple slashes followed by a space:
2657 # //////// Header comment
2658 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
erg@google.com35589e62010-11-17 18:58:16 +00002659 Search(r'^/$', line[commentend:]) or
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002660 Search(r'^!< ', line[commentend:]) or
2661 Search(r'^/< ', line[commentend:]) or
erg@google.com6317a9c2009-06-25 00:28:19 +00002662 Search(r'^/+ ', line[commentend:]))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002663 if not match:
2664 error(filename, linenum, 'whitespace/comments', 4,
2665 'Should have a space between // and comment')
2666 CheckComment(line[commentpos:], filename, linenum, error)
2667
2668 line = clean_lines.elided[linenum] # get rid of comments and strings
2669
2670 # Don't try to do spacing checks for operator methods
2671 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
2672
2673 # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
2674 # Otherwise not. Note we only check for non-spaces on *both* sides;
2675 # sometimes people put non-spaces on one side when aligning ='s among
2676 # many lines (not that this is behavior that I approve of...)
2677 if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line):
2678 error(filename, linenum, 'whitespace/operators', 4,
2679 'Missing spaces around =')
2680
2681 # It's ok not to have spaces around binary operators like + - * /, but if
2682 # there's too little whitespace, we get concerned. It's hard to tell,
2683 # though, so we punt on this one for now. TODO.
2684
2685 # You should always have whitespace around binary operators.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002686 #
2687 # Check <= and >= first to avoid false positives with < and >, then
2688 # check non-include lines for spacing around < and >.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002689 match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002690 if match:
2691 error(filename, linenum, 'whitespace/operators', 3,
2692 'Missing spaces around %s' % match.group(1))
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002693 # We allow no-spaces around << when used like this: 10<<20, but
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002694 # not otherwise (particularly, not when used as streams)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002695 # Also ignore using ns::operator<<;
2696 match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<(\S)', line)
2697 if (match and
2698 not (match.group(1).isdigit() and match.group(2).isdigit()) and
2699 not (match.group(1) == 'operator' and match.group(2) == ';')):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002700 error(filename, linenum, 'whitespace/operators', 3,
2701 'Missing spaces around <<')
2702 elif not Match(r'#.*include', line):
2703 # Avoid false positives on ->
2704 reduced_line = line.replace('->', '')
2705
2706 # Look for < that is not surrounded by spaces. This is only
2707 # triggered if both sides are missing spaces, even though
2708 # technically should should flag if at least one side is missing a
2709 # space. This is done to avoid some false positives with shifts.
2710 match = Search(r'[^\s<]<([^\s=<].*)', reduced_line)
2711 if (match and
2712 not FindNextMatchingAngleBracket(clean_lines, linenum, match.group(1))):
2713 error(filename, linenum, 'whitespace/operators', 3,
2714 'Missing spaces around <')
2715
2716 # Look for > that is not surrounded by spaces. Similar to the
2717 # above, we only trigger if both sides are missing spaces to avoid
2718 # false positives with shifts.
2719 match = Search(r'^(.*[^\s>])>[^\s=>]', reduced_line)
2720 if (match and
2721 not FindPreviousMatchingAngleBracket(clean_lines, linenum,
2722 match.group(1))):
2723 error(filename, linenum, 'whitespace/operators', 3,
2724 'Missing spaces around >')
2725
2726 # We allow no-spaces around >> for almost anything. This is because
2727 # C++11 allows ">>" to close nested templates, which accounts for
2728 # most cases when ">>" is not followed by a space.
2729 #
2730 # We still warn on ">>" followed by alpha character, because that is
2731 # likely due to ">>" being used for right shifts, e.g.:
2732 # value >> alpha
2733 #
2734 # When ">>" is used to close templates, the alphanumeric letter that
2735 # follows would be part of an identifier, and there should still be
2736 # a space separating the template type and the identifier.
2737 # type<type<type>> alpha
2738 match = Search(r'>>[a-zA-Z_]', line)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002739 if match:
2740 error(filename, linenum, 'whitespace/operators', 3,
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002741 'Missing spaces around >>')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002742
2743 # There shouldn't be space around unary operators
2744 match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
2745 if match:
2746 error(filename, linenum, 'whitespace/operators', 4,
2747 'Extra space for operator %s' % match.group(1))
2748
2749 # A pet peeve of mine: no spaces after an if, while, switch, or for
2750 match = Search(r' (if\(|for\(|while\(|switch\()', line)
2751 if match:
2752 error(filename, linenum, 'whitespace/parens', 5,
2753 'Missing space before ( in %s' % match.group(1))
2754
2755 # For if/for/while/switch, the left and right parens should be
2756 # consistent about how many spaces are inside the parens, and
2757 # there should either be zero or one spaces inside the parens.
2758 # We don't want: "if ( foo)" or "if ( foo )".
erg@google.com6317a9c2009-06-25 00:28:19 +00002759 # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002760 match = Search(r'\b(if|for|while|switch)\s*'
2761 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
2762 line)
2763 if match:
2764 if len(match.group(2)) != len(match.group(4)):
2765 if not (match.group(3) == ';' and
erg@google.com6317a9c2009-06-25 00:28:19 +00002766 len(match.group(2)) == 1 + len(match.group(4)) or
2767 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002768 error(filename, linenum, 'whitespace/parens', 5,
2769 'Mismatching spaces inside () in %s' % match.group(1))
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002770 if len(match.group(2)) not in [0, 1]:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002771 error(filename, linenum, 'whitespace/parens', 5,
2772 'Should have zero or one spaces inside ( and ) in %s' %
2773 match.group(1))
2774
2775 # You should always have a space after a comma (either as fn arg or operator)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002776 #
2777 # This does not apply when the non-space character following the
2778 # comma is another comma, since the only time when that happens is
2779 # for empty macro arguments.
2780 #
2781 # We run this check in two passes: first pass on elided lines to
2782 # verify that lines contain missing whitespaces, second pass on raw
2783 # lines to confirm that those missing whitespaces are not due to
2784 # elided comments.
2785 if Search(r',[^,\s]', line) and Search(r',[^,\s]', raw[linenum]):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002786 error(filename, linenum, 'whitespace/comma', 3,
2787 'Missing space after ,')
2788
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002789 # You should always have a space after a semicolon
2790 # except for few corner cases
2791 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more
2792 # space after ;
2793 if Search(r';[^\s};\\)/]', line):
2794 error(filename, linenum, 'whitespace/semicolon', 3,
2795 'Missing space after ;')
2796
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002797 # Next we will look for issues with function calls.
2798 CheckSpacingForFunctionCall(filename, line, linenum, error)
2799
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002800 # Except after an opening paren, or after another opening brace (in case of
2801 # an initializer list, for instance), you should have spaces before your
2802 # braces. And since you should never have braces at the beginning of a line,
2803 # this is an easy test.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002804 match = Match(r'^(.*[^ ({]){', line)
2805 if match:
2806 # Try a bit harder to check for brace initialization. This
2807 # happens in one of the following forms:
2808 # Constructor() : initializer_list_{} { ... }
2809 # Constructor{}.MemberFunction()
2810 # Type variable{};
2811 # FunctionCall(type{}, ...);
2812 # LastArgument(..., type{});
2813 # LOG(INFO) << type{} << " ...";
2814 # map_of_type[{...}] = ...;
2815 #
2816 # We check for the character following the closing brace, and
2817 # silence the warning if it's one of those listed above, i.e.
2818 # "{.;,)<]".
2819 #
2820 # To account for nested initializer list, we allow any number of
2821 # closing braces up to "{;,)<". We can't simply silence the
2822 # warning on first sight of closing brace, because that would
2823 # cause false negatives for things that are not initializer lists.
2824 # Silence this: But not this:
2825 # Outer{ if (...) {
2826 # Inner{...} if (...){ // Missing space before {
2827 # }; }
2828 #
2829 # There is a false negative with this approach if people inserted
2830 # spurious semicolons, e.g. "if (cond){};", but we will catch the
2831 # spurious semicolon with a separate check.
2832 (endline, endlinenum, endpos) = CloseExpression(
2833 clean_lines, linenum, len(match.group(1)))
2834 trailing_text = ''
2835 if endpos > -1:
2836 trailing_text = endline[endpos:]
2837 for offset in xrange(endlinenum + 1,
2838 min(endlinenum + 3, clean_lines.NumLines() - 1)):
2839 trailing_text += clean_lines.elided[offset]
2840 if not Match(r'^[\s}]*[{.;,)<\]]', trailing_text):
2841 error(filename, linenum, 'whitespace/braces', 5,
2842 'Missing space before {')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002843
2844 # Make sure '} else {' has spaces.
2845 if Search(r'}else', line):
2846 error(filename, linenum, 'whitespace/braces', 5,
2847 'Missing space before else')
2848
2849 # You shouldn't have spaces before your brackets, except maybe after
2850 # 'delete []' or 'new char * []'.
2851 if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
2852 error(filename, linenum, 'whitespace/braces', 5,
2853 'Extra space before [')
2854
2855 # You shouldn't have a space before a semicolon at the end of the line.
2856 # There's a special case for "for" since the style guide allows space before
2857 # the semicolon there.
2858 if Search(r':\s*;\s*$', line):
2859 error(filename, linenum, 'whitespace/semicolon', 5,
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002860 'Semicolon defining empty statement. Use {} instead.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002861 elif Search(r'^\s*;\s*$', line):
2862 error(filename, linenum, 'whitespace/semicolon', 5,
2863 'Line contains only semicolon. If this should be an empty statement, '
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002864 'use {} instead.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002865 elif (Search(r'\s+;\s*$', line) and
2866 not Search(r'\bfor\b', line)):
2867 error(filename, linenum, 'whitespace/semicolon', 5,
2868 'Extra space before last semicolon. If this should be an empty '
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002869 'statement, use {} instead.')
2870
2871 # In range-based for, we wanted spaces before and after the colon, but
2872 # not around "::" tokens that might appear.
2873 if (Search('for *\(.*[^:]:[^: ]', line) or
2874 Search('for *\(.*[^: ]:[^:]', line)):
2875 error(filename, linenum, 'whitespace/forcolon', 2,
2876 'Missing space around colon in range-based for loop')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002877
2878
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002879def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
2880 """Checks for additional blank line issues related to sections.
2881
2882 Currently the only thing checked here is blank line before protected/private.
2883
2884 Args:
2885 filename: The name of the current file.
2886 clean_lines: A CleansedLines instance containing the file.
2887 class_info: A _ClassInfo objects.
2888 linenum: The number of the line to check.
2889 error: The function to call with any errors found.
2890 """
2891 # Skip checks if the class is small, where small means 25 lines or less.
2892 # 25 lines seems like a good cutoff since that's the usual height of
2893 # terminals, and any class that can't fit in one screen can't really
2894 # be considered "small".
2895 #
2896 # Also skip checks if we are on the first line. This accounts for
2897 # classes that look like
2898 # class Foo { public: ... };
2899 #
2900 # If we didn't find the end of the class, last_line would be zero,
2901 # and the check will be skipped by the first condition.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002902 if (class_info.last_line - class_info.starting_linenum <= 24 or
2903 linenum <= class_info.starting_linenum):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002904 return
2905
2906 matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum])
2907 if matched:
2908 # Issue warning if the line before public/protected/private was
2909 # not a blank line, but don't do this if the previous line contains
2910 # "class" or "struct". This can happen two ways:
2911 # - We are at the beginning of the class.
2912 # - We are forward-declaring an inner class that is semantically
2913 # private, but needed to be public for implementation reasons.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002914 # Also ignores cases where the previous line ends with a backslash as can be
2915 # common when defining classes in C macros.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002916 prev_line = clean_lines.lines[linenum - 1]
2917 if (not IsBlankLine(prev_line) and
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002918 not Search(r'\b(class|struct)\b', prev_line) and
2919 not Search(r'\\$', prev_line)):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002920 # Try a bit harder to find the beginning of the class. This is to
2921 # account for multi-line base-specifier lists, e.g.:
2922 # class Derived
2923 # : public Base {
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002924 end_class_head = class_info.starting_linenum
2925 for i in range(class_info.starting_linenum, linenum):
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00002926 if Search(r'\{\s*$', clean_lines.lines[i]):
2927 end_class_head = i
2928 break
2929 if end_class_head < linenum - 1:
2930 error(filename, linenum, 'whitespace/blank_line', 3,
2931 '"%s:" should be preceded by a blank line' % matched.group(1))
2932
2933
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002934def GetPreviousNonBlankLine(clean_lines, linenum):
2935 """Return the most recent non-blank line and its line number.
2936
2937 Args:
2938 clean_lines: A CleansedLines instance containing the file contents.
2939 linenum: The number of the line to check.
2940
2941 Returns:
2942 A tuple with two elements. The first element is the contents of the last
2943 non-blank line before the current line, or the empty string if this is the
2944 first non-blank line. The second is the line number of that line, or -1
2945 if this is the first non-blank line.
2946 """
2947
2948 prevlinenum = linenum - 1
2949 while prevlinenum >= 0:
2950 prevline = clean_lines.elided[prevlinenum]
2951 if not IsBlankLine(prevline): # if not a blank line...
2952 return (prevline, prevlinenum)
2953 prevlinenum -= 1
2954 return ('', -1)
2955
2956
2957def CheckBraces(filename, clean_lines, linenum, error):
2958 """Looks for misplaced braces (e.g. at the end of line).
2959
2960 Args:
2961 filename: The name of the current file.
2962 clean_lines: A CleansedLines instance containing the file.
2963 linenum: The number of the line to check.
2964 error: The function to call with any errors found.
2965 """
2966
2967 line = clean_lines.elided[linenum] # get rid of comments and strings
2968
2969 if Match(r'\s*{\s*$', line):
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002970 # We allow an open brace to start a line in the case where someone is using
2971 # braces in a block to explicitly create a new scope, which is commonly used
2972 # to control the lifetime of stack-allocated variables. Braces are also
2973 # used for brace initializers inside function calls. We don't detect this
2974 # perfectly: we just don't complain if the last non-whitespace character on
2975 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the
2976 # previous line starts a preprocessor block.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002977 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00002978 if (not Search(r'[,;:}{(]\s*$', prevline) and
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00002979 not Match(r'\s*#', prevline)):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00002980 error(filename, linenum, 'whitespace/braces', 4,
2981 '{ should almost always be at the end of the previous line')
2982
2983 # An else clause should be on the same line as the preceding closing brace.
2984 if Match(r'\s*else\s*', line):
2985 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
2986 if Match(r'\s*}\s*$', prevline):
2987 error(filename, linenum, 'whitespace/newline', 4,
2988 'An else should appear on the same line as the preceding }')
2989
2990 # If braces come on one side of an else, they should be on both.
2991 # However, we have to worry about "else if" that spans multiple lines!
2992 if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
2993 if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if
2994 # find the ( after the if
2995 pos = line.find('else if')
2996 pos = line.find('(', pos)
2997 if pos > 0:
2998 (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
2999 if endline[endpos:].find('{') == -1: # must be brace after if
3000 error(filename, linenum, 'readability/braces', 5,
3001 'If an else has a brace on one side, it should have it on both')
3002 else: # common case: else not followed by a multi-line if
3003 error(filename, linenum, 'readability/braces', 5,
3004 'If an else has a brace on one side, it should have it on both')
3005
3006 # Likewise, an else should never have the else clause on the same line
3007 if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
3008 error(filename, linenum, 'whitespace/newline', 4,
3009 'Else clause should never be on same line as else (use 2 lines)')
3010
3011 # In the same way, a do/while should never be on one line
3012 if Match(r'\s*do [^\s{]', line):
3013 error(filename, linenum, 'whitespace/newline', 4,
3014 'do/while clauses should not be on a single line')
3015
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003016 # Block bodies should not be followed by a semicolon. Due to C++11
3017 # brace initialization, there are more places where semicolons are
3018 # required than not, so we use a whitelist approach to check these
3019 # rather than a blacklist. These are the places where "};" should
3020 # be replaced by just "}":
3021 # 1. Some flavor of block following closing parenthesis:
3022 # for (;;) {};
3023 # while (...) {};
3024 # switch (...) {};
3025 # Function(...) {};
3026 # if (...) {};
3027 # if (...) else if (...) {};
3028 #
3029 # 2. else block:
3030 # if (...) else {};
3031 #
3032 # 3. const member function:
3033 # Function(...) const {};
3034 #
3035 # 4. Block following some statement:
3036 # x = 42;
3037 # {};
3038 #
3039 # 5. Block at the beginning of a function:
3040 # Function(...) {
3041 # {};
3042 # }
3043 #
3044 # Note that naively checking for the preceding "{" will also match
3045 # braces inside multi-dimensional arrays, but this is fine since
3046 # that expression will not contain semicolons.
3047 #
3048 # 6. Block following another block:
3049 # while (true) {}
3050 # {};
3051 #
3052 # 7. End of namespaces:
3053 # namespace {};
3054 #
3055 # These semicolons seems far more common than other kinds of
3056 # redundant semicolons, possibly due to people converting classes
3057 # to namespaces. For now we do not warn for this case.
3058 #
3059 # Try matching case 1 first.
3060 match = Match(r'^(.*\)\s*)\{', line)
3061 if match:
3062 # Matched closing parenthesis (case 1). Check the token before the
3063 # matching opening parenthesis, and don't warn if it looks like a
3064 # macro. This avoids these false positives:
3065 # - macro that defines a base class
3066 # - multi-line macro that defines a base class
3067 # - macro that defines the whole class-head
3068 #
3069 # But we still issue warnings for macros that we know are safe to
3070 # warn, specifically:
3071 # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P
3072 # - TYPED_TEST
3073 # - INTERFACE_DEF
3074 # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED:
3075 #
3076 # We implement a whitelist of safe macros instead of a blacklist of
3077 # unsafe macros, even though the latter appears less frequently in
3078 # google code and would have been easier to implement. This is because
3079 # the downside for getting the whitelist wrong means some extra
3080 # semicolons, while the downside for getting the blacklist wrong
3081 # would result in compile errors.
3082 #
3083 # In addition to macros, we also don't want to warn on compound
3084 # literals.
3085 closing_brace_pos = match.group(1).rfind(')')
3086 opening_parenthesis = ReverseCloseExpression(
3087 clean_lines, linenum, closing_brace_pos)
3088 if opening_parenthesis[2] > -1:
3089 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]]
3090 macro = Search(r'\b([A-Z_]+)\s*$', line_prefix)
3091 if ((macro and
3092 macro.group(1) not in (
3093 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',
3094 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',
3095 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or
3096 Search(r'\s+=\s*$', line_prefix)):
3097 match = None
3098
3099 else:
3100 # Try matching cases 2-3.
3101 match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line)
3102 if not match:
3103 # Try matching cases 4-6. These are always matched on separate lines.
3104 #
3105 # Note that we can't simply concatenate the previous line to the
3106 # current line and do a single match, otherwise we may output
3107 # duplicate warnings for the blank line case:
3108 # if (cond) {
3109 # // blank line
3110 # }
3111 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
3112 if prevline and Search(r'[;{}]\s*$', prevline):
3113 match = Match(r'^(\s*)\{', line)
3114
3115 # Check matching closing brace
3116 if match:
3117 (endline, endlinenum, endpos) = CloseExpression(
3118 clean_lines, linenum, len(match.group(1)))
3119 if endpos > -1 and Match(r'^\s*;', endline[endpos:]):
3120 # Current {} pair is eligible for semicolon check, and we have found
3121 # the redundant semicolon, output warning here.
3122 #
3123 # Note: because we are scanning forward for opening braces, and
3124 # outputting warnings for the matching closing brace, if there are
3125 # nested blocks with trailing semicolons, we will get the error
3126 # messages in reversed order.
3127 error(filename, endlinenum, 'readability/braces', 4,
3128 "You don't need a ; after a }")
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003129
3130
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003131def CheckEmptyBlockBody(filename, clean_lines, linenum, error):
3132 """Look for empty loop/conditional body with only a single semicolon.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003133
3134 Args:
3135 filename: The name of the current file.
3136 clean_lines: A CleansedLines instance containing the file.
3137 linenum: The number of the line to check.
3138 error: The function to call with any errors found.
3139 """
3140
3141 # Search for loop keywords at the beginning of the line. Because only
3142 # whitespaces are allowed before the keywords, this will also ignore most
3143 # do-while-loops, since those lines should start with closing brace.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003144 #
3145 # We also check "if" blocks here, since an empty conditional block
3146 # is likely an error.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003147 line = clean_lines.elided[linenum]
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003148 matched = Match(r'\s*(for|while|if)\s*\(', line)
3149 if matched:
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003150 # Find the end of the conditional expression
3151 (end_line, end_linenum, end_pos) = CloseExpression(
3152 clean_lines, linenum, line.find('('))
3153
3154 # Output warning if what follows the condition expression is a semicolon.
3155 # No warning for all other cases, including whitespace or newline, since we
3156 # have a separate check for semicolons preceded by whitespace.
3157 if end_pos >= 0 and Match(r';', end_line[end_pos:]):
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003158 if matched.group(1) == 'if':
3159 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5,
3160 'Empty conditional bodies should use {}')
3161 else:
3162 error(filename, end_linenum, 'whitespace/empty_loop_body', 5,
3163 'Empty loop bodies should use {} or continue')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003164
3165
3166def CheckCheck(filename, clean_lines, linenum, error):
3167 """Checks the use of CHECK and EXPECT macros.
3168
3169 Args:
3170 filename: The name of the current file.
3171 clean_lines: A CleansedLines instance containing the file.
3172 linenum: The number of the line to check.
3173 error: The function to call with any errors found.
3174 """
3175
3176 # Decide the set of replacement macros that should be suggested
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003177 lines = clean_lines.elided
3178 check_macro = None
3179 start_pos = -1
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003180 for macro in _CHECK_MACROS:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003181 i = lines[linenum].find(macro)
3182 if i >= 0:
3183 check_macro = macro
3184
3185 # Find opening parenthesis. Do a regular expression match here
3186 # to make sure that we are matching the expected CHECK macro, as
3187 # opposed to some other macro that happens to contain the CHECK
3188 # substring.
3189 matched = Match(r'^(.*\b' + check_macro + r'\s*)\(', lines[linenum])
3190 if not matched:
3191 continue
3192 start_pos = len(matched.group(1))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003193 break
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003194 if not check_macro or start_pos < 0:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003195 # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
3196 return
3197
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003198 # Find end of the boolean expression by matching parentheses
3199 (last_line, end_line, end_pos) = CloseExpression(
3200 clean_lines, linenum, start_pos)
3201 if end_pos < 0:
3202 return
3203 if linenum == end_line:
3204 expression = lines[linenum][start_pos + 1:end_pos - 1]
3205 else:
3206 expression = lines[linenum][start_pos + 1:]
3207 for i in xrange(linenum + 1, end_line):
3208 expression += lines[i]
3209 expression += last_line[0:end_pos - 1]
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003210
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003211 # Parse expression so that we can take parentheses into account.
3212 # This avoids false positives for inputs like "CHECK((a < 4) == b)",
3213 # which is not replaceable by CHECK_LE.
3214 lhs = ''
3215 rhs = ''
3216 operator = None
3217 while expression:
3218 matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||'
3219 r'==|!=|>=|>|<=|<|\()(.*)$', expression)
3220 if matched:
3221 token = matched.group(1)
3222 if token == '(':
3223 # Parenthesized operand
3224 expression = matched.group(2)
3225 (end, _) = FindEndOfExpressionInLine(expression, 0, 1, '(', ')')
3226 if end < 0:
3227 return # Unmatched parenthesis
3228 lhs += '(' + expression[0:end]
3229 expression = expression[end:]
3230 elif token in ('&&', '||'):
3231 # Logical and/or operators. This means the expression
3232 # contains more than one term, for example:
3233 # CHECK(42 < a && a < b);
3234 #
3235 # These are not replaceable with CHECK_LE, so bail out early.
3236 return
3237 elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'):
3238 # Non-relational operator
3239 lhs += token
3240 expression = matched.group(2)
3241 else:
3242 # Relational operator
3243 operator = token
3244 rhs = matched.group(2)
3245 break
3246 else:
3247 # Unparenthesized operand. Instead of appending to lhs one character
3248 # at a time, we do another regular expression match to consume several
3249 # characters at once if possible. Trivial benchmark shows that this
3250 # is more efficient when the operands are longer than a single
3251 # character, which is generally the case.
3252 matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression)
3253 if not matched:
3254 matched = Match(r'^(\s*\S)(.*)$', expression)
3255 if not matched:
3256 break
3257 lhs += matched.group(1)
3258 expression = matched.group(2)
3259
3260 # Only apply checks if we got all parts of the boolean expression
3261 if not (lhs and operator and rhs):
3262 return
3263
3264 # Check that rhs do not contain logical operators. We already know
3265 # that lhs is fine since the loop above parses out && and ||.
3266 if rhs.find('&&') > -1 or rhs.find('||') > -1:
3267 return
3268
3269 # At least one of the operands must be a constant literal. This is
3270 # to avoid suggesting replacements for unprintable things like
3271 # CHECK(variable != iterator)
3272 #
3273 # The following pattern matches decimal, hex integers, strings, and
3274 # characters (in that order).
3275 lhs = lhs.strip()
3276 rhs = rhs.strip()
3277 match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$'
3278 if Match(match_constant, lhs) or Match(match_constant, rhs):
3279 # Note: since we know both lhs and rhs, we can provide a more
3280 # descriptive error message like:
3281 # Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42)
3282 # Instead of:
3283 # Consider using CHECK_EQ instead of CHECK(a == b)
3284 #
3285 # We are still keeping the less descriptive message because if lhs
3286 # or rhs gets long, the error message might become unreadable.
3287 error(filename, linenum, 'readability/check', 2,
3288 'Consider using %s instead of %s(a %s b)' % (
3289 _CHECK_REPLACEMENT[check_macro][operator],
3290 check_macro, operator))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003291
3292
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003293def CheckAltTokens(filename, clean_lines, linenum, error):
3294 """Check alternative keywords being used in boolean expressions.
3295
3296 Args:
3297 filename: The name of the current file.
3298 clean_lines: A CleansedLines instance containing the file.
3299 linenum: The number of the line to check.
3300 error: The function to call with any errors found.
3301 """
3302 line = clean_lines.elided[linenum]
3303
3304 # Avoid preprocessor lines
3305 if Match(r'^\s*#', line):
3306 return
3307
3308 # Last ditch effort to avoid multi-line comments. This will not help
3309 # if the comment started before the current line or ended after the
3310 # current line, but it catches most of the false positives. At least,
3311 # it provides a way to workaround this warning for people who use
3312 # multi-line comments in preprocessor macros.
3313 #
3314 # TODO(unknown): remove this once cpplint has better support for
3315 # multi-line comments.
3316 if line.find('/*') >= 0 or line.find('*/') >= 0:
3317 return
3318
3319 for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line):
3320 error(filename, linenum, 'readability/alt_tokens', 2,
3321 'Use operator %s instead of %s' % (
3322 _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))
3323
3324
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003325def GetLineWidth(line):
3326 """Determines the width of the line in column positions.
3327
3328 Args:
3329 line: A string, which may be a Unicode string.
3330
3331 Returns:
3332 The width of the line in column positions, accounting for Unicode
3333 combining characters and wide characters.
3334 """
3335 if isinstance(line, unicode):
3336 width = 0
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003337 for uc in unicodedata.normalize('NFC', line):
3338 if unicodedata.east_asian_width(uc) in ('W', 'F'):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003339 width += 2
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003340 elif not unicodedata.combining(uc):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003341 width += 1
3342 return width
3343 else:
3344 return len(line)
3345
3346
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003347def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003348 error):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003349 """Checks rules from the 'C++ style rules' section of cppguide.html.
3350
3351 Most of these rules are hard to test (naming, comment style), but we
3352 do what we can. In particular we check for 2-space indents, line lengths,
3353 tab usage, spaces inside code, etc.
3354
3355 Args:
3356 filename: The name of the current file.
3357 clean_lines: A CleansedLines instance containing the file.
3358 linenum: The number of the line to check.
3359 file_extension: The extension (without the dot) of the filename.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003360 nesting_state: A _NestingState instance which maintains information about
3361 the current stack of nested blocks being parsed.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003362 error: The function to call with any errors found.
3363 """
3364
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003365 # Don't use "elided" lines here, otherwise we can't check commented lines.
3366 # Don't want to use "raw" either, because we don't want to check inside C++11
3367 # raw strings,
3368 raw_lines = clean_lines.lines_without_raw_strings
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003369 line = raw_lines[linenum]
3370
3371 if line.find('\t') != -1:
3372 error(filename, linenum, 'whitespace/tab', 1,
3373 'Tab found; better to use spaces')
3374
3375 # One or three blank spaces at the beginning of the line is weird; it's
3376 # hard to reconcile that with 2-space indents.
3377 # NOTE: here are the conditions rob pike used for his tests. Mine aren't
3378 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
3379 # if(RLENGTH > 20) complain = 0;
3380 # if(match($0, " +(error|private|public|protected):")) complain = 0;
3381 # if(match(prev, "&& *$")) complain = 0;
3382 # if(match(prev, "\\|\\| *$")) complain = 0;
3383 # if(match(prev, "[\",=><] *$")) complain = 0;
3384 # if(match($0, " <<")) complain = 0;
3385 # if(match(prev, " +for \\(")) complain = 0;
3386 # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
3387 initial_spaces = 0
3388 cleansed_line = clean_lines.elided[linenum]
3389 while initial_spaces < len(line) and line[initial_spaces] == ' ':
3390 initial_spaces += 1
3391 if line and line[-1].isspace():
3392 error(filename, linenum, 'whitespace/end_of_line', 4,
3393 'Line ends in whitespace. Consider deleting these extra spaces.')
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003394 # There are certain situations we allow one space, notably for section labels
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003395 elif ((initial_spaces == 1 or initial_spaces == 3) and
3396 not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
3397 error(filename, linenum, 'whitespace/indent', 3,
3398 'Weird number of spaces at line-start. '
3399 'Are you using a 2-space indent?')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003400
3401 # Check if the line is a header guard.
3402 is_header_guard = False
3403 if file_extension == 'h':
3404 cppvar = GetHeaderGuardCPPVariable(filename)
3405 if (line.startswith('#ifndef %s' % cppvar) or
3406 line.startswith('#define %s' % cppvar) or
3407 line.startswith('#endif // %s' % cppvar)):
3408 is_header_guard = True
3409 # #include lines and header guards can be long, since there's no clean way to
3410 # split them.
erg@google.com6317a9c2009-06-25 00:28:19 +00003411 #
3412 # URLs can be long too. It's possible to split these, but it makes them
3413 # harder to cut&paste.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003414 #
3415 # The "$Id:...$" comment may also get very long without it being the
3416 # developers fault.
erg@google.com6317a9c2009-06-25 00:28:19 +00003417 if (not line.startswith('#include') and not is_header_guard and
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003418 not Match(r'^\s*//.*http(s?)://\S*$', line) and
3419 not Match(r'^// \$Id:.*#[0-9]+ \$$', line)):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003420 line_width = GetLineWidth(line)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003421 extended_length = int((_line_length * 1.25))
3422 if line_width > extended_length:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003423 error(filename, linenum, 'whitespace/line_length', 4,
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003424 'Lines should very rarely be longer than %i characters' %
3425 extended_length)
3426 elif line_width > _line_length:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003427 error(filename, linenum, 'whitespace/line_length', 2,
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003428 'Lines should be <= %i characters long' % _line_length)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003429
3430 if (cleansed_line.count(';') > 1 and
3431 # for loops are allowed two ;'s (and may run over two lines).
3432 cleansed_line.find('for') == -1 and
3433 (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
3434 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
3435 # It's ok to have many commands in a switch case that fits in 1 line
3436 not ((cleansed_line.find('case ') != -1 or
3437 cleansed_line.find('default:') != -1) and
3438 cleansed_line.find('break;') != -1)):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003439 error(filename, linenum, 'whitespace/newline', 0,
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003440 'More than one command on the same line')
3441
3442 # Some more style checks
3443 CheckBraces(filename, clean_lines, linenum, error)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003444 CheckEmptyBlockBody(filename, clean_lines, linenum, error)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003445 CheckAccess(filename, clean_lines, linenum, nesting_state, error)
3446 CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003447 CheckCheck(filename, clean_lines, linenum, error)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003448 CheckAltTokens(filename, clean_lines, linenum, error)
3449 classinfo = nesting_state.InnermostClass()
3450 if classinfo:
3451 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003452
3453
3454_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
3455_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
3456# Matches the first component of a filename delimited by -s and _s. That is:
3457# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
3458# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
3459# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
3460# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
3461_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
3462
3463
3464def _DropCommonSuffixes(filename):
3465 """Drops common suffixes like _test.cc or -inl.h from filename.
3466
3467 For example:
3468 >>> _DropCommonSuffixes('foo/foo-inl.h')
3469 'foo/foo'
3470 >>> _DropCommonSuffixes('foo/bar/foo.cc')
3471 'foo/bar/foo'
3472 >>> _DropCommonSuffixes('foo/foo_internal.h')
3473 'foo/foo'
3474 >>> _DropCommonSuffixes('foo/foo_unusualinternal.h')
3475 'foo/foo_unusualinternal'
3476
3477 Args:
3478 filename: The input filename.
3479
3480 Returns:
3481 The filename with the common suffix removed.
3482 """
3483 for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
3484 'inl.h', 'impl.h', 'internal.h'):
3485 if (filename.endswith(suffix) and len(filename) > len(suffix) and
3486 filename[-len(suffix) - 1] in ('-', '_')):
3487 return filename[:-len(suffix) - 1]
3488 return os.path.splitext(filename)[0]
3489
3490
3491def _IsTestFilename(filename):
3492 """Determines if the given filename has a suffix that identifies it as a test.
3493
3494 Args:
3495 filename: The input filename.
3496
3497 Returns:
3498 True if 'filename' looks like a test, False otherwise.
3499 """
3500 if (filename.endswith('_test.cc') or
3501 filename.endswith('_unittest.cc') or
3502 filename.endswith('_regtest.cc')):
3503 return True
3504 else:
3505 return False
3506
3507
3508def _ClassifyInclude(fileinfo, include, is_system):
3509 """Figures out what kind of header 'include' is.
3510
3511 Args:
3512 fileinfo: The current file cpplint is running over. A FileInfo instance.
3513 include: The path to a #included file.
3514 is_system: True if the #include used <> rather than "".
3515
3516 Returns:
3517 One of the _XXX_HEADER constants.
3518
3519 For example:
3520 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
3521 _C_SYS_HEADER
3522 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
3523 _CPP_SYS_HEADER
3524 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
3525 _LIKELY_MY_HEADER
3526 >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
3527 ... 'bar/foo_other_ext.h', False)
3528 _POSSIBLE_MY_HEADER
3529 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
3530 _OTHER_HEADER
3531 """
3532 # This is a list of all standard c++ header files, except
3533 # those already checked for above.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003534 is_cpp_h = include in _CPP_HEADERS
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003535
3536 if is_system:
3537 if is_cpp_h:
3538 return _CPP_SYS_HEADER
3539 else:
3540 return _C_SYS_HEADER
3541
3542 # If the target file and the include we're checking share a
3543 # basename when we drop common extensions, and the include
3544 # lives in . , then it's likely to be owned by the target file.
3545 target_dir, target_base = (
3546 os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
3547 include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
3548 if target_base == include_base and (
3549 include_dir == target_dir or
3550 include_dir == os.path.normpath(target_dir + '/../public')):
3551 return _LIKELY_MY_HEADER
3552
3553 # If the target and include share some initial basename
3554 # component, it's possible the target is implementing the
3555 # include, so it's allowed to be first, but we'll never
3556 # complain if it's not there.
3557 target_first_component = _RE_FIRST_COMPONENT.match(target_base)
3558 include_first_component = _RE_FIRST_COMPONENT.match(include_base)
3559 if (target_first_component and include_first_component and
3560 target_first_component.group(0) ==
3561 include_first_component.group(0)):
3562 return _POSSIBLE_MY_HEADER
3563
3564 return _OTHER_HEADER
3565
3566
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003567
erg@google.com6317a9c2009-06-25 00:28:19 +00003568def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
3569 """Check rules that are applicable to #include lines.
3570
3571 Strings on #include lines are NOT removed from elided line, to make
3572 certain tasks easier. However, to prevent false positives, checks
3573 applicable to #include lines in CheckLanguage must be put here.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003574
3575 Args:
3576 filename: The name of the current file.
3577 clean_lines: A CleansedLines instance containing the file.
3578 linenum: The number of the line to check.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003579 include_state: An _IncludeState instance in which the headers are inserted.
3580 error: The function to call with any errors found.
3581 """
3582 fileinfo = FileInfo(filename)
3583
erg@google.com6317a9c2009-06-25 00:28:19 +00003584 line = clean_lines.lines[linenum]
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003585
3586 # "include" should use the new style "foo/bar.h" instead of just "bar.h"
erg@google.com6317a9c2009-06-25 00:28:19 +00003587 if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003588 error(filename, linenum, 'build/include', 4,
3589 'Include the directory when naming .h files')
3590
3591 # we shouldn't include a file more than once. actually, there are a
3592 # handful of instances where doing so is okay, but in general it's
3593 # not.
erg@google.com6317a9c2009-06-25 00:28:19 +00003594 match = _RE_PATTERN_INCLUDE.search(line)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003595 if match:
3596 include = match.group(2)
3597 is_system = (match.group(1) == '<')
3598 if include in include_state:
3599 error(filename, linenum, 'build/include', 4,
3600 '"%s" already included at %s:%s' %
3601 (include, filename, include_state[include]))
3602 else:
3603 include_state[include] = linenum
3604
3605 # We want to ensure that headers appear in the right order:
3606 # 1) for foo.cc, foo.h (preferred location)
3607 # 2) c system files
3608 # 3) cpp system files
3609 # 4) for foo.cc, foo.h (deprecated location)
3610 # 5) other google headers
3611 #
3612 # We classify each include statement as one of those 5 types
3613 # using a number of techniques. The include_state object keeps
3614 # track of the highest type seen, and complains if we see a
3615 # lower type after that.
3616 error_message = include_state.CheckNextIncludeOrder(
3617 _ClassifyInclude(fileinfo, include, is_system))
3618 if error_message:
3619 error(filename, linenum, 'build/include_order', 4,
3620 '%s. Should be: %s.h, c system, c++ system, other.' %
3621 (error_message, fileinfo.BaseName()))
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003622 canonical_include = include_state.CanonicalizeAlphabeticalOrder(include)
3623 if not include_state.IsInAlphabeticalOrder(
3624 clean_lines, linenum, canonical_include):
erg@google.com26970fa2009-11-17 18:07:32 +00003625 error(filename, linenum, 'build/include_alpha', 4,
3626 'Include "%s" not in alphabetical order' % include)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003627 include_state.SetLastHeader(canonical_include)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003628
erg@google.com6317a9c2009-06-25 00:28:19 +00003629 # Look for any of the stream classes that are part of standard C++.
3630 match = _RE_PATTERN_INCLUDE.match(line)
3631 if match:
3632 include = match.group(2)
3633 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
3634 # Many unit tests use cout, so we exempt them.
3635 if not _IsTestFilename(filename):
3636 error(filename, linenum, 'readability/streams', 3,
3637 'Streams are highly discouraged.')
3638
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003639
3640def _GetTextInside(text, start_pattern):
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003641 r"""Retrieves all the text between matching open and close parentheses.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003642
3643 Given a string of lines and a regular expression string, retrieve all the text
3644 following the expression and between opening punctuation symbols like
3645 (, [, or {, and the matching close-punctuation symbol. This properly nested
3646 occurrences of the punctuations, so for the text like
3647 printf(a(), b(c()));
3648 a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'.
3649 start_pattern must match string having an open punctuation symbol at the end.
3650
3651 Args:
3652 text: The lines to extract text. Its comments and strings must be elided.
3653 It can be single line and can span multiple lines.
3654 start_pattern: The regexp string indicating where to start extracting
3655 the text.
3656 Returns:
3657 The extracted text.
3658 None if either the opening string or ending punctuation could not be found.
3659 """
3660 # TODO(sugawarayu): Audit cpplint.py to see what places could be profitably
3661 # rewritten to use _GetTextInside (and use inferior regexp matching today).
3662
3663 # Give opening punctuations to get the matching close-punctuations.
3664 matching_punctuation = {'(': ')', '{': '}', '[': ']'}
3665 closing_punctuation = set(matching_punctuation.itervalues())
3666
3667 # Find the position to start extracting text.
3668 match = re.search(start_pattern, text, re.M)
3669 if not match: # start_pattern not found in text.
3670 return None
3671 start_position = match.end(0)
3672
3673 assert start_position > 0, (
3674 'start_pattern must ends with an opening punctuation.')
3675 assert text[start_position - 1] in matching_punctuation, (
3676 'start_pattern must ends with an opening punctuation.')
3677 # Stack of closing punctuations we expect to have in text after position.
3678 punctuation_stack = [matching_punctuation[text[start_position - 1]]]
3679 position = start_position
3680 while punctuation_stack and position < len(text):
3681 if text[position] == punctuation_stack[-1]:
3682 punctuation_stack.pop()
3683 elif text[position] in closing_punctuation:
3684 # A closing punctuation without matching opening punctuations.
3685 return None
3686 elif text[position] in matching_punctuation:
3687 punctuation_stack.append(matching_punctuation[text[position]])
3688 position += 1
3689 if punctuation_stack:
3690 # Opening punctuations left without matching close-punctuations.
3691 return None
3692 # punctuations match.
3693 return text[start_position:position - 1]
3694
3695
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003696# Patterns for matching call-by-reference parameters.
3697#
3698# Supports nested templates up to 2 levels deep using this messy pattern:
3699# < (?: < (?: < [^<>]*
3700# >
3701# | [^<>] )*
3702# >
3703# | [^<>] )*
3704# >
3705_RE_PATTERN_IDENT = r'[_a-zA-Z]\w*' # =~ [[:alpha:]][[:alnum:]]*
3706_RE_PATTERN_TYPE = (
3707 r'(?:const\s+)?(?:typename\s+|class\s+|struct\s+|union\s+|enum\s+)?'
3708 r'(?:\w|'
3709 r'\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|'
3710 r'::)+')
3711# A call-by-reference parameter ends with '& identifier'.
3712_RE_PATTERN_REF_PARAM = re.compile(
3713 r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*'
3714 r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]')
3715# A call-by-const-reference parameter either ends with 'const& identifier'
3716# or looks like 'const type& identifier' when 'type' is atomic.
3717_RE_PATTERN_CONST_REF_PARAM = (
3718 r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT +
3719 r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')')
3720
3721
3722def CheckLanguage(filename, clean_lines, linenum, file_extension,
3723 include_state, nesting_state, error):
erg@google.com6317a9c2009-06-25 00:28:19 +00003724 """Checks rules from the 'C++ language rules' section of cppguide.html.
3725
3726 Some of these rules are hard to test (function overloading, using
3727 uint32 inappropriately), but we do the best we can.
3728
3729 Args:
3730 filename: The name of the current file.
3731 clean_lines: A CleansedLines instance containing the file.
3732 linenum: The number of the line to check.
3733 file_extension: The extension (without the dot) of the filename.
3734 include_state: An _IncludeState instance in which the headers are inserted.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003735 nesting_state: A _NestingState instance which maintains information about
3736 the current stack of nested blocks being parsed.
erg@google.com6317a9c2009-06-25 00:28:19 +00003737 error: The function to call with any errors found.
3738 """
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003739 # If the line is empty or consists of entirely a comment, no need to
3740 # check it.
3741 line = clean_lines.elided[linenum]
3742 if not line:
3743 return
3744
erg@google.com6317a9c2009-06-25 00:28:19 +00003745 match = _RE_PATTERN_INCLUDE.search(line)
3746 if match:
3747 CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
3748 return
3749
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003750 # Reset include state across preprocessor directives. This is meant
3751 # to silence warnings for conditional includes.
3752 if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line):
3753 include_state.ResetSection()
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003754
3755 # Make Windows paths like Unix.
3756 fullname = os.path.abspath(filename).replace('\\', '/')
3757
3758 # TODO(unknown): figure out if they're using default arguments in fn proto.
3759
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003760 # Check to see if they're using an conversion function cast.
3761 # I just try to capture the most common basic types, though there are more.
3762 # Parameterless conversion functions, such as bool(), are allowed as they are
3763 # probably a member operator declaration or default constructor.
3764 match = Search(
erg@google.com26970fa2009-11-17 18:07:32 +00003765 r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003766 r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
3767 r'(\([^)].*)', line)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003768 if match:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003769 matched_new = match.group(1)
3770 matched_type = match.group(2)
3771 matched_funcptr = match.group(3)
3772
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003773 # gMock methods are defined using some variant of MOCK_METHODx(name, type)
3774 # where type may be float(), int(string), etc. Without context they are
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003775 # virtually indistinguishable from int(x) casts. Likewise, gMock's
3776 # MockCallback takes a template parameter of the form return_type(arg_type),
3777 # which looks much like the cast we're trying to detect.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003778 #
3779 # std::function<> wrapper has a similar problem.
3780 #
3781 # Return types for function pointers also look like casts if they
3782 # don't have an extra space.
3783 if (matched_new is None and # If new operator, then this isn't a cast
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003784 not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003785 Search(r'\bMockCallback<.*>', line) or
3786 Search(r'\bstd::function<.*>', line)) and
3787 not (matched_funcptr and
3788 Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(',
3789 matched_funcptr))):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003790 # Try a bit harder to catch gmock lines: the only place where
3791 # something looks like an old-style cast is where we declare the
3792 # return type of the mocked method, and the only time when we
3793 # are missing context is if MOCK_METHOD was split across
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003794 # multiple lines. The missing MOCK_METHOD is usually one or two
3795 # lines back, so scan back one or two lines.
3796 #
3797 # It's not possible for gmock macros to appear in the first 2
3798 # lines, since the class head + section name takes up 2 lines.
3799 if (linenum < 2 or
3800 not (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
3801 clean_lines.elided[linenum - 1]) or
3802 Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
3803 clean_lines.elided[linenum - 2]))):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003804 error(filename, linenum, 'readability/casting', 4,
3805 'Using deprecated casting style. '
3806 'Use static_cast<%s>(...) instead' %
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003807 matched_type)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003808
3809 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3810 'static_cast',
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003811 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
3812
3813 # This doesn't catch all cases. Consider (const char * const)"hello".
3814 #
3815 # (char *) "foo" should always be a const_cast (reinterpret_cast won't
3816 # compile).
3817 if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3818 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error):
3819 pass
3820 else:
3821 # Check pointer casts for other than string constants
3822 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3823 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003824
3825 # In addition, we look for people taking the address of a cast. This
3826 # is dangerous -- casts can assign to temporaries, so the pointer doesn't
3827 # point where you think.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003828 match = Search(
3829 r'(?:&\(([^)]+)\)[\w(])|'
3830 r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line)
3831 if match and match.group(1) != '*':
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003832 error(filename, linenum, 'runtime/casting', 4,
3833 ('Are you taking an address of a cast? '
3834 'This is dangerous: could be a temp var. '
3835 'Take the address before doing the cast, rather than after'))
3836
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003837 # Create an extended_line, which is the concatenation of the current and
3838 # next lines, for more effective checking of code that may span more than one
3839 # line.
3840 if linenum + 1 < clean_lines.NumLines():
3841 extended_line = line + clean_lines.elided[linenum + 1]
3842 else:
3843 extended_line = line
3844
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003845 # Check for people declaring static/global STL strings at the top level.
3846 # This is dangerous because the C++ language does not guarantee that
3847 # globals with constructors are initialized before the first access.
3848 match = Match(
3849 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
3850 line)
3851 # Make sure it's not a function.
3852 # Function template specialization looks like: "string foo<Type>(...".
3853 # Class template definitions look like: "string Foo<Type>::Method(...".
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00003854 #
3855 # Also ignore things that look like operators. These are matched separately
3856 # because operator names cross non-word boundaries. If we change the pattern
3857 # above, we would decrease the accuracy of matching identifiers.
3858 if (match and
3859 not Search(r'\boperator\W', line) and
3860 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3))):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003861 error(filename, linenum, 'runtime/string', 4,
3862 'For a static/global string constant, use a C style string instead: '
3863 '"%schar %s[]".' %
3864 (match.group(1), match.group(2)))
3865
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003866 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
3867 error(filename, linenum, 'runtime/init', 4,
3868 'You seem to be initializing a member variable with itself.')
3869
3870 if file_extension == 'h':
3871 # TODO(unknown): check that 1-arg constructors are explicit.
3872 # How to tell it's a constructor?
3873 # (handled in CheckForNonStandardConstructs for now)
3874 # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
3875 # (level 1 error)
3876 pass
3877
3878 # Check if people are using the verboten C basic types. The only exception
3879 # we regularly allow is "unsigned short port" for port.
3880 if Search(r'\bshort port\b', line):
3881 if not Search(r'\bunsigned short port\b', line):
3882 error(filename, linenum, 'runtime/int', 4,
3883 'Use "unsigned short" for ports, not "short"')
3884 else:
3885 match = Search(r'\b(short|long(?! +double)|long long)\b', line)
3886 if match:
3887 error(filename, linenum, 'runtime/int', 4,
3888 'Use int16/int64/etc, rather than the C type %s' % match.group(1))
3889
3890 # When snprintf is used, the second argument shouldn't be a literal.
3891 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
erg@google.com35589e62010-11-17 18:58:16 +00003892 if match and match.group(2) != '0':
3893 # If 2nd arg is zero, snprintf is used to calculate size.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003894 error(filename, linenum, 'runtime/printf', 3,
3895 'If you can, use sizeof(%s) instead of %s as the 2nd arg '
3896 'to snprintf.' % (match.group(1), match.group(2)))
3897
3898 # Check if some verboten C functions are being used.
3899 if Search(r'\bsprintf\b', line):
3900 error(filename, linenum, 'runtime/printf', 5,
3901 'Never use sprintf. Use snprintf instead.')
3902 match = Search(r'\b(strcpy|strcat)\b', line)
3903 if match:
3904 error(filename, linenum, 'runtime/printf', 4,
3905 'Almost always, snprintf is better than %s' % match.group(1))
3906
erg@google.com26970fa2009-11-17 18:07:32 +00003907 # Check if some verboten operator overloading is going on
3908 # TODO(unknown): catch out-of-line unary operator&:
3909 # class X {};
3910 # int operator&(const X& x) { return 42; } // unary operator&
3911 # The trick is it's hard to tell apart from binary operator&:
3912 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
3913 if Search(r'\boperator\s*&\s*\(\s*\)', line):
3914 error(filename, linenum, 'runtime/operator', 4,
3915 'Unary operator& is dangerous. Do not use it.')
3916
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003917 # Check for suspicious usage of "if" like
3918 # } if (a == b) {
3919 if Search(r'\}\s*if\s*\(', line):
3920 error(filename, linenum, 'readability/braces', 4,
3921 'Did you mean "else if"? If not, start a new line for "if".')
3922
3923 # Check for potential format string bugs like printf(foo).
3924 # We constrain the pattern not to pick things like DocidForPrintf(foo).
3925 # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003926 # TODO(sugawarayu): Catch the following case. Need to change the calling
3927 # convention of the whole function to process multiple line to handle it.
3928 # printf(
3929 # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line);
3930 printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(')
3931 if printf_args:
3932 match = Match(r'([\w.\->()]+)$', printf_args)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00003933 if match and match.group(1) != '__VA_ARGS__':
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003934 function_name = re.search(r'\b((?:string)?printf)\s*\(',
3935 line, re.I).group(1)
3936 error(filename, linenum, 'runtime/printf', 4,
3937 'Potential format string bug. Do %s("%%s", %s) instead.'
3938 % (function_name, match.group(1)))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003939
3940 # Check for potential memset bugs like memset(buf, sizeof(buf), 0).
3941 match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
3942 if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
3943 error(filename, linenum, 'runtime/memset', 4,
3944 'Did you mean "memset(%s, 0, %s)"?'
3945 % (match.group(1), match.group(2)))
3946
3947 if Search(r'\busing namespace\b', line):
3948 error(filename, linenum, 'build/namespaces', 5,
3949 'Do not use namespace using-directives. '
3950 'Use using-declarations instead.')
3951
3952 # Detect variable-length arrays.
3953 match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
3954 if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
3955 match.group(3).find(']') == -1):
3956 # Split the size using space and arithmetic operators as delimiters.
3957 # If any of the resulting tokens are not compile time constants then
3958 # report the error.
3959 tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
3960 is_const = True
3961 skip_next = False
3962 for tok in tokens:
3963 if skip_next:
3964 skip_next = False
3965 continue
3966
3967 if Search(r'sizeof\(.+\)', tok): continue
3968 if Search(r'arraysize\(\w+\)', tok): continue
3969
3970 tok = tok.lstrip('(')
3971 tok = tok.rstrip(')')
3972 if not tok: continue
3973 if Match(r'\d+', tok): continue
3974 if Match(r'0[xX][0-9a-fA-F]+', tok): continue
3975 if Match(r'k[A-Z0-9]\w*', tok): continue
3976 if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
3977 if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
3978 # A catch all for tricky sizeof cases, including 'sizeof expression',
3979 # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00003980 # requires skipping the next token because we split on ' ' and '*'.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00003981 if tok.startswith('sizeof'):
3982 skip_next = True
3983 continue
3984 is_const = False
3985 break
3986 if not is_const:
3987 error(filename, linenum, 'runtime/arrays', 1,
3988 'Do not use variable-length arrays. Use an appropriately named '
3989 "('k' followed by CamelCase) compile-time constant for the size.")
3990
3991 # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or
3992 # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing
3993 # in the class declaration.
3994 match = Match(
3995 (r'\s*'
3996 r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'
3997 r'\(.*\);$'),
3998 line)
3999 if match and linenum + 1 < clean_lines.NumLines():
4000 next_line = clean_lines.elided[linenum + 1]
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004001 # We allow some, but not all, declarations of variables to be present
4002 # in the statement that defines the class. The [\w\*,\s]* fragment of
4003 # the regular expression below allows users to declare instances of
4004 # the class or pointers to instances, but not less common types such
4005 # as function pointers or arrays. It's a tradeoff between allowing
4006 # reasonable code and avoiding trying to parse more C++ using regexps.
4007 if not Search(r'^\s*}[\w\*,\s]*;', next_line):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004008 error(filename, linenum, 'readability/constructors', 3,
4009 match.group(1) + ' should be the last thing in the class')
4010
4011 # Check for use of unnamed namespaces in header files. Registration
4012 # macros are typically OK, so we allow use of "namespace {" on lines
4013 # that end with backslashes.
4014 if (file_extension == 'h'
4015 and Search(r'\bnamespace\s*{', line)
4016 and line[-1] != '\\'):
4017 error(filename, linenum, 'build/namespaces', 4,
4018 'Do not use unnamed namespaces in header files. See '
4019 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
4020 ' for more information.')
4021
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004022def CheckForNonConstReference(filename, clean_lines, linenum,
4023 nesting_state, error):
4024 """Check for non-const references.
4025
4026 Separate from CheckLanguage since it scans backwards from current
4027 line, instead of scanning forward.
4028
4029 Args:
4030 filename: The name of the current file.
4031 clean_lines: A CleansedLines instance containing the file.
4032 linenum: The number of the line to check.
4033 nesting_state: A _NestingState instance which maintains information about
4034 the current stack of nested blocks being parsed.
4035 error: The function to call with any errors found.
4036 """
4037 # Do nothing if there is no '&' on current line.
4038 line = clean_lines.elided[linenum]
4039 if '&' not in line:
4040 return
4041
4042 # Long type names may be broken across multiple lines, usually in one
4043 # of these forms:
4044 # LongType
4045 # ::LongTypeContinued &identifier
4046 # LongType::
4047 # LongTypeContinued &identifier
4048 # LongType<
4049 # ...>::LongTypeContinued &identifier
4050 #
4051 # If we detected a type split across two lines, join the previous
4052 # line to current line so that we can match const references
4053 # accordingly.
4054 #
4055 # Note that this only scans back one line, since scanning back
4056 # arbitrary number of lines would be expensive. If you have a type
4057 # that spans more than 2 lines, please use a typedef.
4058 if linenum > 1:
4059 previous = None
4060 if Match(r'\s*::(?:[\w<>]|::)+\s*&\s*\S', line):
4061 # previous_line\n + ::current_line
4062 previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$',
4063 clean_lines.elided[linenum - 1])
4064 elif Match(r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S', line):
4065 # previous_line::\n + current_line
4066 previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$',
4067 clean_lines.elided[linenum - 1])
4068 if previous:
4069 line = previous.group(1) + line.lstrip()
4070 else:
4071 # Check for templated parameter that is split across multiple lines
4072 endpos = line.rfind('>')
4073 if endpos > -1:
4074 (_, startline, startpos) = ReverseCloseExpression(
4075 clean_lines, linenum, endpos)
4076 if startpos > -1 and startline < linenum:
4077 # Found the matching < on an earlier line, collect all
4078 # pieces up to current line.
4079 line = ''
4080 for i in xrange(startline, linenum + 1):
4081 line += clean_lines.elided[i].strip()
4082
4083 # Check for non-const references in function parameters. A single '&' may
4084 # found in the following places:
4085 # inside expression: binary & for bitwise AND
4086 # inside expression: unary & for taking the address of something
4087 # inside declarators: reference parameter
4088 # We will exclude the first two cases by checking that we are not inside a
4089 # function body, including one that was just introduced by a trailing '{'.
4090 # TODO(unknwon): Doesn't account for preprocessor directives.
4091 # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare].
4092 check_params = False
4093 if not nesting_state.stack:
4094 check_params = True # top level
4095 elif (isinstance(nesting_state.stack[-1], _ClassInfo) or
4096 isinstance(nesting_state.stack[-1], _NamespaceInfo)):
4097 check_params = True # within class or namespace
4098 elif Match(r'.*{\s*$', line):
4099 if (len(nesting_state.stack) == 1 or
4100 isinstance(nesting_state.stack[-2], _ClassInfo) or
4101 isinstance(nesting_state.stack[-2], _NamespaceInfo)):
4102 check_params = True # just opened global/class/namespace block
4103 # We allow non-const references in a few standard places, like functions
4104 # called "swap()" or iostream operators like "<<" or ">>". Do not check
4105 # those function parameters.
4106 #
4107 # We also accept & in static_assert, which looks like a function but
4108 # it's actually a declaration expression.
4109 whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|'
4110 r'operator\s*[<>][<>]|'
4111 r'static_assert|COMPILE_ASSERT'
4112 r')\s*\(')
4113 if Search(whitelisted_functions, line):
4114 check_params = False
4115 elif not Search(r'\S+\([^)]*$', line):
4116 # Don't see a whitelisted function on this line. Actually we
4117 # didn't see any function name on this line, so this is likely a
4118 # multi-line parameter list. Try a bit harder to catch this case.
4119 for i in xrange(2):
4120 if (linenum > i and
4121 Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])):
4122 check_params = False
4123 break
4124
4125 if check_params:
4126 decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body
4127 for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls):
4128 if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter):
4129 error(filename, linenum, 'runtime/references', 2,
4130 'Is this a non-const reference? '
4131 'If so, make const or use a pointer: ' +
4132 ReplaceAll(' *<', '<', parameter))
4133
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004134
4135def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
4136 error):
4137 """Checks for a C-style cast by looking for the pattern.
4138
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004139 Args:
4140 filename: The name of the current file.
4141 linenum: The number of the line to check.
4142 line: The line of code to check.
4143 raw_line: The raw line of code to check, with comments.
4144 cast_type: The string for the C++ cast to recommend. This is either
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004145 reinterpret_cast, static_cast, or const_cast, depending.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004146 pattern: The regular expression used to find C-style casts.
4147 error: The function to call with any errors found.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004148
4149 Returns:
4150 True if an error was emitted.
4151 False otherwise.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004152 """
4153 match = Search(pattern, line)
4154 if not match:
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004155 return False
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004156
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004157 # Exclude lines with sizeof, since sizeof looks like a cast.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004158 sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
4159 if sizeof_match:
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004160 return False
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004161
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004162 # operator++(int) and operator--(int)
4163 if (line[0:match.start(1) - 1].endswith(' operator++') or
4164 line[0:match.start(1) - 1].endswith(' operator--')):
4165 return False
4166
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004167 # A single unnamed argument for a function tends to look like old
4168 # style cast. If we see those, don't issue warnings for deprecated
4169 # casts, instead issue warnings for unnamed arguments where
4170 # appropriate.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004171 #
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004172 # These are things that we want warnings for, since the style guide
4173 # explicitly require all parameters to be named:
4174 # Function(int);
4175 # Function(int) {
4176 # ConstMember(int) const;
4177 # ConstMember(int) const {
4178 # ExceptionMember(int) throw (...);
4179 # ExceptionMember(int) throw (...) {
4180 # PureVirtual(int) = 0;
4181 #
4182 # These are functions of some sort, where the compiler would be fine
4183 # if they had named parameters, but people often omit those
4184 # identifiers to reduce clutter:
4185 # (FunctionPointer)(int);
4186 # (FunctionPointer)(int) = value;
4187 # Function((function_pointer_arg)(int))
4188 # <TemplateArgument(int)>;
4189 # <(FunctionPointerTemplateArgument)(int)>;
4190 remainder = line[match.end(0):]
4191 if Match(r'^\s*(?:;|const\b|throw\b|=|>|\{|\))', remainder):
4192 # Looks like an unnamed parameter.
4193
4194 # Don't warn on any kind of template arguments.
4195 if Match(r'^\s*>', remainder):
4196 return False
4197
4198 # Don't warn on assignments to function pointers, but keep warnings for
4199 # unnamed parameters to pure virtual functions. Note that this pattern
4200 # will also pass on assignments of "0" to function pointers, but the
4201 # preferred values for those would be "nullptr" or "NULL".
4202 matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder)
4203 if matched_zero and matched_zero.group(1) != '0':
4204 return False
4205
4206 # Don't warn on function pointer declarations. For this we need
4207 # to check what came before the "(type)" string.
4208 if Match(r'.*\)\s*$', line[0:match.start(0)]):
4209 return False
4210
4211 # Don't warn if the parameter is named with block comments, e.g.:
4212 # Function(int /*unused_param*/);
4213 if '/*' in raw_line:
4214 return False
4215
4216 # Passed all filters, issue warning here.
4217 error(filename, linenum, 'readability/function', 3,
4218 'All parameters should be named in a function')
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004219 return True
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004220
4221 # At this point, all that should be left is actual casts.
4222 error(filename, linenum, 'readability/casting', 4,
4223 'Using C-style cast. Use %s<%s>(...) instead' %
4224 (cast_type, match.group(1)))
4225
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004226 return True
4227
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004228
4229_HEADERS_CONTAINING_TEMPLATES = (
4230 ('<deque>', ('deque',)),
4231 ('<functional>', ('unary_function', 'binary_function',
4232 'plus', 'minus', 'multiplies', 'divides', 'modulus',
4233 'negate',
4234 'equal_to', 'not_equal_to', 'greater', 'less',
4235 'greater_equal', 'less_equal',
4236 'logical_and', 'logical_or', 'logical_not',
4237 'unary_negate', 'not1', 'binary_negate', 'not2',
4238 'bind1st', 'bind2nd',
4239 'pointer_to_unary_function',
4240 'pointer_to_binary_function',
4241 'ptr_fun',
4242 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
4243 'mem_fun_ref_t',
4244 'const_mem_fun_t', 'const_mem_fun1_t',
4245 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
4246 'mem_fun_ref',
4247 )),
4248 ('<limits>', ('numeric_limits',)),
4249 ('<list>', ('list',)),
4250 ('<map>', ('map', 'multimap',)),
4251 ('<memory>', ('allocator',)),
4252 ('<queue>', ('queue', 'priority_queue',)),
4253 ('<set>', ('set', 'multiset',)),
4254 ('<stack>', ('stack',)),
4255 ('<string>', ('char_traits', 'basic_string',)),
4256 ('<utility>', ('pair',)),
4257 ('<vector>', ('vector',)),
4258
4259 # gcc extensions.
4260 # Note: std::hash is their hash, ::hash is our hash
4261 ('<hash_map>', ('hash_map', 'hash_multimap',)),
4262 ('<hash_set>', ('hash_set', 'hash_multiset',)),
4263 ('<slist>', ('slist',)),
4264 )
4265
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004266_RE_PATTERN_STRING = re.compile(r'\bstring\b')
4267
4268_re_pattern_algorithm_header = []
erg@google.com6317a9c2009-06-25 00:28:19 +00004269for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
4270 'transform'):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004271 # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
4272 # type::max().
4273 _re_pattern_algorithm_header.append(
4274 (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
4275 _template,
4276 '<algorithm>'))
4277
4278_re_pattern_templates = []
4279for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
4280 for _template in _templates:
4281 _re_pattern_templates.append(
4282 (re.compile(r'(\<|\b)' + _template + r'\s*\<'),
4283 _template + '<>',
4284 _header))
4285
4286
erg@google.com6317a9c2009-06-25 00:28:19 +00004287def FilesBelongToSameModule(filename_cc, filename_h):
4288 """Check if these two filenames belong to the same module.
4289
4290 The concept of a 'module' here is a as follows:
4291 foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the
4292 same 'module' if they are in the same directory.
4293 some/path/public/xyzzy and some/path/internal/xyzzy are also considered
4294 to belong to the same module here.
4295
4296 If the filename_cc contains a longer path than the filename_h, for example,
4297 '/absolute/path/to/base/sysinfo.cc', and this file would include
4298 'base/sysinfo.h', this function also produces the prefix needed to open the
4299 header. This is used by the caller of this function to more robustly open the
4300 header file. We don't have access to the real include paths in this context,
4301 so we need this guesswork here.
4302
4303 Known bugs: tools/base/bar.cc and base/bar.h belong to the same module
4304 according to this implementation. Because of this, this function gives
4305 some false positives. This should be sufficiently rare in practice.
4306
4307 Args:
4308 filename_cc: is the path for the .cc file
4309 filename_h: is the path for the header path
4310
4311 Returns:
4312 Tuple with a bool and a string:
4313 bool: True if filename_cc and filename_h belong to the same module.
4314 string: the additional prefix needed to open the header file.
4315 """
4316
4317 if not filename_cc.endswith('.cc'):
4318 return (False, '')
4319 filename_cc = filename_cc[:-len('.cc')]
4320 if filename_cc.endswith('_unittest'):
4321 filename_cc = filename_cc[:-len('_unittest')]
4322 elif filename_cc.endswith('_test'):
4323 filename_cc = filename_cc[:-len('_test')]
4324 filename_cc = filename_cc.replace('/public/', '/')
4325 filename_cc = filename_cc.replace('/internal/', '/')
4326
4327 if not filename_h.endswith('.h'):
4328 return (False, '')
4329 filename_h = filename_h[:-len('.h')]
4330 if filename_h.endswith('-inl'):
4331 filename_h = filename_h[:-len('-inl')]
4332 filename_h = filename_h.replace('/public/', '/')
4333 filename_h = filename_h.replace('/internal/', '/')
4334
4335 files_belong_to_same_module = filename_cc.endswith(filename_h)
4336 common_path = ''
4337 if files_belong_to_same_module:
4338 common_path = filename_cc[:-len(filename_h)]
4339 return files_belong_to_same_module, common_path
4340
4341
4342def UpdateIncludeState(filename, include_state, io=codecs):
4343 """Fill up the include_state with new includes found from the file.
4344
4345 Args:
4346 filename: the name of the header to read.
4347 include_state: an _IncludeState instance in which the headers are inserted.
4348 io: The io factory to use to read the file. Provided for testability.
4349
4350 Returns:
4351 True if a header was succesfully added. False otherwise.
4352 """
4353 headerfile = None
4354 try:
4355 headerfile = io.open(filename, 'r', 'utf8', 'replace')
4356 except IOError:
4357 return False
4358 linenum = 0
4359 for line in headerfile:
4360 linenum += 1
4361 clean_line = CleanseComments(line)
4362 match = _RE_PATTERN_INCLUDE.search(clean_line)
4363 if match:
4364 include = match.group(2)
4365 # The value formatting is cute, but not really used right now.
4366 # What matters here is that the key is in include_state.
4367 include_state.setdefault(include, '%s:%d' % (filename, linenum))
4368 return True
4369
4370
4371def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
4372 io=codecs):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004373 """Reports for missing stl includes.
4374
4375 This function will output warnings to make sure you are including the headers
4376 necessary for the stl containers and functions that you use. We only give one
4377 reason to include a header. For example, if you use both equal_to<> and
4378 less<> in a .h file, only one (the latter in the file) of these will be
4379 reported as a reason to include the <functional>.
4380
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004381 Args:
4382 filename: The name of the current file.
4383 clean_lines: A CleansedLines instance containing the file.
4384 include_state: An _IncludeState instance.
4385 error: The function to call with any errors found.
erg@google.com6317a9c2009-06-25 00:28:19 +00004386 io: The IO factory to use to read the header file. Provided for unittest
4387 injection.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004388 """
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004389 required = {} # A map of header name to linenumber and the template entity.
4390 # Example of required: { '<functional>': (1219, 'less<>') }
4391
4392 for linenum in xrange(clean_lines.NumLines()):
4393 line = clean_lines.elided[linenum]
4394 if not line or line[0] == '#':
4395 continue
4396
4397 # String is special -- it is a non-templatized type in STL.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004398 matched = _RE_PATTERN_STRING.search(line)
4399 if matched:
erg@google.com35589e62010-11-17 18:58:16 +00004400 # Don't warn about strings in non-STL namespaces:
4401 # (We check only the first match per line; good enough.)
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004402 prefix = line[:matched.start()]
erg@google.com35589e62010-11-17 18:58:16 +00004403 if prefix.endswith('std::') or not prefix.endswith('::'):
4404 required['<string>'] = (linenum, 'string')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004405
4406 for pattern, template, header in _re_pattern_algorithm_header:
4407 if pattern.search(line):
4408 required[header] = (linenum, template)
4409
4410 # The following function is just a speed up, no semantics are changed.
4411 if not '<' in line: # Reduces the cpu time usage by skipping lines.
4412 continue
4413
4414 for pattern, template, header in _re_pattern_templates:
4415 if pattern.search(line):
4416 required[header] = (linenum, template)
4417
erg@google.com6317a9c2009-06-25 00:28:19 +00004418 # The policy is that if you #include something in foo.h you don't need to
4419 # include it again in foo.cc. Here, we will look at possible includes.
4420 # Let's copy the include_state so it is only messed up within this function.
4421 include_state = include_state.copy()
4422
4423 # Did we find the header for this file (if any) and succesfully load it?
4424 header_found = False
4425
4426 # Use the absolute path so that matching works properly.
erg@chromium.org8f927562012-01-30 19:51:28 +00004427 abs_filename = FileInfo(filename).FullName()
erg@google.com6317a9c2009-06-25 00:28:19 +00004428
4429 # For Emacs's flymake.
4430 # If cpplint is invoked from Emacs's flymake, a temporary file is generated
4431 # by flymake and that file name might end with '_flymake.cc'. In that case,
4432 # restore original file name here so that the corresponding header file can be
4433 # found.
4434 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
4435 # instead of 'foo_flymake.h'
erg@google.com35589e62010-11-17 18:58:16 +00004436 abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename)
erg@google.com6317a9c2009-06-25 00:28:19 +00004437
4438 # include_state is modified during iteration, so we iterate over a copy of
4439 # the keys.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004440 header_keys = include_state.keys()
4441 for header in header_keys:
erg@google.com6317a9c2009-06-25 00:28:19 +00004442 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
4443 fullpath = common_path + header
4444 if same_module and UpdateIncludeState(fullpath, include_state, io):
4445 header_found = True
4446
4447 # If we can't find the header file for a .cc, assume it's because we don't
4448 # know where to look. In that case we'll give up as we're not sure they
4449 # didn't include it in the .h file.
4450 # TODO(unknown): Do a better job of finding .h files so we are confident that
4451 # not having the .h file means there isn't one.
4452 if filename.endswith('.cc') and not header_found:
4453 return
4454
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004455 # All the lines have been processed, report the errors found.
4456 for required_header_unstripped in required:
4457 template = required[required_header_unstripped][1]
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004458 if required_header_unstripped.strip('<>"') not in include_state:
4459 error(filename, required[required_header_unstripped][0],
4460 'build/include_what_you_use', 4,
4461 'Add #include ' + required_header_unstripped + ' for ' + template)
4462
4463
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004464_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<')
4465
4466
4467def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
4468 """Check that make_pair's template arguments are deduced.
4469
4470 G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are
4471 specified explicitly, and such use isn't intended in any case.
4472
4473 Args:
4474 filename: The name of the current file.
4475 clean_lines: A CleansedLines instance containing the file.
4476 linenum: The number of the line to check.
4477 error: The function to call with any errors found.
4478 """
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004479 line = clean_lines.elided[linenum]
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004480 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)
4481 if match:
4482 error(filename, linenum, 'build/explicit_make_pair',
4483 4, # 4 = high confidence
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004484 'For C++11-compatibility, omit template arguments from make_pair'
4485 ' OR use pair directly OR if appropriate, construct a pair directly')
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004486
4487
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004488def ProcessLine(filename, file_extension, clean_lines, line,
4489 include_state, function_state, nesting_state, error,
4490 extra_check_functions=[]):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004491 """Processes a single line in the file.
4492
4493 Args:
4494 filename: Filename of the file that is being processed.
4495 file_extension: The extension (dot not included) of the file.
4496 clean_lines: An array of strings, each representing a line of the file,
4497 with comments stripped.
4498 line: Number of line being processed.
4499 include_state: An _IncludeState instance in which the headers are inserted.
4500 function_state: A _FunctionState instance which counts function lines, etc.
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004501 nesting_state: A _NestingState instance which maintains information about
4502 the current stack of nested blocks being parsed.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004503 error: A callable to which errors are reported, which takes 4 arguments:
4504 filename, line number, error level, and message
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004505 extra_check_functions: An array of additional check functions that will be
4506 run on each source line. Each function takes 4
4507 arguments: filename, clean_lines, line, error
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004508 """
4509 raw_lines = clean_lines.raw_lines
erg@google.com35589e62010-11-17 18:58:16 +00004510 ParseNolintSuppressions(filename, raw_lines[line], line, error)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004511 nesting_state.Update(filename, clean_lines, line, error)
4512 if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM:
4513 return
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004514 CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004515 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004516 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004517 CheckLanguage(filename, clean_lines, line, file_extension, include_state,
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004518 nesting_state, error)
4519 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004520 CheckForNonStandardConstructs(filename, clean_lines, line,
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004521 nesting_state, error)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004522 CheckVlogArguments(filename, clean_lines, line, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004523 CheckPosixThreading(filename, clean_lines, line, error)
erg@google.com6317a9c2009-06-25 00:28:19 +00004524 CheckInvalidIncrement(filename, clean_lines, line, error)
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004525 CheckMakePairUsesDeduction(filename, clean_lines, line, error)
4526 for check_fn in extra_check_functions:
4527 check_fn(filename, clean_lines, line, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004528
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004529def ProcessFileData(filename, file_extension, lines, error,
4530 extra_check_functions=[]):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004531 """Performs lint checks and reports any errors to the given error function.
4532
4533 Args:
4534 filename: Filename of the file that is being processed.
4535 file_extension: The extension (dot not included) of the file.
4536 lines: An array of strings, each representing a line of the file, with the
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004537 last element being empty if the file is terminated with a newline.
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004538 error: A callable to which errors are reported, which takes 4 arguments:
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004539 filename, line number, error level, and message
4540 extra_check_functions: An array of additional check functions that will be
4541 run on each source line. Each function takes 4
4542 arguments: filename, clean_lines, line, error
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004543 """
4544 lines = (['// marker so line numbers and indices both start at 1'] + lines +
4545 ['// marker so line numbers end in a known way'])
4546
4547 include_state = _IncludeState()
4548 function_state = _FunctionState()
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004549 nesting_state = _NestingState()
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004550
erg@google.com35589e62010-11-17 18:58:16 +00004551 ResetNolintSuppressions()
4552
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004553 CheckForCopyright(filename, lines, error)
4554
4555 if file_extension == 'h':
4556 CheckForHeaderGuard(filename, lines, error)
4557
4558 RemoveMultiLineComments(filename, lines, error)
4559 clean_lines = CleansedLines(lines)
4560 for line in xrange(clean_lines.NumLines()):
4561 ProcessLine(filename, file_extension, clean_lines, line,
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004562 include_state, function_state, nesting_state, error,
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004563 extra_check_functions)
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004564 nesting_state.CheckCompletedBlocks(filename, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004565
4566 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
4567
4568 # We check here rather than inside ProcessLine so that we see raw
4569 # lines rather than "cleaned" lines.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004570 CheckForBadCharacters(filename, lines, error)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004571
4572 CheckForNewlineAtEOF(filename, lines, error)
4573
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004574def ProcessFile(filename, vlevel, extra_check_functions=[]):
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004575 """Does google-lint on a single file.
4576
4577 Args:
4578 filename: The name of the file to parse.
4579
4580 vlevel: The level of errors to report. Every error of confidence
4581 >= verbose_level will be reported. 0 is a good default.
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004582
4583 extra_check_functions: An array of additional check functions that will be
4584 run on each source line. Each function takes 4
4585 arguments: filename, clean_lines, line, error
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004586 """
4587
4588 _SetVerboseLevel(vlevel)
4589
4590 try:
4591 # Support the UNIX convention of using "-" for stdin. Note that
4592 # we are not opening the file with universal newline support
4593 # (which codecs doesn't support anyway), so the resulting lines do
4594 # contain trailing '\r' characters if we are reading a file that
4595 # has CRLF endings.
4596 # If after the split a trailing '\r' is present, it is removed
4597 # below. If it is not expected to be present (i.e. os.linesep !=
4598 # '\r\n' as in Windows), a warning is issued below if this file
4599 # is processed.
4600
4601 if filename == '-':
4602 lines = codecs.StreamReaderWriter(sys.stdin,
4603 codecs.getreader('utf8'),
4604 codecs.getwriter('utf8'),
4605 'replace').read().split('\n')
4606 else:
4607 lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
4608
4609 carriage_return_found = False
4610 # Remove trailing '\r'.
4611 for linenum in range(len(lines)):
4612 if lines[linenum].endswith('\r'):
4613 lines[linenum] = lines[linenum].rstrip('\r')
4614 carriage_return_found = True
4615
4616 except IOError:
4617 sys.stderr.write(
4618 "Skipping input '%s': Can't open for reading\n" % filename)
4619 return
4620
4621 # Note, if no dot is found, this will give the entire filename as the ext.
4622 file_extension = filename[filename.rfind('.') + 1:]
4623
4624 # When reading from stdin, the extension is unknown, so no cpplint tests
4625 # should rely on the extension.
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004626 if filename != '-' and file_extension not in _valid_extensions:
4627 sys.stderr.write('Ignoring %s; not a valid file name '
4628 '(%s)\n' % (filename, ', '.join(_valid_extensions)))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004629 else:
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004630 ProcessFileData(filename, file_extension, lines, Error,
4631 extra_check_functions)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004632 if carriage_return_found and os.linesep != '\r\n':
asvitkine@chromium.org8b8d8be2011-09-08 15:34:45 +00004633 # Use 0 for linenum since outputting only one error for potentially
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004634 # several lines.
4635 Error(filename, 0, 'whitespace/newline', 1,
4636 'One or more unexpected \\r (^M) found;'
4637 'better to use only a \\n')
4638
4639 sys.stderr.write('Done processing %s\n' % filename)
4640
4641
4642def PrintUsage(message):
4643 """Prints a brief usage string and exits, optionally with an error message.
4644
4645 Args:
4646 message: The optional error message.
4647 """
4648 sys.stderr.write(_USAGE)
4649 if message:
4650 sys.exit('\nFATAL ERROR: ' + message)
4651 else:
4652 sys.exit(1)
4653
4654
4655def PrintCategories():
4656 """Prints a list of all the error-categories used by error messages.
4657
4658 These are the categories used to filter messages via --filter.
4659 """
erg@google.com35589e62010-11-17 18:58:16 +00004660 sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES))
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004661 sys.exit(0)
4662
4663
4664def ParseArguments(args):
4665 """Parses the command line arguments.
4666
4667 This may set the output format and verbosity level as side-effects.
4668
4669 Args:
4670 args: The command line arguments:
4671
4672 Returns:
4673 The list of filenames to lint.
4674 """
4675 try:
4676 (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
erg@google.com26970fa2009-11-17 18:07:32 +00004677 'counting=',
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004678 'filter=',
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004679 'root=',
4680 'linelength=',
4681 'extensions='])
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004682 except getopt.GetoptError:
4683 PrintUsage('Invalid arguments.')
4684
4685 verbosity = _VerboseLevel()
4686 output_format = _OutputFormat()
4687 filters = ''
erg@google.com26970fa2009-11-17 18:07:32 +00004688 counting_style = ''
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004689
4690 for (opt, val) in opts:
4691 if opt == '--help':
4692 PrintUsage(None)
4693 elif opt == '--output':
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004694 if val not in ('emacs', 'vs7', 'eclipse'):
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004695 PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004696 output_format = val
4697 elif opt == '--verbose':
4698 verbosity = int(val)
4699 elif opt == '--filter':
4700 filters = val
erg@google.com6317a9c2009-06-25 00:28:19 +00004701 if not filters:
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004702 PrintCategories()
erg@google.com26970fa2009-11-17 18:07:32 +00004703 elif opt == '--counting':
4704 if val not in ('total', 'toplevel', 'detailed'):
4705 PrintUsage('Valid counting options are total, toplevel, and detailed')
4706 counting_style = val
mazda@chromium.org3fffcec2013-06-07 01:04:53 +00004707 elif opt == '--root':
4708 global _root
4709 _root = val
raphael.kubo.da.costa@intel.com331fbc42014-05-09 08:48:20 +00004710 elif opt == '--linelength':
4711 global _line_length
4712 try:
4713 _line_length = int(val)
4714 except ValueError:
4715 PrintUsage('Line length must be digits.')
4716 elif opt == '--extensions':
4717 global _valid_extensions
4718 try:
4719 _valid_extensions = set(val.split(','))
4720 except ValueError:
4721 PrintUsage('Extensions must be comma seperated list.')
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004722
4723 if not filenames:
4724 PrintUsage('No files were specified.')
4725
4726 _SetOutputFormat(output_format)
4727 _SetVerboseLevel(verbosity)
4728 _SetFilters(filters)
erg@google.com26970fa2009-11-17 18:07:32 +00004729 _SetCountingStyle(counting_style)
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004730
4731 return filenames
4732
4733
4734def main():
4735 filenames = ParseArguments(sys.argv[1:])
4736
4737 # Change stderr to write with replacement characters so we don't die
4738 # if we try to print something containing non-ASCII characters.
4739 sys.stderr = codecs.StreamReaderWriter(sys.stderr,
4740 codecs.getreader('utf8'),
4741 codecs.getwriter('utf8'),
4742 'replace')
4743
erg@google.com26970fa2009-11-17 18:07:32 +00004744 _cpplint_state.ResetErrorCounts()
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004745 for filename in filenames:
4746 ProcessFile(filename, _cpplint_state.verbose_level)
erg@google.com26970fa2009-11-17 18:07:32 +00004747 _cpplint_state.PrintErrorCounts()
4748
maruel@google.comfb2b8eb2009-04-23 21:03:42 +00004749 sys.exit(_cpplint_state.error_count > 0)
4750
4751
4752if __name__ == '__main__':
4753 main()