Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: cpplint.py

Issue 269013009: Update cpplint.py to r119. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright (c) 2009 Google Inc. All rights reserved. 3 # Copyright (c) 2009 Google Inc. All rights reserved.
4 # 4 #
5 # Redistribution and use in source and binary forms, with or without 5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are 6 # modification, are permitted provided that the following conditions are
7 # met: 7 # met:
8 # 8 #
9 # * Redistributions of source code must retain the above copyright 9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer. 10 # notice, this list of conditions and the following disclaimer.
(...skipping 10 matching lines...) Expand all
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 # Here are some issues that I've had people identify in my code during reviews,
32 # that I think are possible to flag automatically in a lint tool. If these were
33 # caught by lint, it would save time both for myself and that of my reviewers.
34 # Most likely, some of these are beyond the scope of the current lint framework,
35 # but I think it is valuable to retain these wish-list items even if they cannot
36 # be immediately implemented.
37 #
38 # Suggestions
39 # -----------
40 # - Check for no 'explicit' for multi-arg ctor
41 # - Check for boolean assign RHS in parens
42 # - Check for ctor initializer-list colon position and spacing
43 # - Check that if there's a ctor, there should be a dtor
44 # - Check accessors that return non-pointer member variables are
45 # declared const
46 # - Check accessors that return non-const pointer member vars are
47 # *not* declared const
48 # - Check for using public includes for testing
49 # - Check for spaces between brackets in one-line inline method
50 # - Check for no assert()
51 # - Check for spaces surrounding operators
52 # - Check for 0 in pointer context (should be NULL)
53 # - Check for 0 in char context (should be '\0')
54 # - Check for camel-case method name conventions for methods
55 # that are not simple inline getters and setters
56 # - Do not indent namespace contents
57 # - Avoid inlining non-trivial constructors in header files
58 # - Check for old-school (void) cast for call-sites of functions
59 # ignored return value
60 # - Check gUnit usage of anonymous namespace
61 # - Check for class declaration order (typedefs, consts, enums,
62 # ctor(s?), dtor, friend declarations, methods, member vars)
63 #
64
65 """Does google-lint on c++ files. 31 """Does google-lint on c++ files.
66 32
67 The goal of this script is to identify places in the code that *may* 33 The goal of this script is to identify places in the code that *may*
68 be in non-compliance with google style. It does not attempt to fix 34 be in non-compliance with google style. It does not attempt to fix
69 up these problems -- the point is to educate. It does also not 35 up these problems -- the point is to educate. It does also not
70 attempt to find all problems, or to ensure that everything it does 36 attempt to find all problems, or to ensure that everything it does
71 find is legitimately a problem. 37 find is legitimately a problem.
72 38
73 In particular, we can get very confused by /* and // inside strings! 39 In particular, we can get very confused by /* and // inside strings!
74 We do a small hack, which is to ignore //'s with "'s after them on the 40 We do a small hack, which is to ignore //'s with "'s after them on the
75 same line, but it is far from perfect (in either direction). 41 same line, but it is far from perfect (in either direction).
76 """ 42 """
77 43
78 import codecs 44 import codecs
79 import copy 45 import copy
80 import getopt 46 import getopt
81 import math # for log 47 import math # for log
82 import os 48 import os
83 import re 49 import re
84 import sre_compile 50 import sre_compile
85 import string 51 import string
86 import sys 52 import sys
87 import unicodedata 53 import unicodedata
88 54
89 55
90 _USAGE = """ 56 _USAGE = """
91 Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] 57 Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
92 [--counting=total|toplevel|detailed] 58 [--counting=total|toplevel|detailed] [--root=subdir]
59 [--linelength=digits]
93 <file> [file] ... 60 <file> [file] ...
94 61
95 The style guidelines this tries to follow are those in 62 The style guidelines this tries to follow are those in
96 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 63 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
97 64
98 Every problem is given a confidence score from 1-5, with 5 meaning we are 65 Every problem is given a confidence score from 1-5, with 5 meaning we are
99 certain of the problem, and 1 meaning it could be a legitimate construct. 66 certain of the problem, and 1 meaning it could be a legitimate construct.
100 This will miss some errors, and is not a substitute for a code review. 67 This will miss some errors, and is not a substitute for a code review.
101 68
102 To suppress false-positive errors of a certain category, add a 69 To suppress false-positive errors of a certain category, add a
103 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) 70 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*)
104 suppresses errors of all categories on that line. 71 suppresses errors of all categories on that line.
105 72
106 The files passed in will be linted; at least one file must be provided. 73 The files passed in will be linted; at least one file must be provided.
107 Linted extensions are .cc, .cpp, and .h. Other file types will be ignored. 74 Default linted extensions are .cc, .cpp, .cu, .cuh and .h. Change the
75 extensions with the --extensions flag.
108 76
109 Flags: 77 Flags:
110 78
111 output=vs7 79 output=vs7
112 By default, the output is formatted to ease emacs parsing. Visual Studio 80 By default, the output is formatted to ease emacs parsing. Visual Studio
113 compatible output (vs7) may also be used. Other formats are unsupported. 81 compatible output (vs7) may also be used. Other formats are unsupported.
114 82
115 verbose=# 83 verbose=#
116 Specify a number 0-5 to restrict errors to certain verbosity levels. 84 Specify a number 0-5 to restrict errors to certain verbosity levels.
117 85
(...skipping 27 matching lines...) Expand all
145 directory. If the specified directory does not exist, this flag is 113 directory. If the specified directory does not exist, this flag is
146 ignored. 114 ignored.
147 115
148 Examples: 116 Examples:
149 Assuing that src/.git exists, the header guard CPP variables for 117 Assuing that src/.git exists, the header guard CPP variables for
150 src/chrome/browser/ui/browser.h are: 118 src/chrome/browser/ui/browser.h are:
151 119
152 No flag => CHROME_BROWSER_UI_BROWSER_H_ 120 No flag => CHROME_BROWSER_UI_BROWSER_H_
153 --root=chrome => BROWSER_UI_BROWSER_H_ 121 --root=chrome => BROWSER_UI_BROWSER_H_
154 --root=chrome/browser => UI_BROWSER_H_ 122 --root=chrome/browser => UI_BROWSER_H_
123
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
155 """ 136 """
156 137
157 # We categorize each error message we print. Here are the categories. 138 # We categorize each error message we print. Here are the categories.
158 # We want an explicit list so we can list them all in cpplint --filter=. 139 # We want an explicit list so we can list them all in cpplint --filter=.
159 # If you add a new error message with a new category, add it to the list 140 # If you add a new error message with a new category, add it to the list
160 # here! cpplint_unittest.py should tell you if you forget to do this. 141 # here! cpplint_unittest.py should tell you if you forget to do this.
161 # \ used for clearer layout -- pylint: disable-msg=C6013
162 _ERROR_CATEGORIES = [ 142 _ERROR_CATEGORIES = [
163 'build/class', 143 'build/class',
164 'build/deprecated', 144 'build/deprecated',
165 'build/endif_comment', 145 'build/endif_comment',
166 'build/explicit_make_pair', 146 'build/explicit_make_pair',
167 'build/forward_decl', 147 'build/forward_decl',
168 'build/header_guard', 148 'build/header_guard',
169 'build/include', 149 'build/include',
170 'build/include_alpha', 150 'build/include_alpha',
171 'build/include_order', 151 'build/include_order',
172 'build/include_what_you_use', 152 'build/include_what_you_use',
173 'build/namespaces', 153 'build/namespaces',
174 'build/printf_format', 154 'build/printf_format',
175 'build/storage_class', 155 'build/storage_class',
176 'legal/copyright', 156 'legal/copyright',
177 'readability/alt_tokens', 157 'readability/alt_tokens',
178 'readability/braces', 158 'readability/braces',
179 'readability/casting', 159 'readability/casting',
180 'readability/check', 160 'readability/check',
181 'readability/constructors', 161 'readability/constructors',
182 'readability/fn_size', 162 'readability/fn_size',
183 'readability/function', 163 'readability/function',
184 'readability/multiline_comment', 164 'readability/multiline_comment',
185 'readability/multiline_string', 165 'readability/multiline_string',
186 'readability/namespace', 166 'readability/namespace',
187 'readability/nolint', 167 'readability/nolint',
168 'readability/nul',
188 'readability/streams', 169 'readability/streams',
189 'readability/todo', 170 'readability/todo',
190 'readability/utf8', 171 'readability/utf8',
191 'runtime/arrays', 172 'runtime/arrays',
192 'runtime/casting', 173 'runtime/casting',
193 'runtime/explicit', 174 'runtime/explicit',
194 'runtime/int', 175 'runtime/int',
195 'runtime/init', 176 'runtime/init',
196 'runtime/invalid_increment', 177 'runtime/invalid_increment',
197 'runtime/member_string_references', 178 'runtime/member_string_references',
198 'runtime/memset', 179 'runtime/memset',
199 'runtime/operator', 180 'runtime/operator',
200 'runtime/printf', 181 'runtime/printf',
201 'runtime/printf_format', 182 'runtime/printf_format',
202 'runtime/references', 183 'runtime/references',
203 'runtime/rtti',
204 'runtime/sizeof',
205 'runtime/string', 184 'runtime/string',
206 'runtime/threadsafe_fn', 185 'runtime/threadsafe_fn',
186 'runtime/vlog',
207 'whitespace/blank_line', 187 'whitespace/blank_line',
208 'whitespace/braces', 188 'whitespace/braces',
209 'whitespace/comma', 189 'whitespace/comma',
210 'whitespace/comments', 190 'whitespace/comments',
191 'whitespace/empty_conditional_body',
211 'whitespace/empty_loop_body', 192 'whitespace/empty_loop_body',
212 'whitespace/end_of_line', 193 'whitespace/end_of_line',
213 'whitespace/ending_newline', 194 'whitespace/ending_newline',
214 'whitespace/forcolon', 195 'whitespace/forcolon',
215 'whitespace/indent', 196 'whitespace/indent',
216 'whitespace/labels',
217 'whitespace/line_length', 197 'whitespace/line_length',
218 'whitespace/newline', 198 'whitespace/newline',
219 'whitespace/operators', 199 'whitespace/operators',
220 'whitespace/parens', 200 'whitespace/parens',
221 'whitespace/semicolon', 201 'whitespace/semicolon',
222 'whitespace/tab', 202 'whitespace/tab',
223 'whitespace/todo' 203 'whitespace/todo'
224 ] 204 ]
225 205
226 # The default state of the category filter. This is overrided by the --filter= 206 # The default state of the category filter. This is overrided by the --filter=
227 # flag. By default all errors are on, so only add here categories that should be 207 # flag. By default all errors are on, so only add here categories that should be
228 # off by default (i.e., categories that must be enabled by the --filter= flags). 208 # off by default (i.e., categories that must be enabled by the --filter= flags).
229 # All entries here should start with a '-' or '+', as in the --filter= flag. 209 # All entries here should start with a '-' or '+', as in the --filter= flag.
230 _DEFAULT_FILTERS = ['-build/include_alpha'] 210 _DEFAULT_FILTERS = ['-build/include_alpha']
231 211
232 # We used to check for high-bit characters, but after much discussion we 212 # We used to check for high-bit characters, but after much discussion we
233 # decided those were OK, as long as they were in UTF-8 and didn't represent 213 # decided those were OK, as long as they were in UTF-8 and didn't represent
234 # hard-coded international strings, which belong in a separate i18n file. 214 # hard-coded international strings, which belong in a separate i18n file.
235 215
236 # Headers that we consider STL headers. 216
237 _STL_HEADERS = frozenset([ 217 # C++ headers
238 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', 218 _CPP_HEADERS = frozenset([
239 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', 219 # Legacy
240 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'new', 220 'algobase.h',
241 'pair.h', 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack', 221 'algo.h',
242 'stl_alloc.h', 'stl_relops.h', 'type_traits.h', 222 'alloc.h',
243 'utility', 'vector', 'vector.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',
244 ]) 351 ])
245 352
246
247 # Non-STL C++ system headers.
248 _CPP_HEADERS = frozenset([
249 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
250 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
251 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
252 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
253 'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
254 'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
255 'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream',
256 'istream.h', 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
257 'numeric', 'ostream', 'ostream.h', 'parsestream.h', 'pfstream.h',
258 'PlotFile.h', 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h',
259 'ropeimpl.h', 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
260 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
261 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
262 ])
263
264
265 # Assertion macros. These are defined in base/logging.h and 353 # Assertion macros. These are defined in base/logging.h and
266 # testing/base/gunit.h. Note that the _M versions need to come first 354 # testing/base/gunit.h. Note that the _M versions need to come first
267 # for substring matching to work. 355 # for substring matching to work.
268 _CHECK_MACROS = [ 356 _CHECK_MACROS = [
269 'DCHECK', 'CHECK', 357 'DCHECK', 'CHECK',
270 'EXPECT_TRUE_M', 'EXPECT_TRUE', 358 'EXPECT_TRUE_M', 'EXPECT_TRUE',
271 'ASSERT_TRUE_M', 'ASSERT_TRUE', 359 'ASSERT_TRUE_M', 'ASSERT_TRUE',
272 'EXPECT_FALSE_M', 'EXPECT_FALSE', 360 'EXPECT_FALSE_M', 'EXPECT_FALSE',
273 'ASSERT_FALSE_M', 'ASSERT_FALSE', 361 'ASSERT_FALSE_M', 'ASSERT_FALSE',
274 ] 362 ]
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 'and_eq': '&=', 397 'and_eq': '&=',
310 'or_eq': '|=', 398 'or_eq': '|=',
311 'xor_eq': '^=', 399 'xor_eq': '^=',
312 'not': '!', 400 'not': '!',
313 'not_eq': '!=' 401 'not_eq': '!='
314 } 402 }
315 403
316 # Compile regular expression that matches all the above keywords. The "[ =()]" 404 # Compile regular expression that matches all the above keywords. The "[ =()]"
317 # bit is meant to avoid matching these keywords outside of boolean expressions. 405 # bit is meant to avoid matching these keywords outside of boolean expressions.
318 # 406 #
319 # False positives include C-style multi-line comments (http://go/nsiut ) 407 # False positives include C-style multi-line comments and multi-line strings
320 # and multi-line strings (http://go/beujw ), but those have always been 408 # but those have always been troublesome for cpplint.
321 # troublesome for cpplint.
322 _ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( 409 _ALT_TOKEN_REPLACEMENT_PATTERN = re.compile(
323 r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') 410 r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)')
324 411
325 412
326 # These constants define types of headers for use with 413 # These constants define types of headers for use with
327 # _IncludeState.CheckNextIncludeOrder(). 414 # _IncludeState.CheckNextIncludeOrder().
328 _C_SYS_HEADER = 1 415 _C_SYS_HEADER = 1
329 _CPP_SYS_HEADER = 2 416 _CPP_SYS_HEADER = 2
330 _LIKELY_MY_HEADER = 3 417 _LIKELY_MY_HEADER = 3
331 _POSSIBLE_MY_HEADER = 4 418 _POSSIBLE_MY_HEADER = 4
(...skipping 17 matching lines...) Expand all
349 _RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?') 436 _RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?')
350 437
351 # {str, set(int)}: a map from error categories to sets of linenumbers 438 # {str, set(int)}: a map from error categories to sets of linenumbers
352 # on which those errors are expected and should be suppressed. 439 # on which those errors are expected and should be suppressed.
353 _error_suppressions = {} 440 _error_suppressions = {}
354 441
355 # The root directory used for deriving header guard CPP variable. 442 # The root directory used for deriving header guard CPP variable.
356 # This is set by --root flag. 443 # This is set by --root flag.
357 _root = None 444 _root = None
358 445
446 # 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
359 def ParseNolintSuppressions(filename, raw_line, linenum, error): 454 def ParseNolintSuppressions(filename, raw_line, linenum, error):
360 """Updates the global list of error-suppressions. 455 """Updates the global list of error-suppressions.
361 456
362 Parses any NOLINT comments on the current line, updating the global 457 Parses any NOLINT comments on the current line, updating the global
363 error_suppressions store. Reports an error if the NOLINT comment 458 error_suppressions store. Reports an error if the NOLINT comment
364 was malformed. 459 was malformed.
365 460
366 Args: 461 Args:
367 filename: str, the name of the input file. 462 filename: str, the name of the input file.
368 raw_line: str, the line of input text, with comments. 463 raw_line: str, the line of input text, with comments.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 bool, True iff the error should be suppressed due to a NOLINT comment. 498 bool, True iff the error should be suppressed due to a NOLINT comment.
404 """ 499 """
405 return (linenum in _error_suppressions.get(category, set()) or 500 return (linenum in _error_suppressions.get(category, set()) or
406 linenum in _error_suppressions.get(None, set())) 501 linenum in _error_suppressions.get(None, set()))
407 502
408 def Match(pattern, s): 503 def Match(pattern, s):
409 """Matches the string with the pattern, caching the compiled regexp.""" 504 """Matches the string with the pattern, caching the compiled regexp."""
410 # The regexp compilation caching is inlined in both Match and Search for 505 # The regexp compilation caching is inlined in both Match and Search for
411 # performance reasons; factoring it out into a separate function turns out 506 # performance reasons; factoring it out into a separate function turns out
412 # to be noticeably expensive. 507 # to be noticeably expensive.
413 if not pattern in _regexp_compile_cache: 508 if pattern not in _regexp_compile_cache:
414 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 509 _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
415 return _regexp_compile_cache[pattern].match(s) 510 return _regexp_compile_cache[pattern].match(s)
416 511
417 512
513 def 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
418 def Search(pattern, s): 531 def Search(pattern, s):
419 """Searches the string for the pattern, caching the compiled regexp.""" 532 """Searches the string for the pattern, caching the compiled regexp."""
420 if not pattern in _regexp_compile_cache: 533 if pattern not in _regexp_compile_cache:
421 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 534 _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
422 return _regexp_compile_cache[pattern].search(s) 535 return _regexp_compile_cache[pattern].search(s)
423 536
424 537
425 class _IncludeState(dict): 538 class _IncludeState(dict):
426 """Tracks line numbers for includes, and the order in which includes appear. 539 """Tracks line numbers for includes, and the order in which includes appear.
427 540
428 As a dict, an _IncludeState object serves as a mapping between include 541 As a dict, an _IncludeState object serves as a mapping between include
429 filename and line number on which that file was included. 542 filename and line number on which that file was included.
430 543
(...skipping 20 matching lines...) Expand all
451 _SECTION_NAMES = { 564 _SECTION_NAMES = {
452 _INITIAL_SECTION: "... nothing. (This can't be an error.)", 565 _INITIAL_SECTION: "... nothing. (This can't be an error.)",
453 _MY_H_SECTION: 'a header this file implements', 566 _MY_H_SECTION: 'a header this file implements',
454 _C_SECTION: 'C system header', 567 _C_SECTION: 'C system header',
455 _CPP_SECTION: 'C++ system header', 568 _CPP_SECTION: 'C++ system header',
456 _OTHER_H_SECTION: 'other header', 569 _OTHER_H_SECTION: 'other header',
457 } 570 }
458 571
459 def __init__(self): 572 def __init__(self):
460 dict.__init__(self) 573 dict.__init__(self)
574 self.ResetSection()
575
576 def ResetSection(self):
461 # The name of the current section. 577 # The name of the current section.
462 self._section = self._INITIAL_SECTION 578 self._section = self._INITIAL_SECTION
463 # The path of last found header. 579 # The path of last found header.
464 self._last_header = '' 580 self._last_header = ''
465 581
582 def SetLastHeader(self, header_path):
583 self._last_header = header_path
584
466 def CanonicalizeAlphabeticalOrder(self, header_path): 585 def CanonicalizeAlphabeticalOrder(self, header_path):
467 """Returns a path canonicalized for alphabetical comparison. 586 """Returns a path canonicalized for alphabetical comparison.
468 587
469 - replaces "-" with "_" so they both cmp the same. 588 - replaces "-" with "_" so they both cmp the same.
470 - removes '-inl' since we don't require them to be after the main header. 589 - removes '-inl' since we don't require them to be after the main header.
471 - lowercase everything, just in case. 590 - lowercase everything, just in case.
472 591
473 Args: 592 Args:
474 header_path: Path to be canonicalized. 593 header_path: Path to be canonicalized.
475 594
476 Returns: 595 Returns:
477 Canonicalized path. 596 Canonicalized path.
478 """ 597 """
479 return header_path.replace('-inl.h', '.h').replace('-', '_').lower() 598 return header_path.replace('-inl.h', '.h').replace('-', '_').lower()
480 599
481 def IsInAlphabeticalOrder(self, header_path): 600 def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path):
482 """Check if a header is in alphabetical order with the previous header. 601 """Check if a header is in alphabetical order with the previous header.
483 602
484 Args: 603 Args:
485 header_path: Header to be checked. 604 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.
486 607
487 Returns: 608 Returns:
488 Returns true if the header is in alphabetical order. 609 Returns true if the header is in alphabetical order.
489 """ 610 """
490 canonical_header = self.CanonicalizeAlphabeticalOrder(header_path) 611 # If previous section is different from current section, _last_header will
491 if self._last_header > canonical_header: 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])):
492 return False 618 return False
493 self._last_header = canonical_header
494 return True 619 return True
495 620
496 def CheckNextIncludeOrder(self, header_type): 621 def CheckNextIncludeOrder(self, header_type):
497 """Returns a non-empty error message if the next header is out of order. 622 """Returns a non-empty error message if the next header is out of order.
498 623
499 This function also updates the internal state to be ready to check 624 This function also updates the internal state to be ready to check
500 the next include. 625 the next include.
501 626
502 Args: 627 Args:
503 header_type: One of the _XXX_HEADER constants defined above. 628 header_type: One of the _XXX_HEADER constants defined above.
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( 1001 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
877 filename, linenum, message, category, confidence)) 1002 filename, linenum, message, category, confidence))
878 elif _cpplint_state.output_format == 'eclipse': 1003 elif _cpplint_state.output_format == 'eclipse':
879 sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( 1004 sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
880 filename, linenum, message, category, confidence)) 1005 filename, linenum, message, category, confidence))
881 else: 1006 else:
882 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( 1007 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
883 filename, linenum, message, category, confidence)) 1008 filename, linenum, message, category, confidence))
884 1009
885 1010
886 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. 1011 # Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.
887 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( 1012 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
888 r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') 1013 r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
889 # Matches strings. Escape codes should already be removed by ESCAPES. 1014 # Matches strings. Escape codes should already be removed by ESCAPES.
890 _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"') 1015 _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
891 # Matches characters. Escape codes should already be removed by ESCAPES. 1016 # Matches characters. Escape codes should already be removed by ESCAPES.
892 _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'") 1017 _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
893 # Matches multi-line C++ comments. 1018 # Matches multi-line C++ comments.
894 # This RE is a little bit more complicated than one might expect, because we 1019 # This RE is a little bit more complicated than one might expect, because we
895 # have to take care of space removals tools so we can handle comments inside 1020 # have to take care of space removals tools so we can handle comments inside
896 # statements better. 1021 # statements better.
(...skipping 18 matching lines...) Expand all
915 1040
916 Returns: 1041 Returns:
917 True, if next character appended to 'line' is inside a 1042 True, if next character appended to 'line' is inside a
918 string constant. 1043 string constant.
919 """ 1044 """
920 1045
921 line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" 1046 line = line.replace(r'\\', 'XX') # after this, \\" does not match to \"
922 return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 1047 return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
923 1048
924 1049
1050 def 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
925 def FindNextMultiLineCommentStart(lines, lineix): 1111 def FindNextMultiLineCommentStart(lines, lineix):
926 """Find the beginning marker for a multiline comment.""" 1112 """Find the beginning marker for a multiline comment."""
927 while lineix < len(lines): 1113 while lineix < len(lines):
928 if lines[lineix].strip().startswith('/*'): 1114 if lines[lineix].strip().startswith('/*'):
929 # Only return this marker if the comment goes beyond this line 1115 # Only return this marker if the comment goes beyond this line
930 if lines[lineix].strip().find('*/', 2) < 0: 1116 if lines[lineix].strip().find('*/', 2) < 0:
931 return lineix 1117 return lineix
932 lineix += 1 1118 lineix += 1
933 return len(lines) 1119 return len(lines)
934 1120
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 2) lines member contains lines without comments, and 1175 2) lines member contains lines without comments, and
990 3) raw_lines member contains all the lines without processing. 1176 3) raw_lines member contains all the lines without processing.
991 All these three members are of <type 'list'>, and of the same length. 1177 All these three members are of <type 'list'>, and of the same length.
992 """ 1178 """
993 1179
994 def __init__(self, lines): 1180 def __init__(self, lines):
995 self.elided = [] 1181 self.elided = []
996 self.lines = [] 1182 self.lines = []
997 self.raw_lines = lines 1183 self.raw_lines = lines
998 self.num_lines = len(lines) 1184 self.num_lines = len(lines)
999 for linenum in range(len(lines)): 1185 self.lines_without_raw_strings = CleanseRawStrings(lines)
1000 self.lines.append(CleanseComments(lines[linenum])) 1186 for linenum in range(len(self.lines_without_raw_strings)):
1001 elided = self._CollapseStrings(lines[linenum]) 1187 self.lines.append(CleanseComments(
1188 self.lines_without_raw_strings[linenum]))
1189 elided = self._CollapseStrings(self.lines_without_raw_strings[linenum])
1002 self.elided.append(CleanseComments(elided)) 1190 self.elided.append(CleanseComments(elided))
1003 1191
1004 def NumLines(self): 1192 def NumLines(self):
1005 """Returns the number of lines represented.""" 1193 """Returns the number of lines represented."""
1006 return self.num_lines 1194 return self.num_lines
1007 1195
1008 @staticmethod 1196 @staticmethod
1009 def _CollapseStrings(elided): 1197 def _CollapseStrings(elided):
1010 """Collapses strings and chars on a line to simple "" or '' blocks. 1198 """Collapses strings and chars on a line to simple "" or '' blocks.
1011 1199
(...skipping 19 matching lines...) Expand all
1031 """Find the position just after the matching endchar. 1219 """Find the position just after the matching endchar.
1032 1220
1033 Args: 1221 Args:
1034 line: a CleansedLines line. 1222 line: a CleansedLines line.
1035 startpos: start searching at this position. 1223 startpos: start searching at this position.
1036 depth: nesting level at startpos. 1224 depth: nesting level at startpos.
1037 startchar: expression opening character. 1225 startchar: expression opening character.
1038 endchar: expression closing character. 1226 endchar: expression closing character.
1039 1227
1040 Returns: 1228 Returns:
1041 Index just after endchar. 1229 On finding matching endchar: (index just after matching endchar, 0)
1230 Otherwise: (-1, new depth at end of this line)
1042 """ 1231 """
1043 for i in xrange(startpos, len(line)): 1232 for i in xrange(startpos, len(line)):
1044 if line[i] == startchar: 1233 if line[i] == startchar:
1045 depth += 1 1234 depth += 1
1046 elif line[i] == endchar: 1235 elif line[i] == endchar:
1047 depth -= 1 1236 depth -= 1
1048 if depth == 0: 1237 if depth == 0:
1049 return i + 1 1238 return (i + 1, 0)
1050 return -1 1239 return (-1, depth)
1051 1240
1052 1241
1053 def CloseExpression(clean_lines, linenum, pos): 1242 def CloseExpression(clean_lines, linenum, pos):
1054 """If input points to ( or { or [, finds the position that closes it. 1243 """If input points to ( or { or [ or <, finds the position that closes it.
1055 1244
1056 If lines[linenum][pos] points to a '(' or '{' or '[', finds the 1245 If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the
1057 linenum/pos that correspond to the closing of the expression. 1246 linenum/pos that correspond to the closing of the expression.
1058 1247
1059 Args: 1248 Args:
1060 clean_lines: A CleansedLines instance containing the file. 1249 clean_lines: A CleansedLines instance containing the file.
1061 linenum: The number of the line to check. 1250 linenum: The number of the line to check.
1062 pos: A position on the line. 1251 pos: A position on the line.
1063 1252
1064 Returns: 1253 Returns:
1065 A tuple (line, linenum, pos) pointer *past* the closing brace, or 1254 A tuple (line, linenum, pos) pointer *past* the closing brace, or
1066 (line, len(lines), -1) if we never find a close. Note we ignore 1255 (line, len(lines), -1) if we never find a close. Note we ignore
1067 strings and comments when matching; and the line we return is the 1256 strings and comments when matching; and the line we return is the
1068 'cleansed' line at linenum. 1257 'cleansed' line at linenum.
1069 """ 1258 """
1070 1259
1071 line = clean_lines.elided[linenum] 1260 line = clean_lines.elided[linenum]
1072 startchar = line[pos] 1261 startchar = line[pos]
1073 if startchar not in '({[': 1262 if startchar not in '({[<':
1074 return (line, clean_lines.NumLines(), -1) 1263 return (line, clean_lines.NumLines(), -1)
1075 if startchar == '(': endchar = ')' 1264 if startchar == '(': endchar = ')'
1076 if startchar == '[': endchar = ']' 1265 if startchar == '[': endchar = ']'
1077 if startchar == '{': endchar = '}' 1266 if startchar == '{': endchar = '}'
1267 if startchar == '<': endchar = '>'
1078 1268
1079 # Check first line 1269 # Check first line
1080 end_pos = FindEndOfExpressionInLine(line, pos, 0, startchar, endchar) 1270 (end_pos, num_open) = FindEndOfExpressionInLine(
1271 line, pos, 0, startchar, endchar)
1081 if end_pos > -1: 1272 if end_pos > -1:
1082 return (line, linenum, end_pos) 1273 return (line, linenum, end_pos)
1083 tail = line[pos:] 1274
1084 num_open = tail.count(startchar) - tail.count(endchar) 1275 # Continue scanning forward
1085 while linenum < clean_lines.NumLines() - 1: 1276 while linenum < clean_lines.NumLines() - 1:
1086 linenum += 1 1277 linenum += 1
1087 line = clean_lines.elided[linenum] 1278 line = clean_lines.elided[linenum]
1088 delta = line.count(startchar) - line.count(endchar) 1279 (end_pos, num_open) = FindEndOfExpressionInLine(
1089 if num_open + delta <= 0: 1280 line, 0, num_open, startchar, endchar)
1090 return (line, linenum, 1281 if end_pos > -1:
1091 FindEndOfExpressionInLine(line, 0, num_open, startchar, endchar)) 1282 return (line, linenum, end_pos)
1092 num_open += delta
1093 1283
1094 # Did not find endchar before end of file, give up 1284 # Did not find endchar before end of file, give up
1095 return (line, clean_lines.NumLines(), -1) 1285 return (line, clean_lines.NumLines(), -1)
1096 1286
1287
1288 def 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
1315 def 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
1097 def CheckForCopyright(filename, lines, error): 1360 def CheckForCopyright(filename, lines, error):
1098 """Logs an error if no Copyright message appears at the top of the file.""" 1361 """Logs an error if no Copyright message appears at the top of the file."""
1099 1362
1100 # We'll say it should occur by line 10. Don't forget there's a 1363 # We'll say it should occur by line 10. Don't forget there's a
1101 # dummy line at the front. 1364 # dummy line at the front.
1102 for line in xrange(1, min(len(lines), 11)): 1365 for line in xrange(1, min(len(lines), 11)):
1103 if re.search(r'Copyright', lines[line], re.I): break 1366 if re.search(r'Copyright', lines[line], re.I): break
1104 else: # means no copyright line was found 1367 else: # means no copyright line was found
1105 error(filename, 0, 'legal/copyright', 5, 1368 error(filename, 0, 'legal/copyright', 5,
1106 'No copyright message found. ' 1369 'No copyright message found. '
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 error_level = 0 1462 error_level = 0
1200 if endif != ('#endif // %s' % (cppvar + '_')): 1463 if endif != ('#endif // %s' % (cppvar + '_')):
1201 error_level = 5 1464 error_level = 5
1202 1465
1203 ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, 1466 ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum,
1204 error) 1467 error)
1205 error(filename, endif_linenum, 'build/header_guard', error_level, 1468 error(filename, endif_linenum, 'build/header_guard', error_level,
1206 '#endif line should be "#endif // %s"' % cppvar) 1469 '#endif line should be "#endif // %s"' % cppvar)
1207 1470
1208 1471
1209 def CheckForUnicodeReplacementCharacters(filename, lines, error): 1472 def CheckForBadCharacters(filename, lines, error):
1210 """Logs an error for each line containing Unicode replacement characters. 1473 """Logs an error for each line containing bad characters.
1211 1474
1212 These indicate that either the file contained invalid UTF-8 (likely) 1475 Two kinds of bad characters:
1213 or Unicode replacement characters (which it shouldn't). Note that 1476
1214 it's possible for this to throw off line numbering if the invalid 1477 1. Unicode replacement characters: These indicate that either the file
1215 UTF-8 occurred adjacent to a newline. 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.
1216 1483
1217 Args: 1484 Args:
1218 filename: The name of the current file. 1485 filename: The name of the current file.
1219 lines: An array of strings, each representing a line of the file. 1486 lines: An array of strings, each representing a line of the file.
1220 error: The function to call with any errors found. 1487 error: The function to call with any errors found.
1221 """ 1488 """
1222 for linenum, line in enumerate(lines): 1489 for linenum, line in enumerate(lines):
1223 if u'\ufffd' in line: 1490 if u'\ufffd' in line:
1224 error(filename, linenum, 'readability/utf8', 5, 1491 error(filename, linenum, 'readability/utf8', 5,
1225 'Line contains invalid UTF-8 (or Unicode replacement character).') 1492 'Line contains invalid UTF-8 (or Unicode replacement character).')
1493 if '\0' in line:
1494 error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.')
1226 1495
1227 1496
1228 def CheckForNewlineAtEOF(filename, lines, error): 1497 def CheckForNewlineAtEOF(filename, lines, error):
1229 """Logs an error if there is no newline char at the end of the file. 1498 """Logs an error if there is no newline char at the end of the file.
1230 1499
1231 Args: 1500 Args:
1232 filename: The name of the current file. 1501 filename: The name of the current file.
1233 lines: An array of strings, each representing a line of the file. 1502 lines: An array of strings, each representing a line of the file.
1234 error: The function to call with any errors found. 1503 error: The function to call with any errors found.
1235 """ 1504 """
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 error(filename, linenum, 'readability/multiline_comment', 5, 1539 error(filename, linenum, 'readability/multiline_comment', 5,
1271 'Complex multi-line /*...*/-style comment found. ' 1540 'Complex multi-line /*...*/-style comment found. '
1272 'Lint may give bogus warnings. ' 1541 'Lint may give bogus warnings. '
1273 'Consider replacing these with //-style comments, ' 1542 'Consider replacing these with //-style comments, '
1274 'with #if 0...#endif, ' 1543 'with #if 0...#endif, '
1275 'or with more clearly structured multi-line comments.') 1544 'or with more clearly structured multi-line comments.')
1276 1545
1277 if (line.count('"') - line.count('\\"')) % 2: 1546 if (line.count('"') - line.count('\\"')) % 2:
1278 error(filename, linenum, 'readability/multiline_string', 5, 1547 error(filename, linenum, 'readability/multiline_string', 5,
1279 'Multi-line string ("...") found. This lint script doesn\'t ' 1548 'Multi-line string ("...") found. This lint script doesn\'t '
1280 'do well with such strings, and may give bogus warnings. They\'re ' 1549 'do well with such strings, and may give bogus warnings. '
1281 'ugly and unnecessary, and you should use concatenation instead".') 1550 'Use C++11 raw strings or concatenation instead.')
1282 1551
1283 1552
1284 threading_list = ( 1553 threading_list = (
1285 ('asctime(', 'asctime_r('), 1554 ('asctime(', 'asctime_r('),
1286 ('ctime(', 'ctime_r('), 1555 ('ctime(', 'ctime_r('),
1287 ('getgrgid(', 'getgrgid_r('), 1556 ('getgrgid(', 'getgrgid_r('),
1288 ('getgrnam(', 'getgrnam_r('), 1557 ('getgrnam(', 'getgrnam_r('),
1289 ('getlogin(', 'getlogin_r('), 1558 ('getlogin(', 'getlogin_r('),
1290 ('getpwnam(', 'getpwnam_r('), 1559 ('getpwnam(', 'getpwnam_r('),
1291 ('getpwuid(', 'getpwuid_r('), 1560 ('getpwuid(', 'getpwuid_r('),
1292 ('gmtime(', 'gmtime_r('), 1561 ('gmtime(', 'gmtime_r('),
1293 ('localtime(', 'localtime_r('), 1562 ('localtime(', 'localtime_r('),
1294 ('rand(', 'rand_r('), 1563 ('rand(', 'rand_r('),
1295 ('readdir(', 'readdir_r('),
1296 ('strtok(', 'strtok_r('), 1564 ('strtok(', 'strtok_r('),
1297 ('ttyname(', 'ttyname_r('), 1565 ('ttyname(', 'ttyname_r('),
1298 ) 1566 )
1299 1567
1300 1568
1301 def CheckPosixThreading(filename, clean_lines, linenum, error): 1569 def CheckPosixThreading(filename, clean_lines, linenum, error):
1302 """Checks for calls to thread-unsafe functions. 1570 """Checks for calls to thread-unsafe functions.
1303 1571
1304 Much code has been originally written without consideration of 1572 Much code has been originally written without consideration of
1305 multi-threading. Also, engineers are relying on their old experience; 1573 multi-threading. Also, engineers are relying on their old experience;
1306 they have learned posix before threading extensions were added. These 1574 they have learned posix before threading extensions were added. These
1307 tests guide the engineers to use thread-safe functions (when using 1575 tests guide the engineers to use thread-safe functions (when using
1308 posix directly). 1576 posix directly).
1309 1577
1310 Args: 1578 Args:
1311 filename: The name of the current file. 1579 filename: The name of the current file.
1312 clean_lines: A CleansedLines instance containing the file. 1580 clean_lines: A CleansedLines instance containing the file.
1313 linenum: The number of the line to check. 1581 linenum: The number of the line to check.
1314 error: The function to call with any errors found. 1582 error: The function to call with any errors found.
1315 """ 1583 """
1316 line = clean_lines.elided[linenum] 1584 line = clean_lines.elided[linenum]
1317 for single_thread_function, multithread_safe_function in threading_list: 1585 for single_thread_function, multithread_safe_function in threading_list:
1318 ix = line.find(single_thread_function) 1586 ix = line.find(single_thread_function)
1319 # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 1587 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-c omparison
1320 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and 1588 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
1321 line[ix - 1] not in ('_', '.', '>'))): 1589 line[ix - 1] not in ('_', '.', '>'))):
1322 error(filename, linenum, 'runtime/threadsafe_fn', 2, 1590 error(filename, linenum, 'runtime/threadsafe_fn', 2,
1323 'Consider using ' + multithread_safe_function + 1591 'Consider using ' + multithread_safe_function +
1324 '...) instead of ' + single_thread_function + 1592 '...) instead of ' + single_thread_function +
1325 '...) for improved thread safety.') 1593 '...) for improved thread safety.')
1326 1594
1327 1595
1596 def 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
1328 # Matches invalid increment: *count++, which moves pointer instead of 1615 # Matches invalid increment: *count++, which moves pointer instead of
1329 # incrementing a value. 1616 # incrementing a value.
1330 _RE_PATTERN_INVALID_INCREMENT = re.compile( 1617 _RE_PATTERN_INVALID_INCREMENT = re.compile(
1331 r'^\s*\*\w+(\+\+|--);') 1618 r'^\s*\*\w+(\+\+|--);')
1332 1619
1333 1620
1334 def CheckInvalidIncrement(filename, clean_lines, linenum, error): 1621 def CheckInvalidIncrement(filename, clean_lines, linenum, error):
1335 """Checks for invalid increment *count++. 1622 """Checks for invalid increment *count++.
1336 1623
1337 For example following function: 1624 For example following function:
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 class _ClassInfo(_BlockInfo): 1680 class _ClassInfo(_BlockInfo):
1394 """Stores information about a class.""" 1681 """Stores information about a class."""
1395 1682
1396 def __init__(self, name, class_or_struct, clean_lines, linenum): 1683 def __init__(self, name, class_or_struct, clean_lines, linenum):
1397 _BlockInfo.__init__(self, False) 1684 _BlockInfo.__init__(self, False)
1398 self.name = name 1685 self.name = name
1399 self.starting_linenum = linenum 1686 self.starting_linenum = linenum
1400 self.is_derived = False 1687 self.is_derived = False
1401 if class_or_struct == 'struct': 1688 if class_or_struct == 'struct':
1402 self.access = 'public' 1689 self.access = 'public'
1690 self.is_struct = True
1403 else: 1691 else:
1404 self.access = 'private' 1692 self.access = 'private'
1693 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
1405 1702
1406 # Try to find the end of the class. This will be confused by things like: 1703 # Try to find the end of the class. This will be confused by things like:
1407 # class A { 1704 # class A {
1408 # } *x = { ... 1705 # } *x = { ...
1409 # 1706 #
1410 # But it's still good enough for CheckSectionSpacing. 1707 # But it's still good enough for CheckSectionSpacing.
1411 self.last_line = 0 1708 self.last_line = 0
1412 depth = 0 1709 depth = 0
1413 for i in range(linenum, clean_lines.NumLines()): 1710 for i in range(linenum, clean_lines.NumLines()):
1414 line = clean_lines.elided[i] 1711 line = clean_lines.elided[i]
1415 depth += line.count('{') - line.count('}') 1712 depth += line.count('{') - line.count('}')
1416 if not depth: 1713 if not depth:
1417 self.last_line = i 1714 self.last_line = i
1418 break 1715 break
1419 1716
1420 def CheckBegin(self, filename, clean_lines, linenum, error): 1717 def CheckBegin(self, filename, clean_lines, linenum, error):
1421 # Look for a bare ':' 1718 # Look for a bare ':'
1422 if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): 1719 if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]):
1423 self.is_derived = True 1720 self.is_derived = True
1424 1721
1722 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
1425 1735
1426 class _NamespaceInfo(_BlockInfo): 1736 class _NamespaceInfo(_BlockInfo):
1427 """Stores information about a namespace.""" 1737 """Stores information about a namespace."""
1428 1738
1429 def __init__(self, name, linenum): 1739 def __init__(self, name, linenum):
1430 _BlockInfo.__init__(self, False) 1740 _BlockInfo.__init__(self, False)
1431 self.name = name or '' 1741 self.name = name or ''
1432 self.starting_linenum = linenum 1742 self.starting_linenum = linenum
1433 1743
1434 def CheckEnd(self, filename, clean_lines, linenum, error): 1744 def CheckEnd(self, filename, clean_lines, linenum, error):
(...skipping 12 matching lines...) Expand all
1447 # deciding what these nontrivial things are, so this check is 1757 # deciding what these nontrivial things are, so this check is
1448 # triggered by namespace size only, which works most of the time. 1758 # triggered by namespace size only, which works most of the time.
1449 if (linenum - self.starting_linenum < 10 1759 if (linenum - self.starting_linenum < 10
1450 and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)): 1760 and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)):
1451 return 1761 return
1452 1762
1453 # Look for matching comment at end of namespace. 1763 # Look for matching comment at end of namespace.
1454 # 1764 #
1455 # Note that we accept C style "/* */" comments for terminating 1765 # Note that we accept C style "/* */" comments for terminating
1456 # namespaces, so that code that terminate namespaces inside 1766 # namespaces, so that code that terminate namespaces inside
1457 # preprocessor macros can be cpplint clean. Example: http://go/nxpiz 1767 # preprocessor macros can be cpplint clean.
1458 # 1768 #
1459 # We also accept stuff like "// end of namespace <name>." with the 1769 # We also accept stuff like "// end of namespace <name>." with the
1460 # period at the end. 1770 # period at the end.
1461 # 1771 #
1462 # Besides these, we don't accept anything else, otherwise we might 1772 # Besides these, we don't accept anything else, otherwise we might
1463 # get false negatives when existing comment is a substring of the 1773 # get false negatives when existing comment is a substring of the
1464 # expected namespace. Example: http://go/ldkdc, http://cl/23548205 1774 # expected namespace.
1465 if self.name: 1775 if self.name:
1466 # Named namespace 1776 # Named namespace
1467 if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) + 1777 if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) +
1468 r'[\*/\.\\\s]*$'), 1778 r'[\*/\.\\\s]*$'),
1469 line): 1779 line):
1470 error(filename, linenum, 'readability/namespace', 5, 1780 error(filename, linenum, 'readability/namespace', 5,
1471 'Namespace should be terminated with "// namespace %s"' % 1781 'Namespace should be terminated with "// namespace %s"' %
1472 self.name) 1782 self.name)
1473 else: 1783 else:
1474 # Anonymous namespace 1784 # Anonymous namespace
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 1835
1526 def UpdatePreprocessor(self, line): 1836 def UpdatePreprocessor(self, line):
1527 """Update preprocessor stack. 1837 """Update preprocessor stack.
1528 1838
1529 We need to handle preprocessors due to classes like this: 1839 We need to handle preprocessors due to classes like this:
1530 #ifdef SWIG 1840 #ifdef SWIG
1531 struct ResultDetailsPageElementExtensionPoint { 1841 struct ResultDetailsPageElementExtensionPoint {
1532 #else 1842 #else
1533 struct ResultDetailsPageElementExtensionPoint : public Extension { 1843 struct ResultDetailsPageElementExtensionPoint : public Extension {
1534 #endif 1844 #endif
1535 (see http://go/qwddn for original example)
1536 1845
1537 We make the following assumptions (good enough for most files): 1846 We make the following assumptions (good enough for most files):
1538 - Preprocessor condition evaluates to true from #if up to first 1847 - Preprocessor condition evaluates to true from #if up to first
1539 #else/#elif/#endif. 1848 #else/#elif/#endif.
1540 1849
1541 - Preprocessor condition evaluates to false from #else/#elif up 1850 - Preprocessor condition evaluates to false from #else/#elif up
1542 to #endif. We still perform lint checks on these lines, but 1851 to #endif. We still perform lint checks on these lines, but
1543 these do not affect nesting stack. 1852 these do not affect nesting stack.
1544 1853
1545 Args: 1854 Args:
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 # time it saw "class Comparator", it may think that it's a new class. 1962 # time it saw "class Comparator", it may think that it's a new class.
1654 # Nested templates have a similar problem: 1963 # Nested templates have a similar problem:
1655 # template < 1964 # template <
1656 # typename ExportedType, 1965 # typename ExportedType,
1657 # typename TupleType, 1966 # typename TupleType,
1658 # template <typename, typename> class ImplTemplate> 1967 # template <typename, typename> class ImplTemplate>
1659 # 1968 #
1660 # To avoid these cases, we ignore classes that are followed by '=' or '>' 1969 # To avoid these cases, we ignore classes that are followed by '=' or '>'
1661 class_decl_match = Match( 1970 class_decl_match = Match(
1662 r'\s*(template\s*<[\w\s<>,:]*>\s*)?' 1971 r'\s*(template\s*<[\w\s<>,:]*>\s*)?'
1663 '(class|struct)\s+([A-Z_]+\s+)*(\w+(?:::\w+)*)' 1972 r'(class|struct)\s+([A-Z_]+\s+)*(\w+(?:::\w+)*)'
1664 '(([^=>]|<[^<>]*>)*)$', line) 1973 r'(([^=>]|<[^<>]*>|<[^<>]*<[^<>]*>\s*>)*)$', line)
1665 if (class_decl_match and 1974 if (class_decl_match and
1666 (not self.stack or self.stack[-1].open_parentheses == 0)): 1975 (not self.stack or self.stack[-1].open_parentheses == 0)):
1667 self.stack.append(_ClassInfo( 1976 self.stack.append(_ClassInfo(
1668 class_decl_match.group(4), class_decl_match.group(2), 1977 class_decl_match.group(4), class_decl_match.group(2),
1669 clean_lines, linenum)) 1978 clean_lines, linenum))
1670 line = class_decl_match.group(5) 1979 line = class_decl_match.group(5)
1671 1980
1672 # If we have not yet seen the opening brace for the innermost block, 1981 # If we have not yet seen the opening brace for the innermost block,
1673 # run checks here. 1982 # run checks here.
1674 if not self.SeenOpenBrace(): 1983 if not self.SeenOpenBrace():
1675 self.stack[-1].CheckBegin(filename, clean_lines, linenum, error) 1984 self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)
1676 1985
1677 # Update access control if we are inside a class/struct 1986 # Update access control if we are inside a class/struct
1678 if self.stack and isinstance(self.stack[-1], _ClassInfo): 1987 if self.stack and isinstance(self.stack[-1], _ClassInfo):
1679 access_match = Match(r'\s*(public|private|protected)\s*:', line) 1988 classinfo = self.stack[-1]
1989 access_match = Match(
1990 r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?'
1991 r':(?:[^:]|$)',
1992 line)
1680 if access_match: 1993 if access_match:
1681 self.stack[-1].access = access_match.group(1) 1994 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))
1682 2011
1683 # Consume braces or semicolons from what's left of the line 2012 # Consume braces or semicolons from what's left of the line
1684 while True: 2013 while True:
1685 # Match first brace, semicolon, or closed parenthesis. 2014 # Match first brace, semicolon, or closed parenthesis.
1686 matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line) 2015 matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line)
1687 if not matched: 2016 if not matched:
1688 break 2017 break
1689 2018
1690 token = matched.group(1) 2019 token = matched.group(1)
1691 if token == '{': 2020 if token == '{':
(...skipping 29 matching lines...) Expand all
1721 2050
1722 Returns: 2051 Returns:
1723 A _ClassInfo object if we are inside a class, or None otherwise. 2052 A _ClassInfo object if we are inside a class, or None otherwise.
1724 """ 2053 """
1725 for i in range(len(self.stack), 0, -1): 2054 for i in range(len(self.stack), 0, -1):
1726 classinfo = self.stack[i - 1] 2055 classinfo = self.stack[i - 1]
1727 if isinstance(classinfo, _ClassInfo): 2056 if isinstance(classinfo, _ClassInfo):
1728 return classinfo 2057 return classinfo
1729 return None 2058 return None
1730 2059
1731 def CheckClassFinished(self, filename, error): 2060 def CheckCompletedBlocks(self, filename, error):
1732 """Checks that all classes have been completely parsed. 2061 """Checks that all classes and namespaces have been completely parsed.
1733 2062
1734 Call this when all lines in a file have been processed. 2063 Call this when all lines in a file have been processed.
1735 Args: 2064 Args:
1736 filename: The name of the current file. 2065 filename: The name of the current file.
1737 error: The function to call with any errors found. 2066 error: The function to call with any errors found.
1738 """ 2067 """
1739 # Note: This test can result in false positives if #ifdef constructs 2068 # Note: This test can result in false positives if #ifdef constructs
1740 # get in the way of brace matching. See the testBuildClass test in 2069 # get in the way of brace matching. See the testBuildClass test in
1741 # cpplint_unittest.py for an example of this. 2070 # cpplint_unittest.py for an example of this.
1742 for obj in self.stack: 2071 for obj in self.stack:
1743 if isinstance(obj, _ClassInfo): 2072 if isinstance(obj, _ClassInfo):
1744 error(filename, obj.starting_linenum, 'build/class', 5, 2073 error(filename, obj.starting_linenum, 'build/class', 5,
1745 'Failed to find complete declaration of class %s' % 2074 'Failed to find complete declaration of class %s' %
1746 obj.name) 2075 obj.name)
2076 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)
1747 2080
1748 2081
1749 def CheckForNonStandardConstructs(filename, clean_lines, linenum, 2082 def CheckForNonStandardConstructs(filename, clean_lines, linenum,
1750 nesting_state, error): 2083 nesting_state, error):
1751 """Logs an error if we see certain non-ANSI constructs ignored by gcc-2. 2084 r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
1752 2085
1753 Complain about several constructs which gcc-2 accepts, but which are 2086 Complain about several constructs which gcc-2 accepts, but which are
1754 not standard C++. Warning about these in lint is one way to ease the 2087 not standard C++. Warning about these in lint is one way to ease the
1755 transition to new compilers. 2088 transition to new compilers.
1756 - put storage class first (e.g. "static const" instead of "const static"). 2089 - put storage class first (e.g. "static const" instead of "const static").
1757 - "%lld" instead of %qd" in printf-type functions. 2090 - "%lld" instead of %qd" in printf-type functions.
1758 - "%1$d" is non-standard in printf-type functions. 2091 - "%1$d" is non-standard in printf-type functions.
1759 - "\%" is an undefined character escape sequence. 2092 - "\%" is an undefined character escape sequence.
1760 - text after #endif is not allowed. 2093 - text after #endif is not allowed.
1761 - invalid inner-style forward declaration. 2094 - invalid inner-style forward declaration.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 # The constructor and destructor will not have those qualifiers. 2173 # The constructor and destructor will not have those qualifiers.
1841 base_classname = classinfo.name.split('::')[-1] 2174 base_classname = classinfo.name.split('::')[-1]
1842 2175
1843 # Look for single-argument constructors that aren't marked explicit. 2176 # Look for single-argument constructors that aren't marked explicit.
1844 # Technically a valid construct, but against style. 2177 # Technically a valid construct, but against style.
1845 args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)' 2178 args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)'
1846 % re.escape(base_classname), 2179 % re.escape(base_classname),
1847 line) 2180 line)
1848 if (args and 2181 if (args and
1849 args.group(1) != 'void' and 2182 args.group(1) != 'void' and
1850 not Match(r'(const\s+)?%s\s*(?:<\w+>\s*)?&' % re.escape(base_classname), 2183 not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&'
1851 args.group(1).strip())): 2184 % re.escape(base_classname), args.group(1).strip())):
1852 error(filename, linenum, 'runtime/explicit', 5, 2185 error(filename, linenum, 'runtime/explicit', 5,
1853 'Single-argument constructors should be marked explicit.') 2186 'Single-argument constructors should be marked explicit.')
1854 2187
1855 2188
1856 def CheckSpacingForFunctionCall(filename, line, linenum, error): 2189 def CheckSpacingForFunctionCall(filename, line, linenum, error):
1857 """Checks for the correctness of various spacing around function calls. 2190 """Checks for the correctness of various spacing around function calls.
1858 2191
1859 Args: 2192 Args:
1860 filename: The name of the current file. 2193 filename: The name of the current file.
1861 line: The text of the line to check. 2194 line: The text of the line to check.
(...skipping 22 matching lines...) Expand all
1884 # function argument when the char before the whitespace is legal in 2217 # function argument when the char before the whitespace is legal in
1885 # a function name (alnum + _) and we're not starting a macro. Also ignore 2218 # a function name (alnum + _) and we're not starting a macro. Also ignore
1886 # pointers and references to arrays and functions coz they're too tricky: 2219 # pointers and references to arrays and functions coz they're too tricky:
1887 # we use a very simple way to recognize these: 2220 # we use a very simple way to recognize these:
1888 # " (something)(maybe-something)" or 2221 # " (something)(maybe-something)" or
1889 # " (something)(maybe-something," or 2222 # " (something)(maybe-something," or
1890 # " (something)[something]" 2223 # " (something)[something]"
1891 # Note that we assume the contents of [] to be short enough that 2224 # Note that we assume the contents of [] to be short enough that
1892 # they'll never need to wrap. 2225 # they'll never need to wrap.
1893 if ( # Ignore control structures. 2226 if ( # Ignore control structures.
1894 not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and 2227 not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b',
2228 fncall) and
1895 # Ignore pointers/references to functions. 2229 # Ignore pointers/references to functions.
1896 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and 2230 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
1897 # Ignore pointers/references to arrays. 2231 # Ignore pointers/references to arrays.
1898 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): 2232 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
1899 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call 2233 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
1900 error(filename, linenum, 'whitespace/parens', 4, 2234 error(filename, linenum, 'whitespace/parens', 4,
1901 'Extra space after ( in function call') 2235 'Extra space after ( in function call')
1902 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): 2236 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
1903 error(filename, linenum, 'whitespace/parens', 2, 2237 error(filename, linenum, 'whitespace/parens', 2,
1904 'Extra space after (') 2238 'Extra space after (')
1905 if (Search(r'\w\s+\(', fncall) and 2239 if (Search(r'\w\s+\(', fncall) and
1906 not Search(r'#\s*define|typedef', fncall) and 2240 not Search(r'#\s*define|typedef', fncall) and
1907 not Search(r'\w\s+\((\w+::)?\*\w+\)\(', fncall)): 2241 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)):
1908 error(filename, linenum, 'whitespace/parens', 4, 2242 error(filename, linenum, 'whitespace/parens', 4,
1909 'Extra space before ( in function call') 2243 'Extra space before ( in function call')
1910 # If the ) is followed only by a newline or a { + newline, assume it's 2244 # If the ) is followed only by a newline or a { + newline, assume it's
1911 # part of a control statement (if/while/etc), and don't complain 2245 # part of a control statement (if/while/etc), and don't complain
1912 if Search(r'[^)]\s+\)\s*[^{\s]', fncall): 2246 if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
1913 # If the closing parenthesis is preceded by only whitespaces, 2247 # If the closing parenthesis is preceded by only whitespaces,
1914 # try to give a more descriptive error message. 2248 # try to give a more descriptive error message.
1915 if Search(r'^\s+\)', fncall): 2249 if Search(r'^\s+\)', fncall):
1916 error(filename, linenum, 'whitespace/parens', 2, 2250 error(filename, linenum, 'whitespace/parens', 2,
1917 'Closing ) should be moved to the previous line') 2251 'Closing ) should be moved to the previous line')
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2025 error(filename, linenum, 'whitespace/todo', 2, 2359 error(filename, linenum, 'whitespace/todo', 2,
2026 'Too many spaces before TODO') 2360 'Too many spaces before TODO')
2027 2361
2028 username = match.group(2) 2362 username = match.group(2)
2029 if not username: 2363 if not username:
2030 error(filename, linenum, 'readability/todo', 2, 2364 error(filename, linenum, 'readability/todo', 2,
2031 'Missing username in TODO; it should look like ' 2365 'Missing username in TODO; it should look like '
2032 '"// TODO(my_username): Stuff."') 2366 '"// TODO(my_username): Stuff."')
2033 2367
2034 middle_whitespace = match.group(3) 2368 middle_whitespace = match.group(3)
2035 # Comparisons made explicit for correctness -- pylint: disable-msg=C6403 2369 # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bo ol-comparison
2036 if middle_whitespace != ' ' and middle_whitespace != '': 2370 if middle_whitespace != ' ' and middle_whitespace != '':
2037 error(filename, linenum, 'whitespace/todo', 2, 2371 error(filename, linenum, 'whitespace/todo', 2,
2038 'TODO(my_username) should be followed by a space') 2372 'TODO(my_username) should be followed by a space')
2039 2373
2040 def CheckAccess(filename, clean_lines, linenum, nesting_state, error): 2374 def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
2041 """Checks for improper use of DISALLOW* macros. 2375 """Checks for improper use of DISALLOW* macros.
2042 2376
2043 Args: 2377 Args:
2044 filename: The name of the current file. 2378 filename: The name of the current file.
2045 clean_lines: A CleansedLines instance containing the file. 2379 clean_lines: A CleansedLines instance containing the file.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 line = init_suffix 2416 line = init_suffix
2083 nesting_stack = ['<'] 2417 nesting_stack = ['<']
2084 while True: 2418 while True:
2085 # Find the next operator that can tell us whether < is used as an 2419 # Find the next operator that can tell us whether < is used as an
2086 # opening bracket or as a less-than operator. We only want to 2420 # opening bracket or as a less-than operator. We only want to
2087 # warn on the latter case. 2421 # warn on the latter case.
2088 # 2422 #
2089 # We could also check all other operators and terminate the search 2423 # We could also check all other operators and terminate the search
2090 # early, e.g. if we got something like this "a<b+c", the "<" is 2424 # early, e.g. if we got something like this "a<b+c", the "<" is
2091 # most likely a less-than operator, but then we will get false 2425 # most likely a less-than operator, but then we will get false
2092 # positives for default arguments (e.g. http://go/prccd) and 2426 # positives for default arguments and other template expressions.
2093 # other template expressions (e.g. http://go/oxcjq).
2094 match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line) 2427 match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line)
2095 if match: 2428 if match:
2096 # Found an operator, update nesting stack 2429 # Found an operator, update nesting stack
2097 operator = match.group(1) 2430 operator = match.group(1)
2098 line = match.group(2) 2431 line = match.group(2)
2099 2432
2100 if nesting_stack[-1] == '<': 2433 if nesting_stack[-1] == '<':
2101 # Expecting closing angle bracket 2434 # Expecting closing angle bracket
2102 if operator in ('<', '(', '['): 2435 if operator in ('<', '(', '['):
2103 nesting_stack.append(operator) 2436 nesting_stack.append(operator)
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 2539
2207 Args: 2540 Args:
2208 filename: The name of the current file. 2541 filename: The name of the current file.
2209 clean_lines: A CleansedLines instance containing the file. 2542 clean_lines: A CleansedLines instance containing the file.
2210 linenum: The number of the line to check. 2543 linenum: The number of the line to check.
2211 nesting_state: A _NestingState instance which maintains information about 2544 nesting_state: A _NestingState instance which maintains information about
2212 the current stack of nested blocks being parsed. 2545 the current stack of nested blocks being parsed.
2213 error: The function to call with any errors found. 2546 error: The function to call with any errors found.
2214 """ 2547 """
2215 2548
2216 raw = clean_lines.raw_lines 2549 # 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
2217 line = raw[linenum] 2553 line = raw[linenum]
2218 2554
2219 # Before nixing comments, check if the line is blank for no good 2555 # Before nixing comments, check if the line is blank for no good
2220 # reason. This includes the first line after a block is opened, and 2556 # reason. This includes the first line after a block is opened, and
2221 # blank lines at the end of a function (ie, right before a line like '}' 2557 # blank lines at the end of a function (ie, right before a line like '}'
2222 # 2558 #
2223 # Skip all the blank line checks if we are immediately inside a 2559 # Skip all the blank line checks if we are immediately inside a
2224 # namespace body. In other words, don't issue blank line warnings 2560 # namespace body. In other words, don't issue blank line warnings
2225 # for this block: 2561 # for this block:
2226 # namespace { 2562 # namespace {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 # closing paren, without the opening paren, followed by an opening brace 2596 # closing paren, without the opening paren, followed by an opening brace
2261 # or colon (for initializer lists) we assume that it is the last line of 2597 # or colon (for initializer lists) we assume that it is the last line of
2262 # a function header. If we have a colon indented 4 spaces, it is an 2598 # a function header. If we have a colon indented 4 spaces, it is an
2263 # initializer list. 2599 # initializer list.
2264 exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', 2600 exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
2265 prev_line) 2601 prev_line)
2266 or Match(r' {4}:', prev_line)) 2602 or Match(r' {4}:', prev_line))
2267 2603
2268 if not exception: 2604 if not exception:
2269 error(filename, linenum, 'whitespace/blank_line', 2, 2605 error(filename, linenum, 'whitespace/blank_line', 2,
2270 'Blank line at the start of a code block. Is this needed?') 2606 'Redundant blank line at the start of a code block '
2607 'should be deleted.')
2271 # Ignore blank lines at the end of a block in a long if-else 2608 # Ignore blank lines at the end of a block in a long if-else
2272 # chain, like this: 2609 # chain, like this:
2273 # if (condition1) { 2610 # if (condition1) {
2274 # // Something followed by a blank line 2611 # // Something followed by a blank line
2275 # 2612 #
2276 # } else if (condition2) { 2613 # } else if (condition2) {
2277 # // Something else 2614 # // Something else
2278 # } 2615 # }
2279 if linenum + 1 < clean_lines.NumLines(): 2616 if linenum + 1 < clean_lines.NumLines():
2280 next_line = raw[linenum + 1] 2617 next_line = raw[linenum + 1]
2281 if (next_line 2618 if (next_line
2282 and Match(r'\s*}', next_line) 2619 and Match(r'\s*}', next_line)
2283 and next_line.find('} else ') == -1): 2620 and next_line.find('} else ') == -1):
2284 error(filename, linenum, 'whitespace/blank_line', 3, 2621 error(filename, linenum, 'whitespace/blank_line', 3,
2285 'Blank line at the end of a code block. Is this needed?') 2622 'Redundant blank line at the end of a code block '
2623 'should be deleted.')
2286 2624
2287 matched = Match(r'\s*(public|protected|private):', prev_line) 2625 matched = Match(r'\s*(public|protected|private):', prev_line)
2288 if matched: 2626 if matched:
2289 error(filename, linenum, 'whitespace/blank_line', 3, 2627 error(filename, linenum, 'whitespace/blank_line', 3,
2290 'Do not leave a blank line after "%s:"' % matched.group(1)) 2628 'Do not leave a blank line after "%s:"' % matched.group(1))
2291 2629
2292 # Next, we complain if there's a comment too near the text 2630 # Next, we complain if there's a comment too near the text
2293 commentpos = line.find('//') 2631 commentpos = line.find('//')
2294 if commentpos != -1: 2632 if commentpos != -1:
2295 # Check if the // may be in quotes. If so, ignore it 2633 # Check if the // may be in quotes. If so, ignore it
2296 # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 2634 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-c omparison
2297 if (line.count('"', 0, commentpos) - 2635 if (line.count('"', 0, commentpos) -
2298 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes 2636 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
2299 # Allow one space for new scopes, two spaces otherwise: 2637 # Allow one space for new scopes, two spaces otherwise:
2300 if (not Match(r'^\s*{ //', line) and 2638 if (not Match(r'^\s*{ //', line) and
2301 ((commentpos >= 1 and 2639 ((commentpos >= 1 and
2302 line[commentpos-1] not in string.whitespace) or 2640 line[commentpos-1] not in string.whitespace) or
2303 (commentpos >= 2 and 2641 (commentpos >= 2 and
2304 line[commentpos-2] not in string.whitespace))): 2642 line[commentpos-2] not in string.whitespace))):
2305 error(filename, linenum, 'whitespace/comments', 2, 2643 error(filename, linenum, 'whitespace/comments', 2,
2306 'At least two spaces is best between code and comments') 2644 'At least two spaces is best between code and comments')
2307 # There should always be a space between the // and the comment 2645 # There should always be a space between the // and the comment
2308 commentend = commentpos + 2 2646 commentend = commentpos + 2
2309 if commentend < len(line) and not line[commentend] == ' ': 2647 if commentend < len(line) and not line[commentend] == ' ':
2310 # but some lines are exceptions -- e.g. if they're big 2648 # but some lines are exceptions -- e.g. if they're big
2311 # comment delimiters like: 2649 # comment delimiters like:
2312 # //---------------------------------------------------------- 2650 # //----------------------------------------------------------
2313 # or are an empty C++ style Doxygen comment, like: 2651 # or are an empty C++ style Doxygen comment, like:
2314 # /// 2652 # ///
2653 # or C++ style Doxygen comments placed after the variable:
2654 # ///< Header comment
2655 # //!< Header comment
2315 # or they begin with multiple slashes followed by a space: 2656 # or they begin with multiple slashes followed by a space:
2316 # //////// Header comment 2657 # //////// Header comment
2317 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or 2658 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
2318 Search(r'^/$', line[commentend:]) or 2659 Search(r'^/$', line[commentend:]) or
2660 Search(r'^!< ', line[commentend:]) or
2661 Search(r'^/< ', line[commentend:]) or
2319 Search(r'^/+ ', line[commentend:])) 2662 Search(r'^/+ ', line[commentend:]))
2320 if not match: 2663 if not match:
2321 error(filename, linenum, 'whitespace/comments', 4, 2664 error(filename, linenum, 'whitespace/comments', 4,
2322 'Should have a space between // and comment') 2665 'Should have a space between // and comment')
2323 CheckComment(line[commentpos:], filename, linenum, error) 2666 CheckComment(line[commentpos:], filename, linenum, error)
2324 2667
2325 line = clean_lines.elided[linenum] # get rid of comments and strings 2668 line = clean_lines.elided[linenum] # get rid of comments and strings
2326 2669
2327 # Don't try to do spacing checks for operator methods 2670 # Don't try to do spacing checks for operator methods
2328 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) 2671 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
(...skipping 13 matching lines...) Expand all
2342 # You should always have whitespace around binary operators. 2685 # You should always have whitespace around binary operators.
2343 # 2686 #
2344 # Check <= and >= first to avoid false positives with < and >, then 2687 # Check <= and >= first to avoid false positives with < and >, then
2345 # check non-include lines for spacing around < and >. 2688 # check non-include lines for spacing around < and >.
2346 match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line) 2689 match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
2347 if match: 2690 if match:
2348 error(filename, linenum, 'whitespace/operators', 3, 2691 error(filename, linenum, 'whitespace/operators', 3,
2349 'Missing spaces around %s' % match.group(1)) 2692 'Missing spaces around %s' % match.group(1))
2350 # We allow no-spaces around << when used like this: 10<<20, but 2693 # We allow no-spaces around << when used like this: 10<<20, but
2351 # not otherwise (particularly, not when used as streams) 2694 # not otherwise (particularly, not when used as streams)
2352 match = Search(r'(\S)(?:L|UL|ULL|l|ul|ull)?<<(\S)', line) 2695 # Also ignore using ns::operator<<;
2353 if match and not (match.group(1).isdigit() and match.group(2).isdigit()): 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) == ';')):
2354 error(filename, linenum, 'whitespace/operators', 3, 2700 error(filename, linenum, 'whitespace/operators', 3,
2355 'Missing spaces around <<') 2701 'Missing spaces around <<')
2356 elif not Match(r'#.*include', line): 2702 elif not Match(r'#.*include', line):
2357 # Avoid false positives on -> 2703 # Avoid false positives on ->
2358 reduced_line = line.replace('->', '') 2704 reduced_line = line.replace('->', '')
2359 2705
2360 # Look for < that is not surrounded by spaces. This is only 2706 # Look for < that is not surrounded by spaces. This is only
2361 # triggered if both sides are missing spaces, even though 2707 # triggered if both sides are missing spaces, even though
2362 # technically should should flag if at least one side is missing a 2708 # technically should should flag if at least one side is missing a
2363 # space. This is done to avoid some false positives with shifts. 2709 # space. This is done to avoid some false positives with shifts.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2414 match = Search(r'\b(if|for|while|switch)\s*' 2760 match = Search(r'\b(if|for|while|switch)\s*'
2415 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', 2761 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
2416 line) 2762 line)
2417 if match: 2763 if match:
2418 if len(match.group(2)) != len(match.group(4)): 2764 if len(match.group(2)) != len(match.group(4)):
2419 if not (match.group(3) == ';' and 2765 if not (match.group(3) == ';' and
2420 len(match.group(2)) == 1 + len(match.group(4)) or 2766 len(match.group(2)) == 1 + len(match.group(4)) or
2421 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): 2767 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
2422 error(filename, linenum, 'whitespace/parens', 5, 2768 error(filename, linenum, 'whitespace/parens', 5,
2423 'Mismatching spaces inside () in %s' % match.group(1)) 2769 'Mismatching spaces inside () in %s' % match.group(1))
2424 if not len(match.group(2)) in [0, 1]: 2770 if len(match.group(2)) not in [0, 1]:
2425 error(filename, linenum, 'whitespace/parens', 5, 2771 error(filename, linenum, 'whitespace/parens', 5,
2426 'Should have zero or one spaces inside ( and ) in %s' % 2772 'Should have zero or one spaces inside ( and ) in %s' %
2427 match.group(1)) 2773 match.group(1))
2428 2774
2429 # You should always have a space after a comma (either as fn arg or operator) 2775 # You should always have a space after a comma (either as fn arg or operator)
2430 if Search(r',[^\s]', line): 2776 #
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]):
2431 error(filename, linenum, 'whitespace/comma', 3, 2786 error(filename, linenum, 'whitespace/comma', 3,
2432 'Missing space after ,') 2787 'Missing space after ,')
2433 2788
2434 # You should always have a space after a semicolon 2789 # You should always have a space after a semicolon
2435 # except for few corner cases 2790 # except for few corner cases
2436 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more 2791 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more
2437 # space after ; 2792 # space after ;
2438 if Search(r';[^\s};\\)/]', line): 2793 if Search(r';[^\s};\\)/]', line):
2439 error(filename, linenum, 'whitespace/semicolon', 3, 2794 error(filename, linenum, 'whitespace/semicolon', 3,
2440 'Missing space after ;') 2795 'Missing space after ;')
2441 2796
2442 # Next we will look for issues with function calls. 2797 # Next we will look for issues with function calls.
2443 CheckSpacingForFunctionCall(filename, line, linenum, error) 2798 CheckSpacingForFunctionCall(filename, line, linenum, error)
2444 2799
2445 # Except after an opening paren, or after another opening brace (in case of 2800 # Except after an opening paren, or after another opening brace (in case of
2446 # an initializer list, for instance), you should have spaces before your 2801 # an initializer list, for instance), you should have spaces before your
2447 # braces. And since you should never have braces at the beginning of a line, 2802 # braces. And since you should never have braces at the beginning of a line,
2448 # this is an easy test. 2803 # this is an easy test.
2449 if Search(r'[^ ({]{', line): 2804 match = Match(r'^(.*[^ ({]){', line)
2450 error(filename, linenum, 'whitespace/braces', 5, 2805 if match:
2451 'Missing space before {') 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 {')
2452 2843
2453 # Make sure '} else {' has spaces. 2844 # Make sure '} else {' has spaces.
2454 if Search(r'}else', line): 2845 if Search(r'}else', line):
2455 error(filename, linenum, 'whitespace/braces', 5, 2846 error(filename, linenum, 'whitespace/braces', 5,
2456 'Missing space before else') 2847 'Missing space before else')
2457 2848
2458 # You shouldn't have spaces before your brackets, except maybe after 2849 # You shouldn't have spaces before your brackets, except maybe after
2459 # 'delete []' or 'new char * []'. 2850 # 'delete []' or 'new char * []'.
2460 if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line): 2851 if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
2461 error(filename, linenum, 'whitespace/braces', 5, 2852 error(filename, linenum, 'whitespace/braces', 5,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2569 Args: 2960 Args:
2570 filename: The name of the current file. 2961 filename: The name of the current file.
2571 clean_lines: A CleansedLines instance containing the file. 2962 clean_lines: A CleansedLines instance containing the file.
2572 linenum: The number of the line to check. 2963 linenum: The number of the line to check.
2573 error: The function to call with any errors found. 2964 error: The function to call with any errors found.
2574 """ 2965 """
2575 2966
2576 line = clean_lines.elided[linenum] # get rid of comments and strings 2967 line = clean_lines.elided[linenum] # get rid of comments and strings
2577 2968
2578 if Match(r'\s*{\s*$', line): 2969 if Match(r'\s*{\s*$', line):
2579 # We allow an open brace to start a line in the case where someone 2970 # We allow an open brace to start a line in the case where someone is using
2580 # is using braces in a block to explicitly create a new scope, 2971 # braces in a block to explicitly create a new scope, which is commonly used
2581 # which is commonly used to control the lifetime of 2972 # to control the lifetime of stack-allocated variables. Braces are also
2582 # stack-allocated variables. We don't detect this perfectly: we 2973 # used for brace initializers inside function calls. We don't detect this
2583 # just don't complain if the last non-whitespace character on the 2974 # perfectly: we just don't complain if the last non-whitespace character on
2584 # previous non-blank line is ';', ':', '{', or '}', or if the previous 2975 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the
2585 # line starts a preprocessor block. 2976 # previous line starts a preprocessor block.
2586 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 2977 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
2587 if (not Search(r'[;:}{]\s*$', prevline) and 2978 if (not Search(r'[,;:}{(]\s*$', prevline) and
2588 not Match(r'\s*#', prevline)): 2979 not Match(r'\s*#', prevline)):
2589 error(filename, linenum, 'whitespace/braces', 4, 2980 error(filename, linenum, 'whitespace/braces', 4,
2590 '{ should almost always be at the end of the previous line') 2981 '{ should almost always be at the end of the previous line')
2591 2982
2592 # An else clause should be on the same line as the preceding closing brace. 2983 # An else clause should be on the same line as the preceding closing brace.
2593 if Match(r'\s*else\s*', line): 2984 if Match(r'\s*else\s*', line):
2594 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 2985 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
2595 if Match(r'\s*}\s*$', prevline): 2986 if Match(r'\s*}\s*$', prevline):
2596 error(filename, linenum, 'whitespace/newline', 4, 2987 error(filename, linenum, 'whitespace/newline', 4,
2597 'An else should appear on the same line as the preceding }') 2988 'An else should appear on the same line as the preceding }')
(...skipping 17 matching lines...) Expand all
2615 # Likewise, an else should never have the else clause on the same line 3006 # Likewise, an else should never have the else clause on the same line
2616 if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): 3007 if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
2617 error(filename, linenum, 'whitespace/newline', 4, 3008 error(filename, linenum, 'whitespace/newline', 4,
2618 'Else clause should never be on same line as else (use 2 lines)') 3009 'Else clause should never be on same line as else (use 2 lines)')
2619 3010
2620 # In the same way, a do/while should never be on one line 3011 # In the same way, a do/while should never be on one line
2621 if Match(r'\s*do [^\s{]', line): 3012 if Match(r'\s*do [^\s{]', line):
2622 error(filename, linenum, 'whitespace/newline', 4, 3013 error(filename, linenum, 'whitespace/newline', 4,
2623 'do/while clauses should not be on a single line') 3014 'do/while clauses should not be on a single line')
2624 3015
2625 # Braces shouldn't be followed by a ; unless they're defining a struct 3016 # Block bodies should not be followed by a semicolon. Due to C++11
2626 # or initializing an array. 3017 # brace initialization, there are more places where semicolons are
2627 # We can't tell in general, but we can for some common cases. 3018 # required than not, so we use a whitelist approach to check these
2628 prevlinenum = linenum 3019 # rather than a blacklist. These are the places where "};" should
2629 while True: 3020 # be replaced by just "}":
2630 (prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum) 3021 # 1. Some flavor of block following closing parenthesis:
2631 if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'): 3022 # for (;;) {};
2632 line = prevline + line 3023 # while (...) {};
2633 else: 3024 # switch (...) {};
2634 break 3025 # Function(...) {};
2635 if (Search(r'{.*}\s*;', line) and 3026 # if (...) {};
2636 line.count('{') == line.count('}') and 3027 # if (...) else if (...) {};
2637 not Search(r'struct|class|enum|\s*=\s*{', line)): 3028 #
2638 error(filename, linenum, 'readability/braces', 4, 3029 # 2. else block:
2639 "You don't need a ; after a }") 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 }")
2640 3129
2641 3130
2642 def CheckEmptyLoopBody(filename, clean_lines, linenum, error): 3131 def CheckEmptyBlockBody(filename, clean_lines, linenum, error):
2643 """Loop for empty loop body with only a single semicolon. 3132 """Look for empty loop/conditional body with only a single semicolon.
2644 3133
2645 Args: 3134 Args:
2646 filename: The name of the current file. 3135 filename: The name of the current file.
2647 clean_lines: A CleansedLines instance containing the file. 3136 clean_lines: A CleansedLines instance containing the file.
2648 linenum: The number of the line to check. 3137 linenum: The number of the line to check.
2649 error: The function to call with any errors found. 3138 error: The function to call with any errors found.
2650 """ 3139 """
2651 3140
2652 # Search for loop keywords at the beginning of the line. Because only 3141 # Search for loop keywords at the beginning of the line. Because only
2653 # whitespaces are allowed before the keywords, this will also ignore most 3142 # whitespaces are allowed before the keywords, this will also ignore most
2654 # do-while-loops, since those lines should start with closing brace. 3143 # do-while-loops, since those lines should start with closing brace.
3144 #
3145 # We also check "if" blocks here, since an empty conditional block
3146 # is likely an error.
2655 line = clean_lines.elided[linenum] 3147 line = clean_lines.elided[linenum]
2656 if Match(r'\s*(for|while)\s*\(', line): 3148 matched = Match(r'\s*(for|while|if)\s*\(', line)
3149 if matched:
2657 # Find the end of the conditional expression 3150 # Find the end of the conditional expression
2658 (end_line, end_linenum, end_pos) = CloseExpression( 3151 (end_line, end_linenum, end_pos) = CloseExpression(
2659 clean_lines, linenum, line.find('(')) 3152 clean_lines, linenum, line.find('('))
2660 3153
2661 # Output warning if what follows the condition expression is a semicolon. 3154 # Output warning if what follows the condition expression is a semicolon.
2662 # No warning for all other cases, including whitespace or newline, since we 3155 # No warning for all other cases, including whitespace or newline, since we
2663 # have a separate check for semicolons preceded by whitespace. 3156 # have a separate check for semicolons preceded by whitespace.
2664 if end_pos >= 0 and Match(r';', end_line[end_pos:]): 3157 if end_pos >= 0 and Match(r';', end_line[end_pos:]):
2665 error(filename, end_linenum, 'whitespace/empty_loop_body', 5, 3158 if matched.group(1) == 'if':
2666 'Empty loop bodies should use {} or continue') 3159 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5,
2667 3160 'Empty conditional bodies should use {}')
2668 3161 else:
2669 def ReplaceableCheck(operator, macro, line): 3162 error(filename, end_linenum, 'whitespace/empty_loop_body', 5,
2670 """Determine whether a basic CHECK can be replaced with a more specific one. 3163 'Empty loop bodies should use {} or continue')
2671
2672 For example suggest using CHECK_EQ instead of CHECK(a == b) and
2673 similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
2674
2675 Args:
2676 operator: The C++ operator used in the CHECK.
2677 macro: The CHECK or EXPECT macro being called.
2678 line: The current source line.
2679
2680 Returns:
2681 True if the CHECK can be replaced with a more specific one.
2682 """
2683
2684 # This matches decimal and hex integers, strings, and chars (in that order).
2685 match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
2686
2687 # Expression to match two sides of the operator with something that
2688 # looks like a literal, since CHECK(x == iterator) won't compile.
2689 # This means we can't catch all the cases where a more specific
2690 # CHECK is possible, but it's less annoying than dealing with
2691 # extraneous warnings.
2692 match_this = (r'\s*' + macro + r'\((\s*' +
2693 match_constant + r'\s*' + operator + r'[^<>].*|'
2694 r'.*[^<>]' + operator + r'\s*' + match_constant +
2695 r'\s*\))')
2696
2697 # Don't complain about CHECK(x == NULL) or similar because
2698 # CHECK_EQ(x, NULL) won't compile (requires a cast).
2699 # Also, don't complain about more complex boolean expressions
2700 # involving && or || such as CHECK(a == b || c == d).
2701 return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line)
2702 3164
2703 3165
2704 def CheckCheck(filename, clean_lines, linenum, error): 3166 def CheckCheck(filename, clean_lines, linenum, error):
2705 """Checks the use of CHECK and EXPECT macros. 3167 """Checks the use of CHECK and EXPECT macros.
2706 3168
2707 Args: 3169 Args:
2708 filename: The name of the current file. 3170 filename: The name of the current file.
2709 clean_lines: A CleansedLines instance containing the file. 3171 clean_lines: A CleansedLines instance containing the file.
2710 linenum: The number of the line to check. 3172 linenum: The number of the line to check.
2711 error: The function to call with any errors found. 3173 error: The function to call with any errors found.
2712 """ 3174 """
2713 3175
2714 # Decide the set of replacement macros that should be suggested 3176 # Decide the set of replacement macros that should be suggested
2715 raw_lines = clean_lines.raw_lines 3177 lines = clean_lines.elided
2716 current_macro = '' 3178 check_macro = None
3179 start_pos = -1
2717 for macro in _CHECK_MACROS: 3180 for macro in _CHECK_MACROS:
2718 if raw_lines[linenum].find(macro) >= 0: 3181 i = lines[linenum].find(macro)
2719 current_macro = 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))
2720 break 3193 break
2721 if not current_macro: 3194 if not check_macro or start_pos < 0:
2722 # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT' 3195 # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
2723 return 3196 return
2724 3197
2725 line = clean_lines.elided[linenum] # get rid of comments and strings 3198 # 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]
2726 3210
2727 # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc. 3211 # Parse expression so that we can take parentheses into account.
2728 for operator in ['==', '!=', '>=', '>', '<=', '<']: 3212 # This avoids false positives for inputs like "CHECK((a < 4) == b)",
2729 if ReplaceableCheck(operator, current_macro, line): 3213 # which is not replaceable by CHECK_LE.
2730 error(filename, linenum, 'readability/check', 2, 3214 lhs = ''
2731 'Consider using %s instead of %s(a %s b)' % ( 3215 rhs = ''
2732 _CHECK_REPLACEMENT[current_macro][operator], 3216 operator = None
2733 current_macro, operator)) 3217 while expression:
2734 break 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))
2735 3291
2736 3292
2737 def CheckAltTokens(filename, clean_lines, linenum, error): 3293 def CheckAltTokens(filename, clean_lines, linenum, error):
2738 """Check alternative keywords being used in boolean expressions. 3294 """Check alternative keywords being used in boolean expressions.
2739 3295
2740 Args: 3296 Args:
2741 filename: The name of the current file. 3297 filename: The name of the current file.
2742 clean_lines: A CleansedLines instance containing the file. 3298 clean_lines: A CleansedLines instance containing the file.
2743 linenum: The number of the line to check. 3299 linenum: The number of the line to check.
2744 error: The function to call with any errors found. 3300 error: The function to call with any errors found.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2799 Args: 3355 Args:
2800 filename: The name of the current file. 3356 filename: The name of the current file.
2801 clean_lines: A CleansedLines instance containing the file. 3357 clean_lines: A CleansedLines instance containing the file.
2802 linenum: The number of the line to check. 3358 linenum: The number of the line to check.
2803 file_extension: The extension (without the dot) of the filename. 3359 file_extension: The extension (without the dot) of the filename.
2804 nesting_state: A _NestingState instance which maintains information about 3360 nesting_state: A _NestingState instance which maintains information about
2805 the current stack of nested blocks being parsed. 3361 the current stack of nested blocks being parsed.
2806 error: The function to call with any errors found. 3362 error: The function to call with any errors found.
2807 """ 3363 """
2808 3364
2809 raw_lines = clean_lines.raw_lines 3365 # 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
2810 line = raw_lines[linenum] 3369 line = raw_lines[linenum]
2811 3370
2812 if line.find('\t') != -1: 3371 if line.find('\t') != -1:
2813 error(filename, linenum, 'whitespace/tab', 1, 3372 error(filename, linenum, 'whitespace/tab', 1,
2814 'Tab found; better to use spaces') 3373 'Tab found; better to use spaces')
2815 3374
2816 # One or three blank spaces at the beginning of the line is weird; it's 3375 # One or three blank spaces at the beginning of the line is weird; it's
2817 # hard to reconcile that with 2-space indents. 3376 # hard to reconcile that with 2-space indents.
2818 # NOTE: here are the conditions rob pike used for his tests. Mine aren't 3377 # NOTE: here are the conditions rob pike used for his tests. Mine aren't
2819 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces 3378 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
2820 # if(RLENGTH > 20) complain = 0; 3379 # if(RLENGTH > 20) complain = 0;
2821 # if(match($0, " +(error|private|public|protected):")) complain = 0; 3380 # if(match($0, " +(error|private|public|protected):")) complain = 0;
2822 # if(match(prev, "&& *$")) complain = 0; 3381 # if(match(prev, "&& *$")) complain = 0;
2823 # if(match(prev, "\\|\\| *$")) complain = 0; 3382 # if(match(prev, "\\|\\| *$")) complain = 0;
2824 # if(match(prev, "[\",=><] *$")) complain = 0; 3383 # if(match(prev, "[\",=><] *$")) complain = 0;
2825 # if(match($0, " <<")) complain = 0; 3384 # if(match($0, " <<")) complain = 0;
2826 # if(match(prev, " +for \\(")) complain = 0; 3385 # if(match(prev, " +for \\(")) complain = 0;
2827 # if(prevodd && match(prevprev, " +for \\(")) complain = 0; 3386 # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
2828 initial_spaces = 0 3387 initial_spaces = 0
2829 cleansed_line = clean_lines.elided[linenum] 3388 cleansed_line = clean_lines.elided[linenum]
2830 while initial_spaces < len(line) and line[initial_spaces] == ' ': 3389 while initial_spaces < len(line) and line[initial_spaces] == ' ':
2831 initial_spaces += 1 3390 initial_spaces += 1
2832 if line and line[-1].isspace(): 3391 if line and line[-1].isspace():
2833 error(filename, linenum, 'whitespace/end_of_line', 4, 3392 error(filename, linenum, 'whitespace/end_of_line', 4,
2834 'Line ends in whitespace. Consider deleting these extra spaces.') 3393 'Line ends in whitespace. Consider deleting these extra spaces.')
2835 # There are certain situations we allow one space, notably for labels 3394 # There are certain situations we allow one space, notably for section labels
2836 elif ((initial_spaces == 1 or initial_spaces == 3) and 3395 elif ((initial_spaces == 1 or initial_spaces == 3) and
2837 not Match(r'\s*\w+\s*:\s*$', cleansed_line)): 3396 not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
2838 error(filename, linenum, 'whitespace/indent', 3, 3397 error(filename, linenum, 'whitespace/indent', 3,
2839 'Weird number of spaces at line-start. ' 3398 'Weird number of spaces at line-start. '
2840 'Are you using a 2-space indent?') 3399 'Are you using a 2-space indent?')
2841 # Labels should always be indented at least one space.
2842 elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
2843 line):
2844 error(filename, linenum, 'whitespace/labels', 4,
2845 'Labels should always be indented at least one space. '
2846 'If this is a member-initializer list in a constructor or '
2847 'the base class list in a class definition, the colon should '
2848 'be on the following line.')
2849
2850 3400
2851 # Check if the line is a header guard. 3401 # Check if the line is a header guard.
2852 is_header_guard = False 3402 is_header_guard = False
2853 if file_extension == 'h': 3403 if file_extension == 'h':
2854 cppvar = GetHeaderGuardCPPVariable(filename) 3404 cppvar = GetHeaderGuardCPPVariable(filename)
2855 if (line.startswith('#ifndef %s' % cppvar) or 3405 if (line.startswith('#ifndef %s' % cppvar) or
2856 line.startswith('#define %s' % cppvar) or 3406 line.startswith('#define %s' % cppvar) or
2857 line.startswith('#endif // %s' % cppvar)): 3407 line.startswith('#endif // %s' % cppvar)):
2858 is_header_guard = True 3408 is_header_guard = True
2859 # #include lines and header guards can be long, since there's no clean way to 3409 # #include lines and header guards can be long, since there's no clean way to
2860 # split them. 3410 # split them.
2861 # 3411 #
2862 # URLs can be long too. It's possible to split these, but it makes them 3412 # URLs can be long too. It's possible to split these, but it makes them
2863 # harder to cut&paste. 3413 # harder to cut&paste.
2864 # 3414 #
2865 # The "$Id:...$" comment may also get very long without it being the 3415 # The "$Id:...$" comment may also get very long without it being the
2866 # developers fault. 3416 # developers fault.
2867 if (not line.startswith('#include') and not is_header_guard and 3417 if (not line.startswith('#include') and not is_header_guard and
2868 not Match(r'^\s*//.*http(s?)://\S*$', line) and 3418 not Match(r'^\s*//.*http(s?)://\S*$', line) and
2869 not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): 3419 not Match(r'^// \$Id:.*#[0-9]+ \$$', line)):
2870 line_width = GetLineWidth(line) 3420 line_width = GetLineWidth(line)
2871 if line_width > 100: 3421 extended_length = int((_line_length * 1.25))
3422 if line_width > extended_length:
2872 error(filename, linenum, 'whitespace/line_length', 4, 3423 error(filename, linenum, 'whitespace/line_length', 4,
2873 'Lines should very rarely be longer than 100 characters') 3424 'Lines should very rarely be longer than %i characters' %
2874 elif line_width > 80: 3425 extended_length)
3426 elif line_width > _line_length:
2875 error(filename, linenum, 'whitespace/line_length', 2, 3427 error(filename, linenum, 'whitespace/line_length', 2,
2876 'Lines should be <= 80 characters long') 3428 'Lines should be <= %i characters long' % _line_length)
2877 3429
2878 if (cleansed_line.count(';') > 1 and 3430 if (cleansed_line.count(';') > 1 and
2879 # for loops are allowed two ;'s (and may run over two lines). 3431 # for loops are allowed two ;'s (and may run over two lines).
2880 cleansed_line.find('for') == -1 and 3432 cleansed_line.find('for') == -1 and
2881 (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or 3433 (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
2882 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and 3434 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
2883 # It's ok to have many commands in a switch case that fits in 1 line 3435 # It's ok to have many commands in a switch case that fits in 1 line
2884 not ((cleansed_line.find('case ') != -1 or 3436 not ((cleansed_line.find('case ') != -1 or
2885 cleansed_line.find('default:') != -1) and 3437 cleansed_line.find('default:') != -1) and
2886 cleansed_line.find('break;') != -1)): 3438 cleansed_line.find('break;') != -1)):
2887 error(filename, linenum, 'whitespace/newline', 0, 3439 error(filename, linenum, 'whitespace/newline', 0,
2888 'More than one command on the same line') 3440 'More than one command on the same line')
2889 3441
2890 # Some more style checks 3442 # Some more style checks
2891 CheckBraces(filename, clean_lines, linenum, error) 3443 CheckBraces(filename, clean_lines, linenum, error)
2892 CheckEmptyLoopBody(filename, clean_lines, linenum, error) 3444 CheckEmptyBlockBody(filename, clean_lines, linenum, error)
2893 CheckAccess(filename, clean_lines, linenum, nesting_state, error) 3445 CheckAccess(filename, clean_lines, linenum, nesting_state, error)
2894 CheckSpacing(filename, clean_lines, linenum, nesting_state, error) 3446 CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
2895 CheckCheck(filename, clean_lines, linenum, error) 3447 CheckCheck(filename, clean_lines, linenum, error)
2896 CheckAltTokens(filename, clean_lines, linenum, error) 3448 CheckAltTokens(filename, clean_lines, linenum, error)
2897 classinfo = nesting_state.InnermostClass() 3449 classinfo = nesting_state.InnermostClass()
2898 if classinfo: 3450 if classinfo:
2899 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) 3451 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
2900 3452
2901 3453
2902 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') 3454 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2972 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) 3524 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
2973 _LIKELY_MY_HEADER 3525 _LIKELY_MY_HEADER
2974 >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), 3526 >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
2975 ... 'bar/foo_other_ext.h', False) 3527 ... 'bar/foo_other_ext.h', False)
2976 _POSSIBLE_MY_HEADER 3528 _POSSIBLE_MY_HEADER
2977 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) 3529 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
2978 _OTHER_HEADER 3530 _OTHER_HEADER
2979 """ 3531 """
2980 # This is a list of all standard c++ header files, except 3532 # This is a list of all standard c++ header files, except
2981 # those already checked for above. 3533 # those already checked for above.
2982 is_stl_h = include in _STL_HEADERS 3534 is_cpp_h = include in _CPP_HEADERS
2983 is_cpp_h = is_stl_h or include in _CPP_HEADERS
2984 3535
2985 if is_system: 3536 if is_system:
2986 if is_cpp_h: 3537 if is_cpp_h:
2987 return _CPP_SYS_HEADER 3538 return _CPP_SYS_HEADER
2988 else: 3539 else:
2989 return _C_SYS_HEADER 3540 return _C_SYS_HEADER
2990 3541
2991 # If the target file and the include we're checking share a 3542 # If the target file and the include we're checking share a
2992 # basename when we drop common extensions, and the include 3543 # basename when we drop common extensions, and the include
2993 # lives in . , then it's likely to be owned by the target file. 3544 # lives in . , then it's likely to be owned by the target file.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3061 # We classify each include statement as one of those 5 types 3612 # We classify each include statement as one of those 5 types
3062 # using a number of techniques. The include_state object keeps 3613 # using a number of techniques. The include_state object keeps
3063 # track of the highest type seen, and complains if we see a 3614 # track of the highest type seen, and complains if we see a
3064 # lower type after that. 3615 # lower type after that.
3065 error_message = include_state.CheckNextIncludeOrder( 3616 error_message = include_state.CheckNextIncludeOrder(
3066 _ClassifyInclude(fileinfo, include, is_system)) 3617 _ClassifyInclude(fileinfo, include, is_system))
3067 if error_message: 3618 if error_message:
3068 error(filename, linenum, 'build/include_order', 4, 3619 error(filename, linenum, 'build/include_order', 4,
3069 '%s. Should be: %s.h, c system, c++ system, other.' % 3620 '%s. Should be: %s.h, c system, c++ system, other.' %
3070 (error_message, fileinfo.BaseName())) 3621 (error_message, fileinfo.BaseName()))
3071 if not include_state.IsInAlphabeticalOrder(include): 3622 canonical_include = include_state.CanonicalizeAlphabeticalOrder(include)
3623 if not include_state.IsInAlphabeticalOrder(
3624 clean_lines, linenum, canonical_include):
3072 error(filename, linenum, 'build/include_alpha', 4, 3625 error(filename, linenum, 'build/include_alpha', 4,
3073 'Include "%s" not in alphabetical order' % include) 3626 'Include "%s" not in alphabetical order' % include)
3627 include_state.SetLastHeader(canonical_include)
3074 3628
3075 # Look for any of the stream classes that are part of standard C++. 3629 # Look for any of the stream classes that are part of standard C++.
3076 match = _RE_PATTERN_INCLUDE.match(line) 3630 match = _RE_PATTERN_INCLUDE.match(line)
3077 if match: 3631 if match:
3078 include = match.group(2) 3632 include = match.group(2)
3079 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): 3633 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
3080 # Many unit tests use cout, so we exempt them. 3634 # Many unit tests use cout, so we exempt them.
3081 if not _IsTestFilename(filename): 3635 if not _IsTestFilename(filename):
3082 error(filename, linenum, 'readability/streams', 3, 3636 error(filename, linenum, 'readability/streams', 3,
3083 'Streams are highly discouraged.') 3637 'Streams are highly discouraged.')
3084 3638
3085 3639
3086 def _GetTextInside(text, start_pattern): 3640 def _GetTextInside(text, start_pattern):
3087 """Retrieves all the text between matching open and close parentheses. 3641 r"""Retrieves all the text between matching open and close parentheses.
3088 3642
3089 Given a string of lines and a regular expression string, retrieve all the text 3643 Given a string of lines and a regular expression string, retrieve all the text
3090 following the expression and between opening punctuation symbols like 3644 following the expression and between opening punctuation symbols like
3091 (, [, or {, and the matching close-punctuation symbol. This properly nested 3645 (, [, or {, and the matching close-punctuation symbol. This properly nested
3092 occurrences of the punctuations, so for the text like 3646 occurrences of the punctuations, so for the text like
3093 printf(a(), b(c())); 3647 printf(a(), b(c()));
3094 a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. 3648 a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'.
3095 start_pattern must match string having an open punctuation symbol at the end. 3649 start_pattern must match string having an open punctuation symbol at the end.
3096 3650
3097 Args: 3651 Args:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3132 elif text[position] in matching_punctuation: 3686 elif text[position] in matching_punctuation:
3133 punctuation_stack.append(matching_punctuation[text[position]]) 3687 punctuation_stack.append(matching_punctuation[text[position]])
3134 position += 1 3688 position += 1
3135 if punctuation_stack: 3689 if punctuation_stack:
3136 # Opening punctuations left without matching close-punctuations. 3690 # Opening punctuations left without matching close-punctuations.
3137 return None 3691 return None
3138 # punctuations match. 3692 # punctuations match.
3139 return text[start_position:position - 1] 3693 return text[start_position:position - 1]
3140 3694
3141 3695
3142 def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state, 3696 # Patterns for matching call-by-reference parameters.
3143 error): 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
3722 def CheckLanguage(filename, clean_lines, linenum, file_extension,
3723 include_state, nesting_state, error):
3144 """Checks rules from the 'C++ language rules' section of cppguide.html. 3724 """Checks rules from the 'C++ language rules' section of cppguide.html.
3145 3725
3146 Some of these rules are hard to test (function overloading, using 3726 Some of these rules are hard to test (function overloading, using
3147 uint32 inappropriately), but we do the best we can. 3727 uint32 inappropriately), but we do the best we can.
3148 3728
3149 Args: 3729 Args:
3150 filename: The name of the current file. 3730 filename: The name of the current file.
3151 clean_lines: A CleansedLines instance containing the file. 3731 clean_lines: A CleansedLines instance containing the file.
3152 linenum: The number of the line to check. 3732 linenum: The number of the line to check.
3153 file_extension: The extension (without the dot) of the filename. 3733 file_extension: The extension (without the dot) of the filename.
3154 include_state: An _IncludeState instance in which the headers are inserted. 3734 include_state: An _IncludeState instance in which the headers are inserted.
3735 nesting_state: A _NestingState instance which maintains information about
3736 the current stack of nested blocks being parsed.
3155 error: The function to call with any errors found. 3737 error: The function to call with any errors found.
3156 """ 3738 """
3157 # If the line is empty or consists of entirely a comment, no need to 3739 # If the line is empty or consists of entirely a comment, no need to
3158 # check it. 3740 # check it.
3159 line = clean_lines.elided[linenum] 3741 line = clean_lines.elided[linenum]
3160 if not line: 3742 if not line:
3161 return 3743 return
3162 3744
3163 match = _RE_PATTERN_INCLUDE.search(line) 3745 match = _RE_PATTERN_INCLUDE.search(line)
3164 if match: 3746 if match:
3165 CheckIncludeLine(filename, clean_lines, linenum, include_state, error) 3747 CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
3166 return 3748 return
3167 3749
3168 # Create an extended_line, which is the concatenation of the current and 3750 # Reset include state across preprocessor directives. This is meant
3169 # next lines, for more effective checking of code that may span more than one 3751 # to silence warnings for conditional includes.
3170 # line. 3752 if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line):
3171 if linenum + 1 < clean_lines.NumLines(): 3753 include_state.ResetSection()
3172 extended_line = line + clean_lines.elided[linenum + 1]
3173 else:
3174 extended_line = line
3175 3754
3176 # Make Windows paths like Unix. 3755 # Make Windows paths like Unix.
3177 fullname = os.path.abspath(filename).replace('\\', '/') 3756 fullname = os.path.abspath(filename).replace('\\', '/')
3178 3757
3179 # TODO(unknown): figure out if they're using default arguments in fn proto. 3758 # TODO(unknown): figure out if they're using default arguments in fn proto.
3180 3759
3181 # Check for non-const references in functions. This is tricky because &
3182 # is also used to take the address of something. We allow <> for templates,
3183 # (ignoring whatever is between the braces) and : for classes.
3184 # These are complicated re's. They try to capture the following:
3185 # paren (for fn-prototype start), typename, &, varname. For the const
3186 # version, we're willing for const to be before typename or after
3187 # Don't check the implementation on same line.
3188 fnline = line.split('{', 1)[0]
3189 if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) >
3190 len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?'
3191 r'(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) +
3192 len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+\s+const(\s?&|&\s?)[\w]+',
3193 fnline))):
3194
3195 # We allow non-const references in a few standard places, like functions
3196 # called "swap()" or iostream operators like "<<" or ">>". We also filter
3197 # out for loops, which lint otherwise mistakenly thinks are functions.
3198 if not Search(
3199 r'(for|swap|Swap|operator[<>][<>])\s*\(\s*'
3200 r'(?:(?:typename\s*)?[\w:]|<.*>)+\s*&',
3201 fnline):
3202 error(filename, linenum, 'runtime/references', 2,
3203 'Is this a non-const reference? '
3204 'If so, make const or use a pointer.')
3205
3206 # Check to see if they're using an conversion function cast. 3760 # Check to see if they're using an conversion function cast.
3207 # I just try to capture the most common basic types, though there are more. 3761 # I just try to capture the most common basic types, though there are more.
3208 # Parameterless conversion functions, such as bool(), are allowed as they are 3762 # Parameterless conversion functions, such as bool(), are allowed as they are
3209 # probably a member operator declaration or default constructor. 3763 # probably a member operator declaration or default constructor.
3210 match = Search( 3764 match = Search(
3211 r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there 3765 r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there
3212 r'(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line) 3766 r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
3767 r'(\([^)].*)', line)
3213 if match: 3768 if match:
3769 matched_new = match.group(1)
3770 matched_type = match.group(2)
3771 matched_funcptr = match.group(3)
3772
3214 # gMock methods are defined using some variant of MOCK_METHODx(name, type) 3773 # gMock methods are defined using some variant of MOCK_METHODx(name, type)
3215 # where type may be float(), int(string), etc. Without context they are 3774 # where type may be float(), int(string), etc. Without context they are
3216 # virtually indistinguishable from int(x) casts. Likewise, gMock's 3775 # virtually indistinguishable from int(x) casts. Likewise, gMock's
3217 # MockCallback takes a template parameter of the form return_type(arg_type), 3776 # MockCallback takes a template parameter of the form return_type(arg_type),
3218 # which looks much like the cast we're trying to detect. 3777 # which looks much like the cast we're trying to detect.
3219 if (match.group(1) is None and # If new operator, then this isn't a cast 3778 #
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
3220 not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or 3784 not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
3221 Match(r'^\s*MockCallback<.*>', line))): 3785 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))):
3222 # Try a bit harder to catch gmock lines: the only place where 3790 # Try a bit harder to catch gmock lines: the only place where
3223 # something looks like an old-style cast is where we declare the 3791 # something looks like an old-style cast is where we declare the
3224 # return type of the mocked method, and the only time when we 3792 # return type of the mocked method, and the only time when we
3225 # are missing context is if MOCK_METHOD was split across 3793 # are missing context is if MOCK_METHOD was split across
3226 # multiple lines (for example http://go/hrfhr ), so we only need 3794 # multiple lines. The missing MOCK_METHOD is usually one or two
3227 # to check the previous line for MOCK_METHOD. 3795 # lines back, so scan back one or two lines.
3228 if (linenum == 0 or 3796 #
3229 not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(\S+,\s*$', 3797 # It's not possible for gmock macros to appear in the first 2
3230 clean_lines.elided[linenum - 1])): 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]))):
3231 error(filename, linenum, 'readability/casting', 4, 3804 error(filename, linenum, 'readability/casting', 4,
3232 'Using deprecated casting style. ' 3805 'Using deprecated casting style. '
3233 'Use static_cast<%s>(...) instead' % 3806 'Use static_cast<%s>(...) instead' %
3234 match.group(2)) 3807 matched_type)
3235 3808
3236 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 3809 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3237 'static_cast', 3810 'static_cast',
3238 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) 3811 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
3239 3812
3240 # This doesn't catch all cases. Consider (const char * const)"hello". 3813 # This doesn't catch all cases. Consider (const char * const)"hello".
3241 # 3814 #
3242 # (char *) "foo" should always be a const_cast (reinterpret_cast won't 3815 # (char *) "foo" should always be a const_cast (reinterpret_cast won't
3243 # compile). 3816 # compile).
3244 if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 3817 if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3245 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error): 3818 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error):
3246 pass 3819 pass
3247 else: 3820 else:
3248 # Check pointer casts for other than string constants 3821 # Check pointer casts for other than string constants
3249 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 3822 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3250 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) 3823 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
3251 3824
3252 # In addition, we look for people taking the address of a cast. This 3825 # In addition, we look for people taking the address of a cast. This
3253 # is dangerous -- casts can assign to temporaries, so the pointer doesn't 3826 # is dangerous -- casts can assign to temporaries, so the pointer doesn't
3254 # point where you think. 3827 # point where you think.
3255 if Search( 3828 match = Search(
3256 r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line): 3829 r'(?:&\(([^)]+)\)[\w(])|'
3830 r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line)
3831 if match and match.group(1) != '*':
3257 error(filename, linenum, 'runtime/casting', 4, 3832 error(filename, linenum, 'runtime/casting', 4,
3258 ('Are you taking an address of a cast? ' 3833 ('Are you taking an address of a cast? '
3259 'This is dangerous: could be a temp var. ' 3834 'This is dangerous: could be a temp var. '
3260 'Take the address before doing the cast, rather than after')) 3835 'Take the address before doing the cast, rather than after'))
3261 3836
3837 # 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
3262 # Check for people declaring static/global STL strings at the top level. 3845 # Check for people declaring static/global STL strings at the top level.
3263 # This is dangerous because the C++ language does not guarantee that 3846 # This is dangerous because the C++ language does not guarantee that
3264 # globals with constructors are initialized before the first access. 3847 # globals with constructors are initialized before the first access.
3265 match = Match( 3848 match = Match(
3266 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', 3849 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
3267 line) 3850 line)
3268 # Make sure it's not a function. 3851 # Make sure it's not a function.
3269 # Function template specialization looks like: "string foo<Type>(...". 3852 # Function template specialization looks like: "string foo<Type>(...".
3270 # Class template definitions look like: "string Foo<Type>::Method(...". 3853 # Class template definitions look like: "string Foo<Type>::Method(...".
3271 if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', 3854 #
3272 match.group(3)): 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))):
3273 error(filename, linenum, 'runtime/string', 4, 3861 error(filename, linenum, 'runtime/string', 4,
3274 'For a static/global string constant, use a C style string instead: ' 3862 'For a static/global string constant, use a C style string instead: '
3275 '"%schar %s[]".' % 3863 '"%schar %s[]".' %
3276 (match.group(1), match.group(2))) 3864 (match.group(1), match.group(2)))
3277 3865
3278 # Check that we're not using RTTI outside of testing code.
3279 if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename):
3280 error(filename, linenum, 'runtime/rtti', 5,
3281 'Do not use dynamic_cast<>. If you need to cast within a class '
3282 "hierarchy, use static_cast<> to upcast. Google doesn't support "
3283 'RTTI.')
3284
3285 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): 3866 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
3286 error(filename, linenum, 'runtime/init', 4, 3867 error(filename, linenum, 'runtime/init', 4,
3287 'You seem to be initializing a member variable with itself.') 3868 'You seem to be initializing a member variable with itself.')
3288 3869
3289 if file_extension == 'h': 3870 if file_extension == 'h':
3290 # TODO(unknown): check that 1-arg constructors are explicit. 3871 # TODO(unknown): check that 1-arg constructors are explicit.
3291 # How to tell it's a constructor? 3872 # How to tell it's a constructor?
3292 # (handled in CheckForNonStandardConstructs for now) 3873 # (handled in CheckForNonStandardConstructs for now)
3293 # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS 3874 # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
3294 # (level 1 error) 3875 # (level 1 error)
(...skipping 21 matching lines...) Expand all
3316 3897
3317 # Check if some verboten C functions are being used. 3898 # Check if some verboten C functions are being used.
3318 if Search(r'\bsprintf\b', line): 3899 if Search(r'\bsprintf\b', line):
3319 error(filename, linenum, 'runtime/printf', 5, 3900 error(filename, linenum, 'runtime/printf', 5,
3320 'Never use sprintf. Use snprintf instead.') 3901 'Never use sprintf. Use snprintf instead.')
3321 match = Search(r'\b(strcpy|strcat)\b', line) 3902 match = Search(r'\b(strcpy|strcat)\b', line)
3322 if match: 3903 if match:
3323 error(filename, linenum, 'runtime/printf', 4, 3904 error(filename, linenum, 'runtime/printf', 4,
3324 'Almost always, snprintf is better than %s' % match.group(1)) 3905 'Almost always, snprintf is better than %s' % match.group(1))
3325 3906
3326 if Search(r'\bsscanf\b', line):
3327 error(filename, linenum, 'runtime/printf', 1,
3328 'sscanf can be ok, but is slow and can overflow buffers.')
3329
3330 # Check if some verboten operator overloading is going on 3907 # Check if some verboten operator overloading is going on
3331 # TODO(unknown): catch out-of-line unary operator&: 3908 # TODO(unknown): catch out-of-line unary operator&:
3332 # class X {}; 3909 # class X {};
3333 # int operator&(const X& x) { return 42; } // unary operator& 3910 # int operator&(const X& x) { return 42; } // unary operator&
3334 # The trick is it's hard to tell apart from binary operator&: 3911 # The trick is it's hard to tell apart from binary operator&:
3335 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& 3912 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
3336 if Search(r'\boperator\s*&\s*\(\s*\)', line): 3913 if Search(r'\boperator\s*&\s*\(\s*\)', line):
3337 error(filename, linenum, 'runtime/operator', 4, 3914 error(filename, linenum, 'runtime/operator', 4,
3338 'Unary operator& is dangerous. Do not use it.') 3915 'Unary operator& is dangerous. Do not use it.')
3339 3916
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
3435 # macros are typically OK, so we allow use of "namespace {" on lines 4012 # macros are typically OK, so we allow use of "namespace {" on lines
3436 # that end with backslashes. 4013 # that end with backslashes.
3437 if (file_extension == 'h' 4014 if (file_extension == 'h'
3438 and Search(r'\bnamespace\s*{', line) 4015 and Search(r'\bnamespace\s*{', line)
3439 and line[-1] != '\\'): 4016 and line[-1] != '\\'):
3440 error(filename, linenum, 'build/namespaces', 4, 4017 error(filename, linenum, 'build/namespaces', 4,
3441 'Do not use unnamed namespaces in header files. See ' 4018 'Do not use unnamed namespaces in header files. See '
3442 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp aces' 4019 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp aces'
3443 ' for more information.') 4020 ' for more information.')
3444 4021
4022 def 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
3445 4134
3446 def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, 4135 def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
3447 error): 4136 error):
3448 """Checks for a C-style cast by looking for the pattern. 4137 """Checks for a C-style cast by looking for the pattern.
3449 4138
3450 This also handles sizeof(type) warnings, due to similarity of content.
3451
3452 Args: 4139 Args:
3453 filename: The name of the current file. 4140 filename: The name of the current file.
3454 linenum: The number of the line to check. 4141 linenum: The number of the line to check.
3455 line: The line of code to check. 4142 line: The line of code to check.
3456 raw_line: The raw line of code to check, with comments. 4143 raw_line: The raw line of code to check, with comments.
3457 cast_type: The string for the C++ cast to recommend. This is either 4144 cast_type: The string for the C++ cast to recommend. This is either
3458 reinterpret_cast, static_cast, or const_cast, depending. 4145 reinterpret_cast, static_cast, or const_cast, depending.
3459 pattern: The regular expression used to find C-style casts. 4146 pattern: The regular expression used to find C-style casts.
3460 error: The function to call with any errors found. 4147 error: The function to call with any errors found.
3461 4148
3462 Returns: 4149 Returns:
3463 True if an error was emitted. 4150 True if an error was emitted.
3464 False otherwise. 4151 False otherwise.
3465 """ 4152 """
3466 match = Search(pattern, line) 4153 match = Search(pattern, line)
3467 if not match: 4154 if not match:
3468 return False 4155 return False
3469 4156
3470 # e.g., sizeof(int) 4157 # Exclude lines with sizeof, since sizeof looks like a cast.
3471 sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1]) 4158 sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
3472 if sizeof_match: 4159 if sizeof_match:
3473 error(filename, linenum, 'runtime/sizeof', 1, 4160 return False
3474 'Using sizeof(type). Use sizeof(varname) instead if possible')
3475 return True
3476 4161
3477 # operator++(int) and operator--(int) 4162 # operator++(int) and operator--(int)
3478 if (line[0:match.start(1) - 1].endswith(' operator++') or 4163 if (line[0:match.start(1) - 1].endswith(' operator++') or
3479 line[0:match.start(1) - 1].endswith(' operator--')): 4164 line[0:match.start(1) - 1].endswith(' operator--')):
3480 return False 4165 return False
3481 4166
4167 # 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.
4171 #
4172 # 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)>;
3482 remainder = line[match.end(0):] 4190 remainder = line[match.end(0):]
4191 if Match(r'^\s*(?:;|const\b|throw\b|=|>|\{|\))', remainder):
4192 # Looks like an unnamed parameter.
3483 4193
3484 # The close paren is for function pointers as arguments to a function. 4194 # Don't warn on any kind of template arguments.
3485 # eg, void foo(void (*bar)(int)); 4195 if Match(r'^\s*>', remainder):
3486 # The semicolon check is a more basic function check; also possibly a 4196 return False
3487 # function pointer typedef. 4197
3488 # eg, void foo(int); or void foo(int) const; 4198 # Don't warn on assignments to function pointers, but keep warnings for
3489 # The equals check is for function pointer assignment. 4199 # unnamed parameters to pure virtual functions. Note that this pattern
3490 # eg, void *(*foo)(int) = ... 4200 # will also pass on assignments of "0" to function pointers, but the
3491 # The > is for MockCallback<...> ... 4201 # preferred values for those would be "nullptr" or "NULL".
3492 # 4202 matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder)
3493 # Right now, this will only catch cases where there's a single argument, and 4203 if matched_zero and matched_zero.group(1) != '0':
3494 # it's unnamed. It should probably be expanded to check for multiple 4204 return False
3495 # arguments with some unnamed. 4205
3496 function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)|>))', remainder) 4206 # Don't warn on function pointer declarations. For this we need
3497 if function_match: 4207 # to check what came before the "(type)" string.
3498 if (not function_match.group(3) or 4208 if Match(r'.*\)\s*$', line[0:match.start(0)]):
3499 function_match.group(3) == ';' or 4209 return False
3500 ('MockCallback<' not in raw_line and 4210
3501 '/*' not in raw_line)): 4211 # Don't warn if the parameter is named with block comments, e.g.:
3502 error(filename, linenum, 'readability/function', 3, 4212 # Function(int /*unused_param*/);
3503 'All parameters should be named in a function') 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')
3504 return True 4219 return True
3505 4220
3506 # At this point, all that should be left is actual casts. 4221 # At this point, all that should be left is actual casts.
3507 error(filename, linenum, 'readability/casting', 4, 4222 error(filename, linenum, 'readability/casting', 4,
3508 'Using C-style cast. Use %s<%s>(...) instead' % 4223 'Using C-style cast. Use %s<%s>(...) instead' %
3509 (cast_type, match.group(1))) 4224 (cast_type, match.group(1)))
3510 4225
3511 return True 4226 return True
3512 4227
3513 4228
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 4469
3755 G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are 4470 G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are
3756 specified explicitly, and such use isn't intended in any case. 4471 specified explicitly, and such use isn't intended in any case.
3757 4472
3758 Args: 4473 Args:
3759 filename: The name of the current file. 4474 filename: The name of the current file.
3760 clean_lines: A CleansedLines instance containing the file. 4475 clean_lines: A CleansedLines instance containing the file.
3761 linenum: The number of the line to check. 4476 linenum: The number of the line to check.
3762 error: The function to call with any errors found. 4477 error: The function to call with any errors found.
3763 """ 4478 """
3764 raw = clean_lines.raw_lines 4479 line = clean_lines.elided[linenum]
3765 line = raw[linenum]
3766 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) 4480 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)
3767 if match: 4481 if match:
3768 error(filename, linenum, 'build/explicit_make_pair', 4482 error(filename, linenum, 'build/explicit_make_pair',
3769 4, # 4 = high confidence 4483 4, # 4 = high confidence
3770 'For C++11-compatibility, omit template arguments from make_pair' 4484 'For C++11-compatibility, omit template arguments from make_pair'
3771 ' OR use pair directly OR if appropriate, construct a pair directly') 4485 ' OR use pair directly OR if appropriate, construct a pair directly')
3772 4486
3773 4487
3774 def ProcessLine(filename, file_extension, clean_lines, line, 4488 def ProcessLine(filename, file_extension, clean_lines, line,
3775 include_state, function_state, nesting_state, error, 4489 include_state, function_state, nesting_state, error,
(...skipping 18 matching lines...) Expand all
3794 """ 4508 """
3795 raw_lines = clean_lines.raw_lines 4509 raw_lines = clean_lines.raw_lines
3796 ParseNolintSuppressions(filename, raw_lines[line], line, error) 4510 ParseNolintSuppressions(filename, raw_lines[line], line, error)
3797 nesting_state.Update(filename, clean_lines, line, error) 4511 nesting_state.Update(filename, clean_lines, line, error)
3798 if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM: 4512 if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM:
3799 return 4513 return
3800 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) 4514 CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
3801 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) 4515 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
3802 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) 4516 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)
3803 CheckLanguage(filename, clean_lines, line, file_extension, include_state, 4517 CheckLanguage(filename, clean_lines, line, file_extension, include_state,
3804 error) 4518 nesting_state, error)
4519 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error)
3805 CheckForNonStandardConstructs(filename, clean_lines, line, 4520 CheckForNonStandardConstructs(filename, clean_lines, line,
3806 nesting_state, error) 4521 nesting_state, error)
4522 CheckVlogArguments(filename, clean_lines, line, error)
3807 CheckPosixThreading(filename, clean_lines, line, error) 4523 CheckPosixThreading(filename, clean_lines, line, error)
3808 CheckInvalidIncrement(filename, clean_lines, line, error) 4524 CheckInvalidIncrement(filename, clean_lines, line, error)
3809 CheckMakePairUsesDeduction(filename, clean_lines, line, error) 4525 CheckMakePairUsesDeduction(filename, clean_lines, line, error)
3810 for check_fn in extra_check_functions: 4526 for check_fn in extra_check_functions:
3811 check_fn(filename, clean_lines, line, error) 4527 check_fn(filename, clean_lines, line, error)
3812 4528
3813 def ProcessFileData(filename, file_extension, lines, error, 4529 def ProcessFileData(filename, file_extension, lines, error,
3814 extra_check_functions=[]): 4530 extra_check_functions=[]):
3815 """Performs lint checks and reports any errors to the given error function. 4531 """Performs lint checks and reports any errors to the given error function.
3816 4532
(...skipping 21 matching lines...) Expand all
3838 4554
3839 if file_extension == 'h': 4555 if file_extension == 'h':
3840 CheckForHeaderGuard(filename, lines, error) 4556 CheckForHeaderGuard(filename, lines, error)
3841 4557
3842 RemoveMultiLineComments(filename, lines, error) 4558 RemoveMultiLineComments(filename, lines, error)
3843 clean_lines = CleansedLines(lines) 4559 clean_lines = CleansedLines(lines)
3844 for line in xrange(clean_lines.NumLines()): 4560 for line in xrange(clean_lines.NumLines()):
3845 ProcessLine(filename, file_extension, clean_lines, line, 4561 ProcessLine(filename, file_extension, clean_lines, line,
3846 include_state, function_state, nesting_state, error, 4562 include_state, function_state, nesting_state, error,
3847 extra_check_functions) 4563 extra_check_functions)
3848 nesting_state.CheckClassFinished(filename, error) 4564 nesting_state.CheckCompletedBlocks(filename, error)
3849 4565
3850 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) 4566 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
3851 4567
3852 # We check here rather than inside ProcessLine so that we see raw 4568 # We check here rather than inside ProcessLine so that we see raw
3853 # lines rather than "cleaned" lines. 4569 # lines rather than "cleaned" lines.
3854 CheckForUnicodeReplacementCharacters(filename, lines, error) 4570 CheckForBadCharacters(filename, lines, error)
3855 4571
3856 CheckForNewlineAtEOF(filename, lines, error) 4572 CheckForNewlineAtEOF(filename, lines, error)
3857 4573
3858 def ProcessFile(filename, vlevel, extra_check_functions=[]): 4574 def ProcessFile(filename, vlevel, extra_check_functions=[]):
3859 """Does google-lint on a single file. 4575 """Does google-lint on a single file.
3860 4576
3861 Args: 4577 Args:
3862 filename: The name of the file to parse. 4578 filename: The name of the file to parse.
3863 4579
3864 vlevel: The level of errors to report. Every error of confidence 4580 vlevel: The level of errors to report. Every error of confidence
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3900 except IOError: 4616 except IOError:
3901 sys.stderr.write( 4617 sys.stderr.write(
3902 "Skipping input '%s': Can't open for reading\n" % filename) 4618 "Skipping input '%s': Can't open for reading\n" % filename)
3903 return 4619 return
3904 4620
3905 # Note, if no dot is found, this will give the entire filename as the ext. 4621 # Note, if no dot is found, this will give the entire filename as the ext.
3906 file_extension = filename[filename.rfind('.') + 1:] 4622 file_extension = filename[filename.rfind('.') + 1:]
3907 4623
3908 # When reading from stdin, the extension is unknown, so no cpplint tests 4624 # When reading from stdin, the extension is unknown, so no cpplint tests
3909 # should rely on the extension. 4625 # should rely on the extension.
3910 if (filename != '-' and file_extension != 'cc' and file_extension != 'h' 4626 if filename != '-' and file_extension not in _valid_extensions:
3911 and file_extension != 'cpp'): 4627 sys.stderr.write('Ignoring %s; not a valid file name '
3912 sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename) 4628 '(%s)\n' % (filename, ', '.join(_valid_extensions)))
3913 else: 4629 else:
3914 ProcessFileData(filename, file_extension, lines, Error, 4630 ProcessFileData(filename, file_extension, lines, Error,
3915 extra_check_functions) 4631 extra_check_functions)
3916 if carriage_return_found and os.linesep != '\r\n': 4632 if carriage_return_found and os.linesep != '\r\n':
3917 # Use 0 for linenum since outputting only one error for potentially 4633 # Use 0 for linenum since outputting only one error for potentially
3918 # several lines. 4634 # several lines.
3919 Error(filename, 0, 'whitespace/newline', 1, 4635 Error(filename, 0, 'whitespace/newline', 1,
3920 'One or more unexpected \\r (^M) found;' 4636 'One or more unexpected \\r (^M) found;'
3921 'better to use only a \\n') 4637 'better to use only a \\n')
3922 4638
(...skipping 30 matching lines...) Expand all
3953 Args: 4669 Args:
3954 args: The command line arguments: 4670 args: The command line arguments:
3955 4671
3956 Returns: 4672 Returns:
3957 The list of filenames to lint. 4673 The list of filenames to lint.
3958 """ 4674 """
3959 try: 4675 try:
3960 (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', 4676 (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
3961 'counting=', 4677 'counting=',
3962 'filter=', 4678 'filter=',
3963 'root=']) 4679 'root=',
4680 'linelength=',
4681 'extensions='])
3964 except getopt.GetoptError: 4682 except getopt.GetoptError:
3965 PrintUsage('Invalid arguments.') 4683 PrintUsage('Invalid arguments.')
3966 4684
3967 verbosity = _VerboseLevel() 4685 verbosity = _VerboseLevel()
3968 output_format = _OutputFormat() 4686 output_format = _OutputFormat()
3969 filters = '' 4687 filters = ''
3970 counting_style = '' 4688 counting_style = ''
3971 4689
3972 for (opt, val) in opts: 4690 for (opt, val) in opts:
3973 if opt == '--help': 4691 if opt == '--help':
3974 PrintUsage(None) 4692 PrintUsage(None)
3975 elif opt == '--output': 4693 elif opt == '--output':
3976 if not val in ('emacs', 'vs7', 'eclipse'): 4694 if val not in ('emacs', 'vs7', 'eclipse'):
3977 PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.' ) 4695 PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.' )
3978 output_format = val 4696 output_format = val
3979 elif opt == '--verbose': 4697 elif opt == '--verbose':
3980 verbosity = int(val) 4698 verbosity = int(val)
3981 elif opt == '--filter': 4699 elif opt == '--filter':
3982 filters = val 4700 filters = val
3983 if not filters: 4701 if not filters:
3984 PrintCategories() 4702 PrintCategories()
3985 elif opt == '--counting': 4703 elif opt == '--counting':
3986 if val not in ('total', 'toplevel', 'detailed'): 4704 if val not in ('total', 'toplevel', 'detailed'):
3987 PrintUsage('Valid counting options are total, toplevel, and detailed') 4705 PrintUsage('Valid counting options are total, toplevel, and detailed')
3988 counting_style = val 4706 counting_style = val
3989 elif opt == '--root': 4707 elif opt == '--root':
3990 global _root 4708 global _root
3991 _root = val 4709 _root = val
4710 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.')
3992 4722
3993 if not filenames: 4723 if not filenames:
3994 PrintUsage('No files were specified.') 4724 PrintUsage('No files were specified.')
3995 4725
3996 _SetOutputFormat(output_format) 4726 _SetOutputFormat(output_format)
3997 _SetVerboseLevel(verbosity) 4727 _SetVerboseLevel(verbosity)
3998 _SetFilters(filters) 4728 _SetFilters(filters)
3999 _SetCountingStyle(counting_style) 4729 _SetCountingStyle(counting_style)
4000 4730
4001 return filenames 4731 return filenames
(...skipping 12 matching lines...) Expand all
4014 _cpplint_state.ResetErrorCounts() 4744 _cpplint_state.ResetErrorCounts()
4015 for filename in filenames: 4745 for filename in filenames:
4016 ProcessFile(filename, _cpplint_state.verbose_level) 4746 ProcessFile(filename, _cpplint_state.verbose_level)
4017 _cpplint_state.PrintErrorCounts() 4747 _cpplint_state.PrintErrorCounts()
4018 4748
4019 sys.exit(_cpplint_state.error_count > 0) 4749 sys.exit(_cpplint_state.error_count > 0)
4020 4750
4021 4751
4022 if __name__ == '__main__': 4752 if __name__ == '__main__':
4023 main() 4753 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698