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

Side by Side Diff: cpplint.py

Issue 395022: - Add a presubmit check that lints C++ files (will submit CLs that... (Closed) Base URL: svn://chrome-svn/chrome/trunk/tools/depot_tools/
Patch Set: '' Created 11 years, 1 month 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 | presubmit_canned_checks.py » ('j') | 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/python2.4 1 #!/usr/bin/python2.4
2 # 2 #
3 # cpplint.py is Copyright (C) 2009 Google Inc. 3 # Copyright (c) 2009 Google Inc. All rights reserved.
4 # 4 #
5 # It is free software; you can redistribute it and/or modify it under the 5 # Redistribution and use in source and binary forms, with or without
6 # terms of either: 6 # modification, are permitted provided that the following conditions are
7 # met:
7 # 8 #
8 # a) the GNU General Public License as published by the Free Software 9 # * Redistributions of source code must retain the above copyright
9 # Foundation; either version 1, or (at your option) any later version, or 10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
10 # 18 #
11 # b) the "Artistic License". 19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 30
13 # Here are some issues that I've had people identify in my code during reviews, 31 # Here are some issues that I've had people identify in my code during reviews,
14 # that I think are possible to flag automatically in a lint tool. If these were 32 # that I think are possible to flag automatically in a lint tool. If these were
15 # caught by lint, it would save time both for myself and that of my reviewers. 33 # caught by lint, it would save time both for myself and that of my reviewers.
16 # Most likely, some of these are beyond the scope of the current lint framework, 34 # Most likely, some of these are beyond the scope of the current lint framework,
17 # but I think it is valuable to retain these wish-list items even if they cannot 35 # but I think it is valuable to retain these wish-list items even if they cannot
18 # be immediately implemented. 36 # be immediately implemented.
19 # 37 #
20 # Suggestions 38 # Suggestions
21 # ----------- 39 # -----------
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 import os 85 import os
68 import re 86 import re
69 import sre_compile 87 import sre_compile
70 import string 88 import string
71 import sys 89 import sys
72 import unicodedata 90 import unicodedata
73 91
74 92
75 _USAGE = """ 93 _USAGE = """
76 Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] 94 Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
95 [--counting=total|toplevel|detailed]
77 <file> [file] ... 96 <file> [file] ...
78 97
79 The style guidelines this tries to follow are those in 98 The style guidelines this tries to follow are those in
80 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 99 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
81 100
82 Every problem is given a confidence score from 1-5, with 5 meaning we are 101 Every problem is given a confidence score from 1-5, with 5 meaning we are
83 certain of the problem, and 1 meaning it could be a legitimate construct. 102 certain of the problem, and 1 meaning it could be a legitimate construct.
84 This will miss some errors, and is not a substitute for a code review. 103 This will miss some errors, and is not a substitute for a code review.
85 104
86 To prevent specific lines from being linted, add a '// NOLINT' comment to the 105 To prevent specific lines from being linted, add a '// NOLINT' comment to the
(...skipping 18 matching lines...) Expand all
105 "[whitespace/indent]".) Filters are evaluated left to right. 124 "[whitespace/indent]".) Filters are evaluated left to right.
106 "-FOO" and "FOO" means "do not print categories that start with FOO". 125 "-FOO" and "FOO" means "do not print categories that start with FOO".
107 "+FOO" means "do print categories that start with FOO". 126 "+FOO" means "do print categories that start with FOO".
108 127
109 Examples: --filter=-whitespace,+whitespace/braces 128 Examples: --filter=-whitespace,+whitespace/braces
110 --filter=whitespace,runtime/printf,+runtime/printf_format 129 --filter=whitespace,runtime/printf,+runtime/printf_format
111 --filter=-,+build/include_what_you_use 130 --filter=-,+build/include_what_you_use
112 131
113 To see a list of all the categories used in cpplint, pass no arg: 132 To see a list of all the categories used in cpplint, pass no arg:
114 --filter= 133 --filter=
134
135 counting=total|toplevel|detailed
136 The total number of errors found is always printed. If
137 'toplevel' is provided, then the count of errors in each of
138 the top-level categories like 'build' and 'whitespace' will
139 also be printed. If 'detailed' is provided, then a count
140 is provided for each category like 'build/class'.
115 """ 141 """
116 142
117 # We categorize each error message we print. Here are the categories. 143 # We categorize each error message we print. Here are the categories.
118 # We want an explicit list so we can list them all in cpplint --filter=. 144 # We want an explicit list so we can list them all in cpplint --filter=.
119 # If you add a new error message with a new category, add it to the list 145 # If you add a new error message with a new category, add it to the list
120 # here! cpplint_unittest.py should tell you if you forget to do this. 146 # here! cpplint_unittest.py should tell you if you forget to do this.
121 # \ used for clearer layout -- pylint: disable-msg=C6013 147 # \ used for clearer layout -- pylint: disable-msg=C6013
122 _ERROR_CATEGORIES = '''\ 148 _ERROR_CATEGORIES = '''\
123 build/class 149 build/class
124 build/deprecated 150 build/deprecated
125 build/endif_comment 151 build/endif_comment
126 build/forward_decl 152 build/forward_decl
127 build/header_guard 153 build/header_guard
128 build/include 154 build/include
155 build/include_alpha
129 build/include_order 156 build/include_order
130 build/include_what_you_use 157 build/include_what_you_use
131 build/namespaces 158 build/namespaces
132 build/printf_format 159 build/printf_format
133 build/storage_class 160 build/storage_class
134 legal/copyright 161 legal/copyright
135 readability/braces 162 readability/braces
136 readability/casting 163 readability/casting
137 readability/check 164 readability/check
138 readability/constructors 165 readability/constructors
139 readability/fn_size 166 readability/fn_size
140 readability/function 167 readability/function
141 readability/multiline_comment 168 readability/multiline_comment
142 readability/multiline_string 169 readability/multiline_string
143 readability/streams 170 readability/streams
144 readability/todo 171 readability/todo
145 readability/utf8 172 readability/utf8
146 runtime/arrays 173 runtime/arrays
147 runtime/casting 174 runtime/casting
148 runtime/explicit 175 runtime/explicit
149 runtime/int 176 runtime/int
150 runtime/init 177 runtime/init
151 runtime/invalid_increment 178 runtime/invalid_increment
179 runtime/member_string_references
152 runtime/memset 180 runtime/memset
181 runtime/operator
153 runtime/printf 182 runtime/printf
154 runtime/printf_format 183 runtime/printf_format
155 runtime/references 184 runtime/references
156 runtime/rtti 185 runtime/rtti
157 runtime/sizeof 186 runtime/sizeof
158 runtime/string 187 runtime/string
159 runtime/threadsafe_fn 188 runtime/threadsafe_fn
160 runtime/virtual 189 runtime/virtual
161 whitespace/blank_line 190 whitespace/blank_line
162 whitespace/braces 191 whitespace/braces
163 whitespace/comma 192 whitespace/comma
164 whitespace/comments 193 whitespace/comments
165 whitespace/end_of_line 194 whitespace/end_of_line
166 whitespace/ending_newline 195 whitespace/ending_newline
167 whitespace/indent 196 whitespace/indent
168 whitespace/labels 197 whitespace/labels
169 whitespace/line_length 198 whitespace/line_length
170 whitespace/newline 199 whitespace/newline
171 whitespace/operators 200 whitespace/operators
172 whitespace/parens 201 whitespace/parens
173 whitespace/semicolon 202 whitespace/semicolon
174 whitespace/tab 203 whitespace/tab
175 whitespace/todo 204 whitespace/todo
176 ''' 205 '''
177 206
178 # The default state of the category filter. This is overrided by the --filter= 207 # The default state of the category filter. This is overrided by the --filter=
179 # flag. By default all errors are on, so only add here categories that should be 208 # flag. By default all errors are on, so only add here categories that should be
180 # off by default (i.e., categories that must be enabled by the --filter= flags). 209 # off by default (i.e., categories that must be enabled by the --filter= flags).
181 # All entries here should start with a '-' or '+', as in the --filter= flag. 210 # All entries here should start with a '-' or '+', as in the --filter= flag.
182 _DEFAULT_FILTERS = [] 211 _DEFAULT_FILTERS = [ '-build/include_alpha' ]
183 212
184 # We used to check for high-bit characters, but after much discussion we 213 # We used to check for high-bit characters, but after much discussion we
185 # decided those were OK, as long as they were in UTF-8 and didn't represent 214 # decided those were OK, as long as they were in UTF-8 and didn't represent
186 # hard-coded international strings, which belong in a seperate i18n file. 215 # hard-coded international strings, which belong in a seperate i18n file.
187 216
188 # Headers that we consider STL headers. 217 # Headers that we consider STL headers.
189 _STL_HEADERS = frozenset([ 218 _STL_HEADERS = frozenset([
190 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', 219 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
191 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', 220 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
192 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h', 221 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h',
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 _SECTION_NAMES = { 334 _SECTION_NAMES = {
306 _INITIAL_SECTION: "... nothing. (This can't be an error.)", 335 _INITIAL_SECTION: "... nothing. (This can't be an error.)",
307 _MY_H_SECTION: 'a header this file implements', 336 _MY_H_SECTION: 'a header this file implements',
308 _C_SECTION: 'C system header', 337 _C_SECTION: 'C system header',
309 _CPP_SECTION: 'C++ system header', 338 _CPP_SECTION: 'C++ system header',
310 _OTHER_H_SECTION: 'other header', 339 _OTHER_H_SECTION: 'other header',
311 } 340 }
312 341
313 def __init__(self): 342 def __init__(self):
314 dict.__init__(self) 343 dict.__init__(self)
344 # The name of the current section.
315 self._section = self._INITIAL_SECTION 345 self._section = self._INITIAL_SECTION
346 # The path of last found header.
347 self._last_header = ''
348
349 def CanonicalizeAlphabeticalOrder(self, header_path):
350 """Returns a path canonicalized for alphabetical comparisson.
351
352 - replaces "-" with "_" so they both cmp the same.
353 - removes '-inl' since we don't require them to be after the main header.
354 - lowercase everything, just in case.
355
356 Args:
357 header_path: Path to be canonicalized.
358
359 Returns:
360 Canonicalized path.
361 """
362 return header_path.replace('-inl.h', '.h').replace('-', '_').lower()
363
364 def IsInAlphabeticalOrder(self, header_path):
365 """Check if a header is in alphabetical order with the previous header.
366
367 Args:
368 header_path: Header to be checked.
369
370 Returns:
371 Returns true if the header is in alphabetical order.
372 """
373 canonical_header = self.CanonicalizeAlphabeticalOrder(header_path)
374 if self._last_header > canonical_header:
375 return False
376 self._last_header = canonical_header
377 return True
316 378
317 def CheckNextIncludeOrder(self, header_type): 379 def CheckNextIncludeOrder(self, header_type):
318 """Returns a non-empty error message if the next header is out of order. 380 """Returns a non-empty error message if the next header is out of order.
319 381
320 This function also updates the internal state to be ready to check 382 This function also updates the internal state to be ready to check
321 the next include. 383 the next include.
322 384
323 Args: 385 Args:
324 header_type: One of the _XXX_HEADER constants defined above. 386 header_type: One of the _XXX_HEADER constants defined above.
325 387
326 Returns: 388 Returns:
327 The empty string if the header is in the right order, or an 389 The empty string if the header is in the right order, or an
328 error message describing what's wrong. 390 error message describing what's wrong.
329 391
330 """ 392 """
331 error_message = ('Found %s after %s' % 393 error_message = ('Found %s after %s' %
332 (self._TYPE_NAMES[header_type], 394 (self._TYPE_NAMES[header_type],
333 self._SECTION_NAMES[self._section])) 395 self._SECTION_NAMES[self._section]))
334 396
397 last_section = self._section
398
335 if header_type == _C_SYS_HEADER: 399 if header_type == _C_SYS_HEADER:
336 if self._section <= self._C_SECTION: 400 if self._section <= self._C_SECTION:
337 self._section = self._C_SECTION 401 self._section = self._C_SECTION
338 else: 402 else:
403 self._last_header = ''
339 return error_message 404 return error_message
340 elif header_type == _CPP_SYS_HEADER: 405 elif header_type == _CPP_SYS_HEADER:
341 if self._section <= self._CPP_SECTION: 406 if self._section <= self._CPP_SECTION:
342 self._section = self._CPP_SECTION 407 self._section = self._CPP_SECTION
343 else: 408 else:
409 self._last_header = ''
344 return error_message 410 return error_message
345 elif header_type == _LIKELY_MY_HEADER: 411 elif header_type == _LIKELY_MY_HEADER:
346 if self._section <= self._MY_H_SECTION: 412 if self._section <= self._MY_H_SECTION:
347 self._section = self._MY_H_SECTION 413 self._section = self._MY_H_SECTION
348 else: 414 else:
349 self._section = self._OTHER_H_SECTION 415 self._section = self._OTHER_H_SECTION
350 elif header_type == _POSSIBLE_MY_HEADER: 416 elif header_type == _POSSIBLE_MY_HEADER:
351 if self._section <= self._MY_H_SECTION: 417 if self._section <= self._MY_H_SECTION:
352 self._section = self._MY_H_SECTION 418 self._section = self._MY_H_SECTION
353 else: 419 else:
354 # This will always be the fallback because we're not sure 420 # This will always be the fallback because we're not sure
355 # enough that the header is associated with this file. 421 # enough that the header is associated with this file.
356 self._section = self._OTHER_H_SECTION 422 self._section = self._OTHER_H_SECTION
357 else: 423 else:
358 assert header_type == _OTHER_HEADER 424 assert header_type == _OTHER_HEADER
359 self._section = self._OTHER_H_SECTION 425 self._section = self._OTHER_H_SECTION
360 426
427 if last_section != self._section:
428 self._last_header = ''
429
361 return '' 430 return ''
362 431
363 432
364 class _CppLintState(object): 433 class _CppLintState(object):
365 """Maintains module-wide state..""" 434 """Maintains module-wide state.."""
366 435
367 def __init__(self): 436 def __init__(self):
368 self.verbose_level = 1 # global setting. 437 self.verbose_level = 1 # global setting.
369 self.error_count = 0 # global count of reported errors 438 self.error_count = 0 # global count of reported errors
370 # filters to apply when emitting error messages 439 # filters to apply when emitting error messages
371 self.filters = _DEFAULT_FILTERS[:] 440 self.filters = _DEFAULT_FILTERS[:]
441 self.counting = 'total' # In what way are we counting errors?
442 self.errors_by_category = {} # string to int dict storing error counts
372 443
373 # output format: 444 # output format:
374 # "emacs" - format that emacs can parse (default) 445 # "emacs" - format that emacs can parse (default)
375 # "vs7" - format that Microsoft Visual Studio 7 can parse 446 # "vs7" - format that Microsoft Visual Studio 7 can parse
376 self.output_format = 'emacs' 447 self.output_format = 'emacs'
377 448
378 def SetOutputFormat(self, output_format): 449 def SetOutputFormat(self, output_format):
379 """Sets the output format for errors.""" 450 """Sets the output format for errors."""
380 self.output_format = output_format 451 self.output_format = output_format
381 452
382 def SetVerboseLevel(self, level): 453 def SetVerboseLevel(self, level):
383 """Sets the module's verbosity, and returns the previous setting.""" 454 """Sets the module's verbosity, and returns the previous setting."""
384 last_verbose_level = self.verbose_level 455 last_verbose_level = self.verbose_level
385 self.verbose_level = level 456 self.verbose_level = level
386 return last_verbose_level 457 return last_verbose_level
387 458
459 def SetCountingStyle(self, counting_style):
460 """Sets the module's counting options."""
461 self.counting = counting_style
462
388 def SetFilters(self, filters): 463 def SetFilters(self, filters):
389 """Sets the error-message filters. 464 """Sets the error-message filters.
390 465
391 These filters are applied when deciding whether to emit a given 466 These filters are applied when deciding whether to emit a given
392 error message. 467 error message.
393 468
394 Args: 469 Args:
395 filters: A string of comma-separated filters (eg "+whitespace/indent"). 470 filters: A string of comma-separated filters (eg "+whitespace/indent").
396 Each filter should start with + or -; else we die. 471 Each filter should start with + or -; else we die.
397 472
398 Raises: 473 Raises:
399 ValueError: The comma-separated filters did not all start with '+' or '-'. 474 ValueError: The comma-separated filters did not all start with '+' or '-'.
400 E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" 475 E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
401 """ 476 """
402 # Default filters always have less priority than the flag ones. 477 # Default filters always have less priority than the flag ones.
403 self.filters = _DEFAULT_FILTERS[:] 478 self.filters = _DEFAULT_FILTERS[:]
404 for filt in filters.split(','): 479 for filt in filters.split(','):
405 clean_filt = filt.strip() 480 clean_filt = filt.strip()
406 if clean_filt: 481 if clean_filt:
407 self.filters.append(clean_filt) 482 self.filters.append(clean_filt)
408 for filt in self.filters: 483 for filt in self.filters:
409 if not (filt.startswith('+') or filt.startswith('-')): 484 if not (filt.startswith('+') or filt.startswith('-')):
410 raise ValueError('Every filter in --filters must start with + or -' 485 raise ValueError('Every filter in --filters must start with + or -'
411 ' (%s does not)' % filt) 486 ' (%s does not)' % filt)
412 487
413 def ResetErrorCount(self): 488 def ResetErrorCounts(self):
414 """Sets the module's error statistic back to zero.""" 489 """Sets the module's error statistic back to zero."""
415 self.error_count = 0 490 self.error_count = 0
491 self.errors_by_category = {}
416 492
417 def IncrementErrorCount(self): 493 def IncrementErrorCount(self, category):
418 """Bumps the module's error statistic.""" 494 """Bumps the module's error statistic."""
419 self.error_count += 1 495 self.error_count += 1
496 if self.counting in ('toplevel', 'detailed'):
497 if self.counting != 'detailed':
498 category = category.split('/')[0]
499 if category not in self.errors_by_category:
500 self.errors_by_category[category] = 0
501 self.errors_by_category[category] += 1
420 502
503 def PrintErrorCounts(self):
504 """Print a summary of errors by category, and the total."""
505 for category, count in self.errors_by_category.iteritems():
506 sys.stderr.write('Category \'%s\' errors found: %d\n' %
507 (category, count))
508 sys.stderr.write('Total errors found: %d\n' % self.error_count)
421 509
422 _cpplint_state = _CppLintState() 510 _cpplint_state = _CppLintState()
423 511
424 512
425 def _OutputFormat(): 513 def _OutputFormat():
426 """Gets the module's output format.""" 514 """Gets the module's output format."""
427 return _cpplint_state.output_format 515 return _cpplint_state.output_format
428 516
429 517
430 def _SetOutputFormat(output_format): 518 def _SetOutputFormat(output_format):
431 """Sets the module's output format.""" 519 """Sets the module's output format."""
432 _cpplint_state.SetOutputFormat(output_format) 520 _cpplint_state.SetOutputFormat(output_format)
433 521
434 522
435 def _VerboseLevel(): 523 def _VerboseLevel():
436 """Returns the module's verbosity setting.""" 524 """Returns the module's verbosity setting."""
437 return _cpplint_state.verbose_level 525 return _cpplint_state.verbose_level
438 526
439 527
440 def _SetVerboseLevel(level): 528 def _SetVerboseLevel(level):
441 """Sets the module's verbosity, and returns the previous setting.""" 529 """Sets the module's verbosity, and returns the previous setting."""
442 return _cpplint_state.SetVerboseLevel(level) 530 return _cpplint_state.SetVerboseLevel(level)
443 531
444 532
533 def _SetCountingStyle(level):
534 """Sets the module's counting options."""
535 _cpplint_state.SetCountingStyle(level)
536
537
445 def _Filters(): 538 def _Filters():
446 """Returns the module's list of output filters, as a list.""" 539 """Returns the module's list of output filters, as a list."""
447 return _cpplint_state.filters 540 return _cpplint_state.filters
448 541
449 542
450 def _SetFilters(filters): 543 def _SetFilters(filters):
451 """Sets the module's error-message filters. 544 """Sets the module's error-message filters.
452 545
453 These filters are applied when deciding whether to emit a given 546 These filters are applied when deciding whether to emit a given
454 error message. 547 error message.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 falls under: "whitespace", say, or "runtime". Categories 736 falls under: "whitespace", say, or "runtime". Categories
644 may have a hierarchy separated by slashes: "whitespace/indent". 737 may have a hierarchy separated by slashes: "whitespace/indent".
645 confidence: A number from 1-5 representing a confidence score for 738 confidence: A number from 1-5 representing a confidence score for
646 the error, with 5 meaning that we are certain of the problem, 739 the error, with 5 meaning that we are certain of the problem,
647 and 1 meaning that it could be a legitimate construct. 740 and 1 meaning that it could be a legitimate construct.
648 message: The error message. 741 message: The error message.
649 """ 742 """
650 # There are two ways we might decide not to print an error message: 743 # There are two ways we might decide not to print an error message:
651 # the verbosity level isn't high enough, or the filters filter it out. 744 # the verbosity level isn't high enough, or the filters filter it out.
652 if _ShouldPrintError(category, confidence): 745 if _ShouldPrintError(category, confidence):
653 _cpplint_state.IncrementErrorCount() 746 _cpplint_state.IncrementErrorCount(category)
654 if _cpplint_state.output_format == 'vs7': 747 if _cpplint_state.output_format == 'vs7':
655 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( 748 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
656 filename, linenum, message, category, confidence)) 749 filename, linenum, message, category, confidence))
657 else: 750 else:
658 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( 751 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
659 filename, linenum, message, category, confidence)) 752 filename, linenum, message, category, confidence))
660 753
661 754
662 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. 755 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
663 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( 756 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 endif_linenum = linenum 999 endif_linenum = linenum
907 1000
908 if not ifndef or not define or ifndef != define: 1001 if not ifndef or not define or ifndef != define:
909 error(filename, 0, 'build/header_guard', 5, 1002 error(filename, 0, 'build/header_guard', 5,
910 'No #ifndef header guard found, suggested CPP variable is: %s' % 1003 'No #ifndef header guard found, suggested CPP variable is: %s' %
911 cppvar) 1004 cppvar)
912 return 1005 return
913 1006
914 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ 1007 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
915 # for backward compatibility. 1008 # for backward compatibility.
916 if ifndef != cppvar: 1009 if ifndef != cppvar and not Search(r'\bNOLINT\b', lines[ifndef_linenum]):
917 error_level = 0 1010 error_level = 0
918 if ifndef != cppvar + '_': 1011 if ifndef != cppvar + '_':
919 error_level = 5 1012 error_level = 5
920 1013
921 error(filename, ifndef_linenum, 'build/header_guard', error_level, 1014 error(filename, ifndef_linenum, 'build/header_guard', error_level,
922 '#ifndef header guard has wrong style, please use: %s' % cppvar) 1015 '#ifndef header guard has wrong style, please use: %s' % cppvar)
923 1016
924 if endif != ('#endif // %s' % cppvar): 1017 if (endif != ('#endif // %s' % cppvar) and
1018 not Search(r'\bNOLINT\b', lines[endif_linenum])):
925 error_level = 0 1019 error_level = 0
926 if endif != ('#endif // %s' % (cppvar + '_')): 1020 if endif != ('#endif // %s' % (cppvar + '_')):
927 error_level = 5 1021 error_level = 5
928 1022
929 error(filename, endif_linenum, 'build/header_guard', error_level, 1023 error(filename, endif_linenum, 'build/header_guard', error_level,
930 '#endif line should be "#endif // %s"' % cppvar) 1024 '#endif line should be "#endif // %s"' % cppvar)
931 1025
932 1026
933 def CheckForUnicodeReplacementCharacters(filename, lines, error): 1027 def CheckForUnicodeReplacementCharacters(filename, lines, error):
934 """Logs an error for each line containing Unicode replacement characters. 1028 """Logs an error for each line containing Unicode replacement characters.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 ix = line.find(single_thread_function) 1136 ix = line.find(single_thread_function)
1043 # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 1137 # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1044 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and 1138 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
1045 line[ix - 1] not in ('_', '.', '>'))): 1139 line[ix - 1] not in ('_', '.', '>'))):
1046 error(filename, linenum, 'runtime/threadsafe_fn', 2, 1140 error(filename, linenum, 'runtime/threadsafe_fn', 2,
1047 'Consider using ' + multithread_safe_function + 1141 'Consider using ' + multithread_safe_function +
1048 '...) instead of ' + single_thread_function + 1142 '...) instead of ' + single_thread_function +
1049 '...) for improved thread safety.') 1143 '...) for improved thread safety.')
1050 1144
1051 1145
1052 # Matches invalid increment: *count++, which moves pointer insead of 1146 # Matches invalid increment: *count++, which moves pointer instead of
1053 # incrementing a value. 1147 # incrementing a value.
1054 _RE_PATTERN_IVALID_INCREMENT = re.compile( 1148 _RE_PATTERN_INVALID_INCREMENT = re.compile(
1055 r'^\s*\*\w+(\+\+|--);') 1149 r'^\s*\*\w+(\+\+|--);')
1056 1150
1057 1151
1058 def CheckInvalidIncrement(filename, clean_lines, linenum, error): 1152 def CheckInvalidIncrement(filename, clean_lines, linenum, error):
1059 """Checks for invalud increment *count++. 1153 """Checks for invalid increment *count++.
1060 1154
1061 For example following function: 1155 For example following function:
1062 void increment_counter(int* count) { 1156 void increment_counter(int* count) {
1063 *count++; 1157 *count++;
1064 } 1158 }
1065 is invalid, because it effectively does count++, moving pointer, and should 1159 is invalid, because it effectively does count++, moving pointer, and should
1066 be replaced with ++*count, (*count)++ or *count += 1. 1160 be replaced with ++*count, (*count)++ or *count += 1.
1067 1161
1068 Args: 1162 Args:
1069 filename: The name of the current file. 1163 filename: The name of the current file.
1070 clean_lines: A CleansedLines instance containing the file. 1164 clean_lines: A CleansedLines instance containing the file.
1071 linenum: The number of the line to check. 1165 linenum: The number of the line to check.
1072 error: The function to call with any errors found. 1166 error: The function to call with any errors found.
1073 """ 1167 """
1074 line = clean_lines.elided[linenum] 1168 line = clean_lines.elided[linenum]
1075 if _RE_PATTERN_IVALID_INCREMENT.match(line): 1169 if _RE_PATTERN_INVALID_INCREMENT.match(line):
1076 error(filename, linenum, 'runtime/invalid_increment', 5, 1170 error(filename, linenum, 'runtime/invalid_increment', 5,
1077 'Changing pointer instead of value (or unused value of operator*).') 1171 'Changing pointer instead of value (or unused value of operator*).')
1078 1172
1079 1173
1080 class _ClassInfo(object): 1174 class _ClassInfo(object):
1081 """Stores information about a class.""" 1175 """Stores information about a class."""
1082 1176
1083 def __init__(self, name, linenum): 1177 def __init__(self, name, linenum):
1084 self.name = name 1178 self.name = name
1085 self.linenum = linenum 1179 self.linenum = linenum
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 - put storage class first (e.g. "static const" instead of "const static"). 1223 - put storage class first (e.g. "static const" instead of "const static").
1130 - "%lld" instead of %qd" in printf-type functions. 1224 - "%lld" instead of %qd" in printf-type functions.
1131 - "%1$d" is non-standard in printf-type functions. 1225 - "%1$d" is non-standard in printf-type functions.
1132 - "\%" is an undefined character escape sequence. 1226 - "\%" is an undefined character escape sequence.
1133 - text after #endif is not allowed. 1227 - text after #endif is not allowed.
1134 - invalid inner-style forward declaration. 1228 - invalid inner-style forward declaration.
1135 - >? and <? operators, and their >?= and <?= cousins. 1229 - >? and <? operators, and their >?= and <?= cousins.
1136 - classes with virtual methods need virtual destructors (compiler warning 1230 - classes with virtual methods need virtual destructors (compiler warning
1137 available, but not turned on yet.) 1231 available, but not turned on yet.)
1138 1232
1139 Additionally, check for constructor/destructor style violations as it 1233 Additionally, check for constructor/destructor style violations and reference
1140 is very convenient to do so while checking for gcc-2 compliance. 1234 members, as it is very convenient to do so while checking for
1235 gcc-2 compliance.
1141 1236
1142 Args: 1237 Args:
1143 filename: The name of the current file. 1238 filename: The name of the current file.
1144 clean_lines: A CleansedLines instance containing the file. 1239 clean_lines: A CleansedLines instance containing the file.
1145 linenum: The number of the line to check. 1240 linenum: The number of the line to check.
1146 class_state: A _ClassState instance which maintains information about 1241 class_state: A _ClassState instance which maintains information about
1147 the current stack of nested class declarations being parsed. 1242 the current stack of nested class declarations being parsed.
1148 error: A callable to which errors are reported, which takes 4 arguments: 1243 error: A callable to which errors are reported, which takes 4 arguments:
1149 filename, line number, error level, and message 1244 filename, line number, error level, and message
1150 """ 1245 """
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 1279
1185 if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line): 1280 if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
1186 error(filename, linenum, 'build/forward_decl', 5, 1281 error(filename, linenum, 'build/forward_decl', 5,
1187 'Inner-style forward declarations are invalid. Remove this line.') 1282 'Inner-style forward declarations are invalid. Remove this line.')
1188 1283
1189 if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', 1284 if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
1190 line): 1285 line):
1191 error(filename, linenum, 'build/deprecated', 3, 1286 error(filename, linenum, 'build/deprecated', 3,
1192 '>? and <? (max and min) operators are non-standard and deprecated.') 1287 '>? and <? (max and min) operators are non-standard and deprecated.')
1193 1288
1289 if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
1290 # TODO(unknown): Could it be expanded safely to arbitrary references,
1291 # without triggering too many false positives? The first
1292 # attempt triggered 5 warnings for mostly benign code in the regtest, hence
1293 # the restriction.
1294 # Here's the original regexp, for the reference:
1295 # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
1296 # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
1297 error(filename, linenum, 'runtime/member_string_references', 2,
1298 'const string& members are dangerous. It is much better to use '
1299 'alternatives, such as pointers or simple constants.')
1300
1194 # Track class entry and exit, and attempt to find cases within the 1301 # Track class entry and exit, and attempt to find cases within the
1195 # class declaration that don't meet the C++ style 1302 # class declaration that don't meet the C++ style
1196 # guidelines. Tracking is very dependent on the code matching Google 1303 # guidelines. Tracking is very dependent on the code matching Google
1197 # style guidelines, but it seems to perform well enough in testing 1304 # style guidelines, but it seems to perform well enough in testing
1198 # to be a worthwhile addition to the checks. 1305 # to be a worthwhile addition to the checks.
1199 classinfo_stack = class_state.classinfo_stack 1306 classinfo_stack = class_state.classinfo_stack
1200 # Look for a class declaration 1307 # Look for a class declaration
1201 class_decl_match = Match( 1308 class_decl_match = Match(
1202 r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line) 1309 r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line)
1203 if class_decl_match: 1310 if class_decl_match:
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
2124 # We classify each include statement as one of those 5 types 2231 # We classify each include statement as one of those 5 types
2125 # using a number of techniques. The include_state object keeps 2232 # using a number of techniques. The include_state object keeps
2126 # track of the highest type seen, and complains if we see a 2233 # track of the highest type seen, and complains if we see a
2127 # lower type after that. 2234 # lower type after that.
2128 error_message = include_state.CheckNextIncludeOrder( 2235 error_message = include_state.CheckNextIncludeOrder(
2129 _ClassifyInclude(fileinfo, include, is_system)) 2236 _ClassifyInclude(fileinfo, include, is_system))
2130 if error_message: 2237 if error_message:
2131 error(filename, linenum, 'build/include_order', 4, 2238 error(filename, linenum, 'build/include_order', 4,
2132 '%s. Should be: %s.h, c system, c++ system, other.' % 2239 '%s. Should be: %s.h, c system, c++ system, other.' %
2133 (error_message, fileinfo.BaseName())) 2240 (error_message, fileinfo.BaseName()))
2241 if not include_state.IsInAlphabeticalOrder(include):
2242 error(filename, linenum, 'build/include_alpha', 4,
2243 'Include "%s" not in alphabetical order' % include)
2134 2244
2135 # Look for any of the stream classes that are part of standard C++. 2245 # Look for any of the stream classes that are part of standard C++.
2136 match = _RE_PATTERN_INCLUDE.match(line) 2246 match = _RE_PATTERN_INCLUDE.match(line)
2137 if match: 2247 if match:
2138 include = match.group(2) 2248 include = match.group(2)
2139 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): 2249 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
2140 # Many unit tests use cout, so we exempt them. 2250 # Many unit tests use cout, so we exempt them.
2141 if not _IsTestFilename(filename): 2251 if not _IsTestFilename(filename):
2142 error(filename, linenum, 'readability/streams', 3, 2252 error(filename, linenum, 'readability/streams', 3,
2143 'Streams are highly discouraged.') 2253 'Streams are highly discouraged.')
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 fnline): 2312 fnline):
2203 error(filename, linenum, 'runtime/references', 2, 2313 error(filename, linenum, 'runtime/references', 2,
2204 'Is this a non-const reference? ' 2314 'Is this a non-const reference? '
2205 'If so, make const or use a pointer.') 2315 'If so, make const or use a pointer.')
2206 2316
2207 # Check to see if they're using an conversion function cast. 2317 # Check to see if they're using an conversion function cast.
2208 # I just try to capture the most common basic types, though there are more. 2318 # I just try to capture the most common basic types, though there are more.
2209 # Parameterless conversion functions, such as bool(), are allowed as they are 2319 # Parameterless conversion functions, such as bool(), are allowed as they are
2210 # probably a member operator declaration or default constructor. 2320 # probably a member operator declaration or default constructor.
2211 match = Search( 2321 match = Search(
2212 r'\b(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line) 2322 r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there
2323 r'(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
2213 if match: 2324 if match:
2214 # gMock methods are defined using some variant of MOCK_METHODx(name, type) 2325 # gMock methods are defined using some variant of MOCK_METHODx(name, type)
2215 # where type may be float(), int(string), etc. Without context they are 2326 # where type may be float(), int(string), etc. Without context they are
2216 # virtually indistinguishable from int(x) casts. 2327 # virtually indistinguishable from int(x) casts.
2217 if not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line): 2328 if (match.group(1) is None and # If new operator, then this isn't a cast
2329 not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line)):
2218 error(filename, linenum, 'readability/casting', 4, 2330 error(filename, linenum, 'readability/casting', 4,
2219 'Using deprecated casting style. ' 2331 'Using deprecated casting style. '
2220 'Use static_cast<%s>(...) instead' % 2332 'Use static_cast<%s>(...) instead' %
2221 match.group(1)) 2333 match.group(2))
2222 2334
2223 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 2335 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2224 'static_cast', 2336 'static_cast',
2225 r'\((int|float|double|bool|char|u?int(16|32|64))\)', 2337 r'\((int|float|double|bool|char|u?int(16|32|64))\)',
2226 error) 2338 error)
2227 # This doesn't catch all cases. Consider (const char * const)"hello". 2339 # This doesn't catch all cases. Consider (const char * const)"hello".
2228 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], 2340 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
2229 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) 2341 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
2230 2342
2231 # In addition, we look for people taking the address of a cast. This 2343 # In addition, we look for people taking the address of a cast. This
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2298 'Never use sprintf. Use snprintf instead.') 2410 'Never use sprintf. Use snprintf instead.')
2299 match = Search(r'\b(strcpy|strcat)\b', line) 2411 match = Search(r'\b(strcpy|strcat)\b', line)
2300 if match: 2412 if match:
2301 error(filename, linenum, 'runtime/printf', 4, 2413 error(filename, linenum, 'runtime/printf', 4,
2302 'Almost always, snprintf is better than %s' % match.group(1)) 2414 'Almost always, snprintf is better than %s' % match.group(1))
2303 2415
2304 if Search(r'\bsscanf\b', line): 2416 if Search(r'\bsscanf\b', line):
2305 error(filename, linenum, 'runtime/printf', 1, 2417 error(filename, linenum, 'runtime/printf', 1,
2306 'sscanf can be ok, but is slow and can overflow buffers.') 2418 'sscanf can be ok, but is slow and can overflow buffers.')
2307 2419
2420 # Check if some verboten operator overloading is going on
2421 # TODO(unknown): catch out-of-line unary operator&:
2422 # class X {};
2423 # int operator&(const X& x) { return 42; } // unary operator&
2424 # The trick is it's hard to tell apart from binary operator&:
2425 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
2426 if Search(r'\boperator\s*&\s*\(\s*\)', line):
2427 error(filename, linenum, 'runtime/operator', 4,
2428 'Unary operator& is dangerous. Do not use it.')
2429
2308 # Check for suspicious usage of "if" like 2430 # Check for suspicious usage of "if" like
2309 # } if (a == b) { 2431 # } if (a == b) {
2310 if Search(r'\}\s*if\s*\(', line): 2432 if Search(r'\}\s*if\s*\(', line):
2311 error(filename, linenum, 'readability/braces', 4, 2433 error(filename, linenum, 'readability/braces', 4,
2312 'Did you mean "else if"? If not, start a new line for "if".') 2434 'Did you mean "else if"? If not, start a new line for "if".')
2313 2435
2314 # Check for potential format string bugs like printf(foo). 2436 # Check for potential format string bugs like printf(foo).
2315 # We constrain the pattern not to pick things like DocidForPrintf(foo). 2437 # We constrain the pattern not to pick things like DocidForPrintf(foo).
2316 # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) 2438 # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
2317 match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I) 2439 match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I)
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2854 This may set the output format and verbosity level as side-effects. 2976 This may set the output format and verbosity level as side-effects.
2855 2977
2856 Args: 2978 Args:
2857 args: The command line arguments: 2979 args: The command line arguments:
2858 2980
2859 Returns: 2981 Returns:
2860 The list of filenames to lint. 2982 The list of filenames to lint.
2861 """ 2983 """
2862 try: 2984 try:
2863 (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', 2985 (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
2986 'counting=',
2864 'filter=']) 2987 'filter='])
2865 except getopt.GetoptError: 2988 except getopt.GetoptError:
2866 PrintUsage('Invalid arguments.') 2989 PrintUsage('Invalid arguments.')
2867 2990
2868 verbosity = _VerboseLevel() 2991 verbosity = _VerboseLevel()
2869 output_format = _OutputFormat() 2992 output_format = _OutputFormat()
2870 filters = '' 2993 filters = ''
2994 counting_style = ''
2871 2995
2872 for (opt, val) in opts: 2996 for (opt, val) in opts:
2873 if opt == '--help': 2997 if opt == '--help':
2874 PrintUsage(None) 2998 PrintUsage(None)
2875 elif opt == '--output': 2999 elif opt == '--output':
2876 if not val in ('emacs', 'vs7'): 3000 if not val in ('emacs', 'vs7'):
2877 PrintUsage('The only allowed output formats are emacs and vs7.') 3001 PrintUsage('The only allowed output formats are emacs and vs7.')
2878 output_format = val 3002 output_format = val
2879 elif opt == '--verbose': 3003 elif opt == '--verbose':
2880 verbosity = int(val) 3004 verbosity = int(val)
2881 elif opt == '--filter': 3005 elif opt == '--filter':
2882 filters = val 3006 filters = val
2883 if not filters: 3007 if not filters:
2884 PrintCategories() 3008 PrintCategories()
3009 elif opt == '--counting':
3010 if val not in ('total', 'toplevel', 'detailed'):
3011 PrintUsage('Valid counting options are total, toplevel, and detailed')
3012 counting_style = val
2885 3013
2886 if not filenames: 3014 if not filenames:
2887 PrintUsage('No files were specified.') 3015 PrintUsage('No files were specified.')
2888 3016
2889 _SetOutputFormat(output_format) 3017 _SetOutputFormat(output_format)
2890 _SetVerboseLevel(verbosity) 3018 _SetVerboseLevel(verbosity)
2891 _SetFilters(filters) 3019 _SetFilters(filters)
3020 _SetCountingStyle(counting_style)
2892 3021
2893 return filenames 3022 return filenames
2894 3023
2895 3024
2896 def main(): 3025 def main():
2897 filenames = ParseArguments(sys.argv[1:]) 3026 filenames = ParseArguments(sys.argv[1:])
2898 3027
2899 # Change stderr to write with replacement characters so we don't die 3028 # Change stderr to write with replacement characters so we don't die
2900 # if we try to print something containing non-ASCII characters. 3029 # if we try to print something containing non-ASCII characters.
2901 sys.stderr = codecs.StreamReaderWriter(sys.stderr, 3030 sys.stderr = codecs.StreamReaderWriter(sys.stderr,
2902 codecs.getreader('utf8'), 3031 codecs.getreader('utf8'),
2903 codecs.getwriter('utf8'), 3032 codecs.getwriter('utf8'),
2904 'replace') 3033 'replace')
2905 3034
2906 _cpplint_state.ResetErrorCount() 3035 _cpplint_state.ResetErrorCounts()
2907 for filename in filenames: 3036 for filename in filenames:
2908 ProcessFile(filename, _cpplint_state.verbose_level) 3037 ProcessFile(filename, _cpplint_state.verbose_level)
2909 sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count) 3038 _cpplint_state.PrintErrorCounts()
3039
2910 sys.exit(_cpplint_state.error_count > 0) 3040 sys.exit(_cpplint_state.error_count > 0)
2911 3041
2912 3042
2913 if __name__ == '__main__': 3043 if __name__ == '__main__':
2914 main() 3044 main()
OLDNEW
« no previous file with comments | « no previous file | presubmit_canned_checks.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698