1#!/usr/bin/env python 2# 3# Copyright (c) 2009 Google Inc. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: 8# 9# * Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above 12# copyright notice, this list of conditions and the following disclaimer 13# in the documentation and/or other materials provided with the 14# distribution. 15# * Neither the name of Google Inc. nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 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. 30 31"""Does google-lint on c++ files. 32 33The goal of this script is to identify places in the code that *may* 34be in non-compliance with google style. It does not attempt to fix 35up these problems -- the point is to educate. It does also not 36attempt to find all problems, or to ensure that everything it does 37find is legitimately a problem. 38 39In particular, we can get very confused by /* and // inside strings! 40We do a small hack, which is to ignore //'s with "'s after them on the 41same line, but it is far from perfect (in either direction). 42""" 43 44import codecs 45import copy 46import getopt 47import math # for log 48import os 49import re 50import sre_compile 51import string 52import sys 53import unicodedata 54 55 56_USAGE = """ 57Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] 58 [--counting=total|toplevel|detailed] [--root=subdir] 59 [--linelength=digits] [--headers=x,y,...] 60 [--quiet] 61 <file> [file] ... 62 63 The style guidelines this tries to follow are those in 64 https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml 65 66 Every problem is given a confidence score from 1-5, with 5 meaning we are 67 certain of the problem, and 1 meaning it could be a legitimate construct. 68 This will miss some errors, and is not a substitute for a code review. 69 70 To suppress false-positive errors of a certain category, add a 71 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) 72 suppresses errors of all categories on that line. 73 74 The files passed in will be linted; at least one file must be provided. 75 Default linted extensions are .cc, .cpp, .cu, .cuh and .h. Change the 76 extensions with the --extensions flag. 77 78 Flags: 79 80 output=vs7 81 By default, the output is formatted to ease emacs parsing. Visual Studio 82 compatible output (vs7) may also be used. Other formats are unsupported. 83 84 verbose=# 85 Specify a number 0-5 to restrict errors to certain verbosity levels. 86 87 quiet 88 Don't print anything if no errors are found. 89 90 filter=-x,+y,... 91 Specify a comma-separated list of category-filters to apply: only 92 error messages whose category names pass the filters will be printed. 93 (Category names are printed with the message and look like 94 "[whitespace/indent]".) Filters are evaluated left to right. 95 "-FOO" and "FOO" means "do not print categories that start with FOO". 96 "+FOO" means "do print categories that start with FOO". 97 98 Examples: --filter=-whitespace,+whitespace/braces 99 --filter=whitespace,runtime/printf,+runtime/printf_format 100 --filter=-,+build/include_what_you_use 101 102 To see a list of all the categories used in cpplint, pass no arg: 103 --filter= 104 105 counting=total|toplevel|detailed 106 The total number of errors found is always printed. If 107 'toplevel' is provided, then the count of errors in each of 108 the top-level categories like 'build' and 'whitespace' will 109 also be printed. If 'detailed' is provided, then a count 110 is provided for each category like 'build/class'. 111 112 root=subdir 113 The root directory used for deriving header guard CPP variable. 114 By default, the header guard CPP variable is calculated as the relative 115 path to the directory that contains .git, .hg, or .svn. When this flag 116 is specified, the relative path is calculated from the specified 117 directory. If the specified directory does not exist, this flag is 118 ignored. 119 120 Examples: 121 Assuming that top/src/.git exists (and cwd=top/src), the header guard 122 CPP variables for top/src/chrome/browser/ui/browser.h are: 123 124 No flag => CHROME_BROWSER_UI_BROWSER_H_ 125 --root=chrome => BROWSER_UI_BROWSER_H_ 126 --root=chrome/browser => UI_BROWSER_H_ 127 --root=.. => SRC_CHROME_BROWSER_UI_BROWSER_H_ 128 129 linelength=digits 130 This is the allowed line length for the project. The default value is 131 80 characters. 132 133 Examples: 134 --linelength=120 135 136 extensions=extension,extension,... 137 The allowed file extensions that cpplint will check 138 139 Examples: 140 --extensions=hpp,cpp 141 142 headers=x,y,... 143 The header extensions that cpplint will treat as .h in checks. Values are 144 automatically added to --extensions list. 145 146 Examples: 147 --headers=hpp,hxx 148 --headers=hpp 149 150 cpplint.py supports per-directory configurations specified in CPPLINT.cfg 151 files. CPPLINT.cfg file can contain a number of key=value pairs. 152 Currently the following options are supported: 153 154 set noparent 155 filter=+filter1,-filter2,... 156 exclude_files=regex 157 linelength=80 158 root=subdir 159 headers=x,y,... 160 161 "set noparent" option prevents cpplint from traversing directory tree 162 upwards looking for more .cfg files in parent directories. This option 163 is usually placed in the top-level project directory. 164 165 The "filter" option is similar in function to --filter flag. It specifies 166 message filters in addition to the |_DEFAULT_FILTERS| and those specified 167 through --filter command-line flag. 168 169 "exclude_files" allows to specify a regular expression to be matched against 170 a file name. If the expression matches, the file is skipped and not run 171 through liner. 172 173 "linelength" allows to specify the allowed line length for the project. 174 175 The "root" option is similar in function to the --root flag (see example 176 above). Paths are relative to the directory of the CPPLINT.cfg. 177 178 The "headers" option is similar in function to the --headers flag 179 (see example above). 180 181 CPPLINT.cfg has an effect on files in the same directory and all 182 sub-directories, unless overridden by a nested configuration file. 183 184 Example file: 185 filter=-build/include_order,+build/include_alpha 186 exclude_files=.*\.cc 187 188 The above example disables build/include_order warning and enables 189 build/include_alpha as well as excludes all .cc from being 190 processed by linter, in the current directory (where the .cfg 191 file is located) and all sub-directories. 192""" 193 194# We categorize each error message we print. Here are the categories. 195# We want an explicit list so we can list them all in cpplint --filter=. 196# If you add a new error message with a new category, add it to the list 197# here! cpplint_unittest.py should tell you if you forget to do this. 198_ERROR_CATEGORIES = [ 199 'build/class', 200 'build/c++11', 201 'build/c++14', 202 'build/c++tr1', 203 'build/deprecated', 204 'build/endif_comment', 205 'build/explicit_make_pair', 206 'build/forward_decl', 207 'build/header_guard', 208 'build/include', 209 'build/include_alpha', 210 'build/include_order', 211 'build/include_what_you_use', 212 'build/namespaces', 213 'build/printf_format', 214 'build/storage_class', 215 'legal/copyright', 216 'readability/alt_tokens', 217 'readability/braces', 218 'readability/casting', 219 'readability/check', 220 'readability/constructors', 221 'readability/fn_size', 222 'readability/inheritance', 223 'readability/multiline_comment', 224 'readability/multiline_string', 225 'readability/namespace', 226 'readability/nolint', 227 'readability/nul', 228 'readability/strings', 229 'readability/todo', 230 'readability/utf8', 231 'runtime/arrays', 232 'runtime/casting', 233 'runtime/explicit', 234 'runtime/int', 235 'runtime/init', 236 'runtime/invalid_increment', 237 'runtime/member_string_references', 238 'runtime/memset', 239 'runtime/indentation_namespace', 240 'runtime/operator', 241 'runtime/printf', 242 'runtime/printf_format', 243 'runtime/references', 244 'runtime/string', 245 'runtime/threadsafe_fn', 246 'runtime/vlog', 247 'whitespace/blank_line', 248 'whitespace/braces', 249 'whitespace/comma', 250 'whitespace/comments', 251 'whitespace/empty_conditional_body', 252 'whitespace/empty_if_body', 253 'whitespace/empty_loop_body', 254 'whitespace/end_of_line', 255 'whitespace/ending_newline', 256 'whitespace/forcolon', 257 'whitespace/indent', 258 'whitespace/line_length', 259 'whitespace/newline', 260 'whitespace/operators', 261 'whitespace/parens', 262 'whitespace/semicolon', 263 'whitespace/tab', 264 'whitespace/todo', 265 ] 266 267# These error categories are no longer enforced by cpplint, but for backwards- 268# compatibility they may still appear in NOLINT comments. 269_LEGACY_ERROR_CATEGORIES = [ 270 'readability/streams', 271 'readability/function', 272 ] 273 274# The default state of the category filter. This is overridden by the --filter= 275# flag. By default all errors are on, so only add here categories that should be 276# off by default (i.e., categories that must be enabled by the --filter= flags). 277# All entries here should start with a '-' or '+', as in the --filter= flag. 278_DEFAULT_FILTERS = ['-build/include_alpha'] 279 280# The default list of categories suppressed for C (not C++) files. 281_DEFAULT_C_SUPPRESSED_CATEGORIES = [ 282 'readability/casting', 283 ] 284 285# The default list of categories suppressed for Linux Kernel files. 286_DEFAULT_KERNEL_SUPPRESSED_CATEGORIES = [ 287 'whitespace/tab', 288 ] 289 290# We used to check for high-bit characters, but after much discussion we 291# decided those were OK, as long as they were in UTF-8 and didn't represent 292# hard-coded international strings, which belong in a separate i18n file. 293 294# C++ headers 295_CPP_HEADERS = frozenset([ 296 # Legacy 297 'algobase.h', 298 'algo.h', 299 'alloc.h', 300 'builtinbuf.h', 301 'bvector.h', 302 'complex.h', 303 'defalloc.h', 304 'deque.h', 305 'editbuf.h', 306 'fstream.h', 307 'function.h', 308 'hash_map', 309 'hash_map.h', 310 'hash_set', 311 'hash_set.h', 312 'hashtable.h', 313 'heap.h', 314 'indstream.h', 315 'iomanip.h', 316 'iostream.h', 317 'istream.h', 318 'iterator.h', 319 'list.h', 320 'map.h', 321 'multimap.h', 322 'multiset.h', 323 'ostream.h', 324 'pair.h', 325 'parsestream.h', 326 'pfstream.h', 327 'procbuf.h', 328 'pthread_alloc', 329 'pthread_alloc.h', 330 'rope', 331 'rope.h', 332 'ropeimpl.h', 333 'set.h', 334 'slist', 335 'slist.h', 336 'stack.h', 337 'stdiostream.h', 338 'stl_alloc.h', 339 'stl_relops.h', 340 'streambuf.h', 341 'stream.h', 342 'strfile.h', 343 'strstream.h', 344 'tempbuf.h', 345 'tree.h', 346 'type_traits.h', 347 'vector.h', 348 # 17.6.1.2 C++ library headers 349 'algorithm', 350 'array', 351 'atomic', 352 'bitset', 353 'chrono', 354 'codecvt', 355 'complex', 356 'condition_variable', 357 'deque', 358 'exception', 359 'forward_list', 360 'fstream', 361 'functional', 362 'future', 363 'initializer_list', 364 'iomanip', 365 'ios', 366 'iosfwd', 367 'iostream', 368 'istream', 369 'iterator', 370 'limits', 371 'list', 372 'locale', 373 'map', 374 'memory', 375 'mutex', 376 'new', 377 'numeric', 378 'ostream', 379 'queue', 380 'random', 381 'ratio', 382 'regex', 383 'scoped_allocator', 384 'set', 385 'sstream', 386 'stack', 387 'stdexcept', 388 'streambuf', 389 'string', 390 'strstream', 391 'system_error', 392 'thread', 393 'tuple', 394 'typeindex', 395 'typeinfo', 396 'type_traits', 397 'unordered_map', 398 'unordered_set', 399 'utility', 400 'valarray', 401 'vector', 402 # 17.6.1.2 C++ headers for C library facilities 403 'cassert', 404 'ccomplex', 405 'cctype', 406 'cerrno', 407 'cfenv', 408 'cfloat', 409 'cinttypes', 410 'ciso646', 411 'climits', 412 'clocale', 413 'cmath', 414 'csetjmp', 415 'csignal', 416 'cstdalign', 417 'cstdarg', 418 'cstdbool', 419 'cstddef', 420 'cstdint', 421 'cstdio', 422 'cstdlib', 423 'cstring', 424 'ctgmath', 425 'ctime', 426 'cuchar', 427 'cwchar', 428 'cwctype', 429 ]) 430 431# Type names 432_TYPES = re.compile( 433 r'^(?:' 434 # [dcl.type.simple] 435 r'(char(16_t|32_t)?)|wchar_t|' 436 r'bool|short|int|long|signed|unsigned|float|double|' 437 # [support.types] 438 r'(ptrdiff_t|size_t|max_align_t|nullptr_t)|' 439 # [cstdint.syn] 440 r'(u?int(_fast|_least)?(8|16|32|64)_t)|' 441 r'(u?int(max|ptr)_t)|' 442 r')$') 443 444 445# These headers are excluded from [build/include] and [build/include_order] 446# checks: 447# - Anything not following google file name conventions (containing an 448# uppercase character, such as Python.h or nsStringAPI.h, for example). 449# - Lua headers. 450_THIRD_PARTY_HEADERS_PATTERN = re.compile( 451 r'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$') 452 453# Pattern for matching FileInfo.BaseName() against test file name 454_TEST_FILE_SUFFIX = r'(_test|_unittest|_regtest)$' 455 456# Pattern that matches only complete whitespace, possibly across multiple lines. 457_EMPTY_CONDITIONAL_BODY_PATTERN = re.compile(r'^\s*$', re.DOTALL) 458 459# Assertion macros. These are defined in base/logging.h and 460# testing/base/public/gunit.h. 461_CHECK_MACROS = [ 462 'DCHECK', 'CHECK', 463 'EXPECT_TRUE', 'ASSERT_TRUE', 464 'EXPECT_FALSE', 'ASSERT_FALSE', 465 ] 466 467# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE 468_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) 469 470for op, replacement in [('==', 'EQ'), ('!=', 'NE'), 471 ('>=', 'GE'), ('>', 'GT'), 472 ('<=', 'LE'), ('<', 'LT')]: 473 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement 474 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement 475 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement 476 _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement 477 478for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), 479 ('>=', 'LT'), ('>', 'LE'), 480 ('<=', 'GT'), ('<', 'GE')]: 481 _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement 482 _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement 483 484# Alternative tokens and their replacements. For full list, see section 2.5 485# Alternative tokens [lex.digraph] in the C++ standard. 486# 487# Digraphs (such as '%:') are not included here since it's a mess to 488# match those on a word boundary. 489_ALT_TOKEN_REPLACEMENT = { 490 'and': '&&', 491 'bitor': '|', 492 'or': '||', 493 'xor': '^', 494 'compl': '~', 495 'bitand': '&', 496 'and_eq': '&=', 497 'or_eq': '|=', 498 'xor_eq': '^=', 499 'not': '!', 500 'not_eq': '!=' 501 } 502 503# Compile regular expression that matches all the above keywords. The "[ =()]" 504# bit is meant to avoid matching these keywords outside of boolean expressions. 505# 506# False positives include C-style multi-line comments and multi-line strings 507# but those have always been troublesome for cpplint. 508_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( 509 r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') 510 511 512# These constants define types of headers for use with 513# _IncludeState.CheckNextIncludeOrder(). 514_C_SYS_HEADER = 1 515_CPP_SYS_HEADER = 2 516_LIKELY_MY_HEADER = 3 517_POSSIBLE_MY_HEADER = 4 518_OTHER_HEADER = 5 519 520# These constants define the current inline assembly state 521_NO_ASM = 0 # Outside of inline assembly block 522_INSIDE_ASM = 1 # Inside inline assembly block 523_END_ASM = 2 # Last line of inline assembly block 524_BLOCK_ASM = 3 # The whole block is an inline assembly block 525 526# Match start of assembly blocks 527_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' 528 r'(?:\s+(volatile|__volatile__))?' 529 r'\s*[{(]') 530 531# Match strings that indicate we're working on a C (not C++) file. 532_SEARCH_C_FILE = re.compile(r'\b(?:LINT_C_FILE|' 533 r'vim?:\s*.*(\s*|:)filetype=c(\s*|:|$))') 534 535# Match string that indicates we're working on a Linux Kernel file. 536_SEARCH_KERNEL_FILE = re.compile(r'\b(?:LINT_KERNEL_FILE)') 537 538_regexp_compile_cache = {} 539 540# {str, set(int)}: a map from error categories to sets of linenumbers 541# on which those errors are expected and should be suppressed. 542_error_suppressions = {} 543 544# The root directory used for deriving header guard CPP variable. 545# This is set by --root flag. 546_root = None 547_root_debug = False 548 549# The allowed line length of files. 550# This is set by --linelength flag. 551_line_length = 80 552 553# The allowed extensions for file names 554# This is set by --extensions flag. 555_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) 556 557# Treat all headers starting with 'h' equally: .h, .hpp, .hxx etc. 558# This is set by --headers flag. 559_hpp_headers = set(['h']) 560 561# {str, bool}: a map from error categories to booleans which indicate if the 562# category should be suppressed for every line. 563_global_error_suppressions = {} 564 565def ProcessHppHeadersOption(val): 566 global _hpp_headers 567 try: 568 _hpp_headers = set(val.split(',')) 569 # Automatically append to extensions list so it does not have to be set 2 times 570 _valid_extensions.update(_hpp_headers) 571 except ValueError: 572 PrintUsage('Header extensions must be comma seperated list.') 573 574def IsHeaderExtension(file_extension): 575 return file_extension in _hpp_headers 576 577def ParseNolintSuppressions(filename, raw_line, linenum, error): 578 """Updates the global list of line error-suppressions. 579 580 Parses any NOLINT comments on the current line, updating the global 581 error_suppressions store. Reports an error if the NOLINT comment 582 was malformed. 583 584 Args: 585 filename: str, the name of the input file. 586 raw_line: str, the line of input text, with comments. 587 linenum: int, the number of the current line. 588 error: function, an error handler. 589 """ 590 matched = Search(r'\bNOLINT(NEXTLINE)?\b(\([^)]+\))?', raw_line) 591 if matched: 592 if matched.group(1): 593 suppressed_line = linenum + 1 594 else: 595 suppressed_line = linenum 596 category = matched.group(2) 597 if category in (None, '(*)'): # => "suppress all" 598 _error_suppressions.setdefault(None, set()).add(suppressed_line) 599 else: 600 if category.startswith('(') and category.endswith(')'): 601 category = category[1:-1] 602 if category in _ERROR_CATEGORIES: 603 _error_suppressions.setdefault(category, set()).add(suppressed_line) 604 elif category not in _LEGACY_ERROR_CATEGORIES: 605 error(filename, linenum, 'readability/nolint', 5, 606 'Unknown NOLINT error category: %s' % category) 607 608 609def ProcessGlobalSuppresions(lines): 610 """Updates the list of global error suppressions. 611 612 Parses any lint directives in the file that have global effect. 613 614 Args: 615 lines: An array of strings, each representing a line of the file, with the 616 last element being empty if the file is terminated with a newline. 617 """ 618 for line in lines: 619 if _SEARCH_C_FILE.search(line): 620 for category in _DEFAULT_C_SUPPRESSED_CATEGORIES: 621 _global_error_suppressions[category] = True 622 if _SEARCH_KERNEL_FILE.search(line): 623 for category in _DEFAULT_KERNEL_SUPPRESSED_CATEGORIES: 624 _global_error_suppressions[category] = True 625 626 627def ResetNolintSuppressions(): 628 """Resets the set of NOLINT suppressions to empty.""" 629 _error_suppressions.clear() 630 _global_error_suppressions.clear() 631 632 633def IsErrorSuppressedByNolint(category, linenum): 634 """Returns true if the specified error category is suppressed on this line. 635 636 Consults the global error_suppressions map populated by 637 ParseNolintSuppressions/ProcessGlobalSuppresions/ResetNolintSuppressions. 638 639 Args: 640 category: str, the category of the error. 641 linenum: int, the current line number. 642 Returns: 643 bool, True iff the error should be suppressed due to a NOLINT comment or 644 global suppression. 645 """ 646 return (_global_error_suppressions.get(category, False) or 647 linenum in _error_suppressions.get(category, set()) or 648 linenum in _error_suppressions.get(None, set())) 649 650 651def Match(pattern, s): 652 """Matches the string with the pattern, caching the compiled regexp.""" 653 # The regexp compilation caching is inlined in both Match and Search for 654 # performance reasons; factoring it out into a separate function turns out 655 # to be noticeably expensive. 656 if pattern not in _regexp_compile_cache: 657 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 658 return _regexp_compile_cache[pattern].match(s) 659 660 661def ReplaceAll(pattern, rep, s): 662 """Replaces instances of pattern in a string with a replacement. 663 664 The compiled regex is kept in a cache shared by Match and Search. 665 666 Args: 667 pattern: regex pattern 668 rep: replacement text 669 s: search string 670 671 Returns: 672 string with replacements made (or original string if no replacements) 673 """ 674 if pattern not in _regexp_compile_cache: 675 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 676 return _regexp_compile_cache[pattern].sub(rep, s) 677 678 679def Search(pattern, s): 680 """Searches the string for the pattern, caching the compiled regexp.""" 681 if pattern not in _regexp_compile_cache: 682 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 683 return _regexp_compile_cache[pattern].search(s) 684 685 686def _IsSourceExtension(s): 687 """File extension (excluding dot) matches a source file extension.""" 688 return s in ('c', 'cc', 'cpp', 'cxx') 689 690 691class _IncludeState(object): 692 """Tracks line numbers for includes, and the order in which includes appear. 693 694 include_list contains list of lists of (header, line number) pairs. 695 It's a lists of lists rather than just one flat list to make it 696 easier to update across preprocessor boundaries. 697 698 Call CheckNextIncludeOrder() once for each header in the file, passing 699 in the type constants defined above. Calls in an illegal order will 700 raise an _IncludeError with an appropriate error message. 701 702 """ 703 # self._section will move monotonically through this set. If it ever 704 # needs to move backwards, CheckNextIncludeOrder will raise an error. 705 _INITIAL_SECTION = 0 706 _MY_H_SECTION = 1 707 _C_SECTION = 2 708 _CPP_SECTION = 3 709 _OTHER_H_SECTION = 4 710 711 _TYPE_NAMES = { 712 _C_SYS_HEADER: 'C system header', 713 _CPP_SYS_HEADER: 'C++ system header', 714 _LIKELY_MY_HEADER: 'header this file implements', 715 _POSSIBLE_MY_HEADER: 'header this file may implement', 716 _OTHER_HEADER: 'other header', 717 } 718 _SECTION_NAMES = { 719 _INITIAL_SECTION: "... nothing. (This can't be an error.)", 720 _MY_H_SECTION: 'a header this file implements', 721 _C_SECTION: 'C system header', 722 _CPP_SECTION: 'C++ system header', 723 _OTHER_H_SECTION: 'other header', 724 } 725 726 def __init__(self): 727 self.include_list = [[]] 728 self.ResetSection('') 729 730 def FindHeader(self, header): 731 """Check if a header has already been included. 732 733 Args: 734 header: header to check. 735 Returns: 736 Line number of previous occurrence, or -1 if the header has not 737 been seen before. 738 """ 739 for section_list in self.include_list: 740 for f in section_list: 741 if f[0] == header: 742 return f[1] 743 return -1 744 745 def ResetSection(self, directive): 746 """Reset section checking for preprocessor directive. 747 748 Args: 749 directive: preprocessor directive (e.g. "if", "else"). 750 """ 751 # The name of the current section. 752 self._section = self._INITIAL_SECTION 753 # The path of last found header. 754 self._last_header = '' 755 756 # Update list of includes. Note that we never pop from the 757 # include list. 758 if directive in ('if', 'ifdef', 'ifndef'): 759 self.include_list.append([]) 760 elif directive in ('else', 'elif'): 761 self.include_list[-1] = [] 762 763 def SetLastHeader(self, header_path): 764 self._last_header = header_path 765 766 def CanonicalizeAlphabeticalOrder(self, header_path): 767 """Returns a path canonicalized for alphabetical comparison. 768 769 - replaces "-" with "_" so they both cmp the same. 770 - removes '-inl' since we don't require them to be after the main header. 771 - lowercase everything, just in case. 772 773 Args: 774 header_path: Path to be canonicalized. 775 776 Returns: 777 Canonicalized path. 778 """ 779 return header_path.replace('-inl.h', '.h').replace('-', '_').lower() 780 781 def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path): 782 """Check if a header is in alphabetical order with the previous header. 783 784 Args: 785 clean_lines: A CleansedLines instance containing the file. 786 linenum: The number of the line to check. 787 header_path: Canonicalized header to be checked. 788 789 Returns: 790 Returns true if the header is in alphabetical order. 791 """ 792 # If previous section is different from current section, _last_header will 793 # be reset to empty string, so it's always less than current header. 794 # 795 # If previous line was a blank line, assume that the headers are 796 # intentionally sorted the way they are. 797 if (self._last_header > header_path and 798 Match(r'^\s*#\s*include\b', clean_lines.elided[linenum - 1])): 799 return False 800 return True 801 802 def CheckNextIncludeOrder(self, header_type): 803 """Returns a non-empty error message if the next header is out of order. 804 805 This function also updates the internal state to be ready to check 806 the next include. 807 808 Args: 809 header_type: One of the _XXX_HEADER constants defined above. 810 811 Returns: 812 The empty string if the header is in the right order, or an 813 error message describing what's wrong. 814 815 """ 816 error_message = ('Found %s after %s' % 817 (self._TYPE_NAMES[header_type], 818 self._SECTION_NAMES[self._section])) 819 820 last_section = self._section 821 822 if header_type == _C_SYS_HEADER: 823 if self._section <= self._C_SECTION: 824 self._section = self._C_SECTION 825 else: 826 self._last_header = '' 827 return error_message 828 elif header_type == _CPP_SYS_HEADER: 829 if self._section <= self._CPP_SECTION: 830 self._section = self._CPP_SECTION 831 else: 832 self._last_header = '' 833 return error_message 834 elif header_type == _LIKELY_MY_HEADER: 835 if self._section <= self._MY_H_SECTION: 836 self._section = self._MY_H_SECTION 837 else: 838 self._section = self._OTHER_H_SECTION 839 elif header_type == _POSSIBLE_MY_HEADER: 840 if self._section <= self._MY_H_SECTION: 841 self._section = self._MY_H_SECTION 842 else: 843 # This will always be the fallback because we're not sure 844 # enough that the header is associated with this file. 845 self._section = self._OTHER_H_SECTION 846 else: 847 assert header_type == _OTHER_HEADER 848 self._section = self._OTHER_H_SECTION 849 850 if last_section != self._section: 851 self._last_header = '' 852 853 return '' 854 855 856class _CppLintState(object): 857 """Maintains module-wide state..""" 858 859 def __init__(self): 860 self.verbose_level = 1 # global setting. 861 self.error_count = 0 # global count of reported errors 862 # filters to apply when emitting error messages 863 self.filters = _DEFAULT_FILTERS[:] 864 # backup of filter list. Used to restore the state after each file. 865 self._filters_backup = self.filters[:] 866 self.counting = 'total' # In what way are we counting errors? 867 self.errors_by_category = {} # string to int dict storing error counts 868 self.quiet = False # Suppress non-error messagess? 869 870 # output format: 871 # "emacs" - format that emacs can parse (default) 872 # "vs7" - format that Microsoft Visual Studio 7 can parse 873 self.output_format = 'emacs' 874 875 def SetOutputFormat(self, output_format): 876 """Sets the output format for errors.""" 877 self.output_format = output_format 878 879 def SetQuiet(self, quiet): 880 """Sets the module's quiet settings, and returns the previous setting.""" 881 last_quiet = self.quiet 882 self.quiet = quiet 883 return last_quiet 884 885 def SetVerboseLevel(self, level): 886 """Sets the module's verbosity, and returns the previous setting.""" 887 last_verbose_level = self.verbose_level 888 self.verbose_level = level 889 return last_verbose_level 890 891 def SetCountingStyle(self, counting_style): 892 """Sets the module's counting options.""" 893 self.counting = counting_style 894 895 def SetFilters(self, filters): 896 """Sets the error-message filters. 897 898 These filters are applied when deciding whether to emit a given 899 error message. 900 901 Args: 902 filters: A string of comma-separated filters (eg "+whitespace/indent"). 903 Each filter should start with + or -; else we die. 904 905 Raises: 906 ValueError: The comma-separated filters did not all start with '+' or '-'. 907 E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" 908 """ 909 # Default filters always have less priority than the flag ones. 910 self.filters = _DEFAULT_FILTERS[:] 911 self.AddFilters(filters) 912 913 def AddFilters(self, filters): 914 """ Adds more filters to the existing list of error-message filters. """ 915 for filt in filters.split(','): 916 clean_filt = filt.strip() 917 if clean_filt: 918 self.filters.append(clean_filt) 919 for filt in self.filters: 920 if not (filt.startswith('+') or filt.startswith('-')): 921 raise ValueError('Every filter in --filters must start with + or -' 922 ' (%s does not)' % filt) 923 924 def BackupFilters(self): 925 """ Saves the current filter list to backup storage.""" 926 self._filters_backup = self.filters[:] 927 928 def RestoreFilters(self): 929 """ Restores filters previously backed up.""" 930 self.filters = self._filters_backup[:] 931 932 def ResetErrorCounts(self): 933 """Sets the module's error statistic back to zero.""" 934 self.error_count = 0 935 self.errors_by_category = {} 936 937 def IncrementErrorCount(self, category): 938 """Bumps the module's error statistic.""" 939 self.error_count += 1 940 if self.counting in ('toplevel', 'detailed'): 941 if self.counting != 'detailed': 942 category = category.split('/')[0] 943 if category not in self.errors_by_category: 944 self.errors_by_category[category] = 0 945 self.errors_by_category[category] += 1 946 947 def PrintErrorCounts(self): 948 """Print a summary of errors by category, and the total.""" 949 for category, count in self.errors_by_category.iteritems(): 950 sys.stderr.write('Category \'%s\' errors found: %d\n' % 951 (category, count)) 952 sys.stdout.write('Total errors found: %d\n' % self.error_count) 953 954_cpplint_state = _CppLintState() 955 956 957def _OutputFormat(): 958 """Gets the module's output format.""" 959 return _cpplint_state.output_format 960 961 962def _SetOutputFormat(output_format): 963 """Sets the module's output format.""" 964 _cpplint_state.SetOutputFormat(output_format) 965 966def _Quiet(): 967 """Return's the module's quiet setting.""" 968 return _cpplint_state.quiet 969 970def _SetQuiet(quiet): 971 """Set the module's quiet status, and return previous setting.""" 972 return _cpplint_state.SetQuiet(quiet) 973 974 975def _VerboseLevel(): 976 """Returns the module's verbosity setting.""" 977 return _cpplint_state.verbose_level 978 979 980def _SetVerboseLevel(level): 981 """Sets the module's verbosity, and returns the previous setting.""" 982 return _cpplint_state.SetVerboseLevel(level) 983 984 985def _SetCountingStyle(level): 986 """Sets the module's counting options.""" 987 _cpplint_state.SetCountingStyle(level) 988 989 990def _Filters(): 991 """Returns the module's list of output filters, as a list.""" 992 return _cpplint_state.filters 993 994 995def _SetFilters(filters): 996 """Sets the module's error-message filters. 997 998 These filters are applied when deciding whether to emit a given 999 error message. 1000 1001 Args: 1002 filters: A string of comma-separated filters (eg "whitespace/indent"). 1003 Each filter should start with + or -; else we die. 1004 """ 1005 _cpplint_state.SetFilters(filters) 1006 1007def _AddFilters(filters): 1008 """Adds more filter overrides. 1009 1010 Unlike _SetFilters, this function does not reset the current list of filters 1011 available. 1012 1013 Args: 1014 filters: A string of comma-separated filters (eg "whitespace/indent"). 1015 Each filter should start with + or -; else we die. 1016 """ 1017 _cpplint_state.AddFilters(filters) 1018 1019def _BackupFilters(): 1020 """ Saves the current filter list to backup storage.""" 1021 _cpplint_state.BackupFilters() 1022 1023def _RestoreFilters(): 1024 """ Restores filters previously backed up.""" 1025 _cpplint_state.RestoreFilters() 1026 1027class _FunctionState(object): 1028 """Tracks current function name and the number of lines in its body.""" 1029 1030 _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. 1031 _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. 1032 1033 def __init__(self): 1034 self.in_a_function = False 1035 self.lines_in_function = 0 1036 self.current_function = '' 1037 1038 def Begin(self, function_name): 1039 """Start analyzing function body. 1040 1041 Args: 1042 function_name: The name of the function being tracked. 1043 """ 1044 self.in_a_function = True 1045 self.lines_in_function = 0 1046 self.current_function = function_name 1047 1048 def Count(self): 1049 """Count line in current function body.""" 1050 if self.in_a_function: 1051 self.lines_in_function += 1 1052 1053 def Check(self, error, filename, linenum): 1054 """Report if too many lines in function body. 1055 1056 Args: 1057 error: The function to call with any errors found. 1058 filename: The name of the current file. 1059 linenum: The number of the line to check. 1060 """ 1061 if not self.in_a_function: 1062 return 1063 1064 if Match(r'T(EST|est)', self.current_function): 1065 base_trigger = self._TEST_TRIGGER 1066 else: 1067 base_trigger = self._NORMAL_TRIGGER 1068 trigger = base_trigger * 2**_VerboseLevel() 1069 1070 if self.lines_in_function > trigger: 1071 error_level = int(math.log(self.lines_in_function / base_trigger, 2)) 1072 # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... 1073 if error_level > 5: 1074 error_level = 5 1075 error(filename, linenum, 'readability/fn_size', error_level, 1076 'Small and focused functions are preferred:' 1077 ' %s has %d non-comment lines' 1078 ' (error triggered by exceeding %d lines).' % ( 1079 self.current_function, self.lines_in_function, trigger)) 1080 1081 def End(self): 1082 """Stop analyzing function body.""" 1083 self.in_a_function = False 1084 1085 1086class _IncludeError(Exception): 1087 """Indicates a problem with the include order in a file.""" 1088 pass 1089 1090 1091class FileInfo(object): 1092 """Provides utility functions for filenames. 1093 1094 FileInfo provides easy access to the components of a file's path 1095 relative to the project root. 1096 """ 1097 1098 def __init__(self, filename): 1099 self._filename = filename 1100 1101 def FullName(self): 1102 """Make Windows paths like Unix.""" 1103 return os.path.abspath(self._filename).replace('\\', '/') 1104 1105 def RepositoryName(self): 1106 """FullName after removing the local path to the repository. 1107 1108 If we have a real absolute path name here we can try to do something smart: 1109 detecting the root of the checkout and truncating /path/to/checkout from 1110 the name so that we get header guards that don't include things like 1111 "C:\Documents and Settings\..." or "/home/username/..." in them and thus 1112 people on different computers who have checked the source out to different 1113 locations won't see bogus errors. 1114 """ 1115 fullname = self.FullName() 1116 1117 if os.path.exists(fullname): 1118 project_dir = os.path.dirname(fullname) 1119 1120 if os.path.exists(os.path.join(project_dir, ".svn")): 1121 # If there's a .svn file in the current directory, we recursively look 1122 # up the directory tree for the top of the SVN checkout 1123 root_dir = project_dir 1124 one_up_dir = os.path.dirname(root_dir) 1125 while os.path.exists(os.path.join(one_up_dir, ".svn")): 1126 root_dir = os.path.dirname(root_dir) 1127 one_up_dir = os.path.dirname(one_up_dir) 1128 1129 prefix = os.path.commonprefix([root_dir, project_dir]) 1130 return fullname[len(prefix) + 1:] 1131 1132 # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by 1133 # searching up from the current path. 1134 root_dir = current_dir = os.path.dirname(fullname) 1135 while current_dir != os.path.dirname(current_dir): 1136 if (os.path.exists(os.path.join(current_dir, ".git")) or 1137 os.path.exists(os.path.join(current_dir, ".hg")) or 1138 os.path.exists(os.path.join(current_dir, ".svn"))): 1139 root_dir = current_dir 1140 current_dir = os.path.dirname(current_dir) 1141 1142 if (os.path.exists(os.path.join(root_dir, ".git")) or 1143 os.path.exists(os.path.join(root_dir, ".hg")) or 1144 os.path.exists(os.path.join(root_dir, ".svn"))): 1145 prefix = os.path.commonprefix([root_dir, project_dir]) 1146 return fullname[len(prefix) + 1:] 1147 1148 # Don't know what to do; header guard warnings may be wrong... 1149 return fullname 1150 1151 def Split(self): 1152 """Splits the file into the directory, basename, and extension. 1153 1154 For 'chrome/browser/browser.cc', Split() would 1155 return ('chrome/browser', 'browser', '.cc') 1156 1157 Returns: 1158 A tuple of (directory, basename, extension). 1159 """ 1160 1161 googlename = self.RepositoryName() 1162 project, rest = os.path.split(googlename) 1163 return (project,) + os.path.splitext(rest) 1164 1165 def BaseName(self): 1166 """File base name - text after the final slash, before the final period.""" 1167 return self.Split()[1] 1168 1169 def Extension(self): 1170 """File extension - text following the final period.""" 1171 return self.Split()[2] 1172 1173 def NoExtension(self): 1174 """File has no source file extension.""" 1175 return '/'.join(self.Split()[0:2]) 1176 1177 def IsSource(self): 1178 """File has a source file extension.""" 1179 return _IsSourceExtension(self.Extension()[1:]) 1180 1181 1182def _ShouldPrintError(category, confidence, linenum): 1183 """If confidence >= verbose, category passes filter and is not suppressed.""" 1184 1185 # There are three ways we might decide not to print an error message: 1186 # a "NOLINT(category)" comment appears in the source, 1187 # the verbosity level isn't high enough, or the filters filter it out. 1188 if IsErrorSuppressedByNolint(category, linenum): 1189 return False 1190 1191 if confidence < _cpplint_state.verbose_level: 1192 return False 1193 1194 is_filtered = False 1195 for one_filter in _Filters(): 1196 if one_filter.startswith('-'): 1197 if category.startswith(one_filter[1:]): 1198 is_filtered = True 1199 elif one_filter.startswith('+'): 1200 if category.startswith(one_filter[1:]): 1201 is_filtered = False 1202 else: 1203 assert False # should have been checked for in SetFilter. 1204 if is_filtered: 1205 return False 1206 1207 return True 1208 1209 1210def Error(filename, linenum, category, confidence, message): 1211 """Logs the fact we've found a lint error. 1212 1213 We log where the error was found, and also our confidence in the error, 1214 that is, how certain we are this is a legitimate style regression, and 1215 not a misidentification or a use that's sometimes justified. 1216 1217 False positives can be suppressed by the use of 1218 "cpplint(category)" comments on the offending line. These are 1219 parsed into _error_suppressions. 1220 1221 Args: 1222 filename: The name of the file containing the error. 1223 linenum: The number of the line containing the error. 1224 category: A string used to describe the "category" this bug 1225 falls under: "whitespace", say, or "runtime". Categories 1226 may have a hierarchy separated by slashes: "whitespace/indent". 1227 confidence: A number from 1-5 representing a confidence score for 1228 the error, with 5 meaning that we are certain of the problem, 1229 and 1 meaning that it could be a legitimate construct. 1230 message: The error message. 1231 """ 1232 if _ShouldPrintError(category, confidence, linenum): 1233 _cpplint_state.IncrementErrorCount(category) 1234 if _cpplint_state.output_format == 'vs7': 1235 sys.stderr.write('%s(%s): error cpplint: [%s] %s [%d]\n' % ( 1236 filename, linenum, category, message, confidence)) 1237 elif _cpplint_state.output_format == 'eclipse': 1238 sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( 1239 filename, linenum, message, category, confidence)) 1240 else: 1241 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( 1242 filename, linenum, message, category, confidence)) 1243 1244 1245# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard. 1246_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( 1247 r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') 1248# Match a single C style comment on the same line. 1249_RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/' 1250# Matches multi-line C style comments. 1251# This RE is a little bit more complicated than one might expect, because we 1252# have to take care of space removals tools so we can handle comments inside 1253# statements better. 1254# The current rule is: We only clear spaces from both sides when we're at the 1255# end of the line. Otherwise, we try to remove spaces from the right side, 1256# if this doesn't work we try on left side but only if there's a non-character 1257# on the right. 1258_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( 1259 r'(\s*' + _RE_PATTERN_C_COMMENTS + r'\s*$|' + 1260 _RE_PATTERN_C_COMMENTS + r'\s+|' + 1261 r'\s+' + _RE_PATTERN_C_COMMENTS + r'(?=\W)|' + 1262 _RE_PATTERN_C_COMMENTS + r')') 1263 1264 1265def IsCppString(line): 1266 """Does line terminate so, that the next symbol is in string constant. 1267 1268 This function does not consider single-line nor multi-line comments. 1269 1270 Args: 1271 line: is a partial line of code starting from the 0..n. 1272 1273 Returns: 1274 True, if next character appended to 'line' is inside a 1275 string constant. 1276 """ 1277 1278 line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" 1279 return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 1280 1281 1282def CleanseRawStrings(raw_lines): 1283 """Removes C++11 raw strings from lines. 1284 1285 Before: 1286 static const char kData[] = R"( 1287 multi-line string 1288 )"; 1289 1290 After: 1291 static const char kData[] = "" 1292 (replaced by blank line) 1293 ""; 1294 1295 Args: 1296 raw_lines: list of raw lines. 1297 1298 Returns: 1299 list of lines with C++11 raw strings replaced by empty strings. 1300 """ 1301 1302 delimiter = None 1303 lines_without_raw_strings = [] 1304 for line in raw_lines: 1305 if delimiter: 1306 # Inside a raw string, look for the end 1307 end = line.find(delimiter) 1308 if end >= 0: 1309 # Found the end of the string, match leading space for this 1310 # line and resume copying the original lines, and also insert 1311 # a "" on the last line. 1312 leading_space = Match(r'^(\s*)\S', line) 1313 line = leading_space.group(1) + '""' + line[end + len(delimiter):] 1314 delimiter = None 1315 else: 1316 # Haven't found the end yet, append a blank line. 1317 line = '""' 1318 1319 # Look for beginning of a raw string, and replace them with 1320 # empty strings. This is done in a loop to handle multiple raw 1321 # strings on the same line. 1322 while delimiter is None: 1323 # Look for beginning of a raw string. 1324 # See 2.14.15 [lex.string] for syntax. 1325 # 1326 # Once we have matched a raw string, we check the prefix of the 1327 # line to make sure that the line is not part of a single line 1328 # comment. It's done this way because we remove raw strings 1329 # before removing comments as opposed to removing comments 1330 # before removing raw strings. This is because there are some 1331 # cpplint checks that requires the comments to be preserved, but 1332 # we don't want to check comments that are inside raw strings. 1333 matched = Match(r'^(.*?)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) 1334 if (matched and 1335 not Match(r'^([^\'"]|\'(\\.|[^\'])*\'|"(\\.|[^"])*")*//', 1336 matched.group(1))): 1337 delimiter = ')' + matched.group(2) + '"' 1338 1339 end = matched.group(3).find(delimiter) 1340 if end >= 0: 1341 # Raw string ended on same line 1342 line = (matched.group(1) + '""' + 1343 matched.group(3)[end + len(delimiter):]) 1344 delimiter = None 1345 else: 1346 # Start of a multi-line raw string 1347 line = matched.group(1) + '""' 1348 else: 1349 break 1350 1351 lines_without_raw_strings.append(line) 1352 1353 # TODO(unknown): if delimiter is not None here, we might want to 1354 # emit a warning for unterminated string. 1355 return lines_without_raw_strings 1356 1357 1358def FindNextMultiLineCommentStart(lines, lineix): 1359 """Find the beginning marker for a multiline comment.""" 1360 while lineix < len(lines): 1361 if lines[lineix].strip().startswith('/*'): 1362 # Only return this marker if the comment goes beyond this line 1363 if lines[lineix].strip().find('*/', 2) < 0: 1364 return lineix 1365 lineix += 1 1366 return len(lines) 1367 1368 1369def FindNextMultiLineCommentEnd(lines, lineix): 1370 """We are inside a comment, find the end marker.""" 1371 while lineix < len(lines): 1372 if lines[lineix].strip().endswith('*/'): 1373 return lineix 1374 lineix += 1 1375 return len(lines) 1376 1377 1378def RemoveMultiLineCommentsFromRange(lines, begin, end): 1379 """Clears a range of lines for multi-line comments.""" 1380 # Having // dummy comments makes the lines non-empty, so we will not get 1381 # unnecessary blank line warnings later in the code. 1382 for i in range(begin, end): 1383 lines[i] = '/**/' 1384 1385 1386def RemoveMultiLineComments(filename, lines, error): 1387 """Removes multiline (c-style) comments from lines.""" 1388 lineix = 0 1389 while lineix < len(lines): 1390 lineix_begin = FindNextMultiLineCommentStart(lines, lineix) 1391 if lineix_begin >= len(lines): 1392 return 1393 lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) 1394 if lineix_end >= len(lines): 1395 error(filename, lineix_begin + 1, 'readability/multiline_comment', 5, 1396 'Could not find end of multi-line comment') 1397 return 1398 RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1) 1399 lineix = lineix_end + 1 1400 1401 1402def CleanseComments(line): 1403 """Removes //-comments and single-line C-style /* */ comments. 1404 1405 Args: 1406 line: A line of C++ source. 1407 1408 Returns: 1409 The line with single-line comments removed. 1410 """ 1411 commentpos = line.find('//') 1412 if commentpos != -1 and not IsCppString(line[:commentpos]): 1413 line = line[:commentpos].rstrip() 1414 # get rid of /* ... */ 1415 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) 1416 1417 1418class CleansedLines(object): 1419 """Holds 4 copies of all lines with different preprocessing applied to them. 1420 1421 1) elided member contains lines without strings and comments. 1422 2) lines member contains lines without comments. 1423 3) raw_lines member contains all the lines without processing. 1424 4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw 1425 strings removed. 1426 All these members are of <type 'list'>, and of the same length. 1427 """ 1428 1429 def __init__(self, lines): 1430 self.elided = [] 1431 self.lines = [] 1432 self.raw_lines = lines 1433 self.num_lines = len(lines) 1434 self.lines_without_raw_strings = CleanseRawStrings(lines) 1435 for linenum in range(len(self.lines_without_raw_strings)): 1436 self.lines.append(CleanseComments( 1437 self.lines_without_raw_strings[linenum])) 1438 elided = self._CollapseStrings(self.lines_without_raw_strings[linenum]) 1439 self.elided.append(CleanseComments(elided)) 1440 1441 def NumLines(self): 1442 """Returns the number of lines represented.""" 1443 return self.num_lines 1444 1445 @staticmethod 1446 def _CollapseStrings(elided): 1447 """Collapses strings and chars on a line to simple "" or '' blocks. 1448 1449 We nix strings first so we're not fooled by text like '"http://"' 1450 1451 Args: 1452 elided: The line being processed. 1453 1454 Returns: 1455 The line with collapsed strings. 1456 """ 1457 if _RE_PATTERN_INCLUDE.match(elided): 1458 return elided 1459 1460 # Remove escaped characters first to make quote/single quote collapsing 1461 # basic. Things that look like escaped characters shouldn't occur 1462 # outside of strings and chars. 1463 elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) 1464 1465 # Replace quoted strings and digit separators. Both single quotes 1466 # and double quotes are processed in the same loop, otherwise 1467 # nested quotes wouldn't work. 1468 collapsed = '' 1469 while True: 1470 # Find the first quote character 1471 match = Match(r'^([^\'"]*)([\'"])(.*)$', elided) 1472 if not match: 1473 collapsed += elided 1474 break 1475 head, quote, tail = match.groups() 1476 1477 if quote == '"': 1478 # Collapse double quoted strings 1479 second_quote = tail.find('"') 1480 if second_quote >= 0: 1481 collapsed += head + '""' 1482 elided = tail[second_quote + 1:] 1483 else: 1484 # Unmatched double quote, don't bother processing the rest 1485 # of the line since this is probably a multiline string. 1486 collapsed += elided 1487 break 1488 else: 1489 # Found single quote, check nearby text to eliminate digit separators. 1490 # 1491 # There is no special handling for floating point here, because 1492 # the integer/fractional/exponent parts would all be parsed 1493 # correctly as long as there are digits on both sides of the 1494 # separator. So we are fine as long as we don't see something 1495 # like "0.'3" (gcc 4.9.0 will not allow this literal). 1496 if Search(r'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$', head): 1497 match_literal = Match(r'^((?:\'?[0-9a-zA-Z_])*)(.*)$', "'" + tail) 1498 collapsed += head + match_literal.group(1).replace("'", '') 1499 elided = match_literal.group(2) 1500 else: 1501 second_quote = tail.find('\'') 1502 if second_quote >= 0: 1503 collapsed += head + "''" 1504 elided = tail[second_quote + 1:] 1505 else: 1506 # Unmatched single quote 1507 collapsed += elided 1508 break 1509 1510 return collapsed 1511 1512 1513def FindEndOfExpressionInLine(line, startpos, stack): 1514 """Find the position just after the end of current parenthesized expression. 1515 1516 Args: 1517 line: a CleansedLines line. 1518 startpos: start searching at this position. 1519 stack: nesting stack at startpos. 1520 1521 Returns: 1522 On finding matching end: (index just after matching end, None) 1523 On finding an unclosed expression: (-1, None) 1524 Otherwise: (-1, new stack at end of this line) 1525 """ 1526 for i in xrange(startpos, len(line)): 1527 char = line[i] 1528 if char in '([{': 1529 # Found start of parenthesized expression, push to expression stack 1530 stack.append(char) 1531 elif char == '<': 1532 # Found potential start of template argument list 1533 if i > 0 and line[i - 1] == '<': 1534 # Left shift operator 1535 if stack and stack[-1] == '<': 1536 stack.pop() 1537 if not stack: 1538 return (-1, None) 1539 elif i > 0 and Search(r'\boperator\s*$', line[0:i]): 1540 # operator<, don't add to stack 1541 continue 1542 else: 1543 # Tentative start of template argument list 1544 stack.append('<') 1545 elif char in ')]}': 1546 # Found end of parenthesized expression. 1547 # 1548 # If we are currently expecting a matching '>', the pending '<' 1549 # must have been an operator. Remove them from expression stack. 1550 while stack and stack[-1] == '<': 1551 stack.pop() 1552 if not stack: 1553 return (-1, None) 1554 if ((stack[-1] == '(' and char == ')') or 1555 (stack[-1] == '[' and char == ']') or 1556 (stack[-1] == '{' and char == '}')): 1557 stack.pop() 1558 if not stack: 1559 return (i + 1, None) 1560 else: 1561 # Mismatched parentheses 1562 return (-1, None) 1563 elif char == '>': 1564 # Found potential end of template argument list. 1565 1566 # Ignore "->" and operator functions 1567 if (i > 0 and 1568 (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))): 1569 continue 1570 1571 # Pop the stack if there is a matching '<'. Otherwise, ignore 1572 # this '>' since it must be an operator. 1573 if stack: 1574 if stack[-1] == '<': 1575 stack.pop() 1576 if not stack: 1577 return (i + 1, None) 1578 elif char == ';': 1579 # Found something that look like end of statements. If we are currently 1580 # expecting a '>', the matching '<' must have been an operator, since 1581 # template argument list should not contain statements. 1582 while stack and stack[-1] == '<': 1583 stack.pop() 1584 if not stack: 1585 return (-1, None) 1586 1587 # Did not find end of expression or unbalanced parentheses on this line 1588 return (-1, stack) 1589 1590 1591def CloseExpression(clean_lines, linenum, pos): 1592 """If input points to ( or { or [ or <, finds the position that closes it. 1593 1594 If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the 1595 linenum/pos that correspond to the closing of the expression. 1596 1597 TODO(unknown): cpplint spends a fair bit of time matching parentheses. 1598 Ideally we would want to index all opening and closing parentheses once 1599 and have CloseExpression be just a simple lookup, but due to preprocessor 1600 tricks, this is not so easy. 1601 1602 Args: 1603 clean_lines: A CleansedLines instance containing the file. 1604 linenum: The number of the line to check. 1605 pos: A position on the line. 1606 1607 Returns: 1608 A tuple (line, linenum, pos) pointer *past* the closing brace, or 1609 (line, len(lines), -1) if we never find a close. Note we ignore 1610 strings and comments when matching; and the line we return is the 1611 'cleansed' line at linenum. 1612 """ 1613 1614 line = clean_lines.elided[linenum] 1615 if (line[pos] not in '({[<') or Match(r'<[<=]', line[pos:]): 1616 return (line, clean_lines.NumLines(), -1) 1617 1618 # Check first line 1619 (end_pos, stack) = FindEndOfExpressionInLine(line, pos, []) 1620 if end_pos > -1: 1621 return (line, linenum, end_pos) 1622 1623 # Continue scanning forward 1624 while stack and linenum < clean_lines.NumLines() - 1: 1625 linenum += 1 1626 line = clean_lines.elided[linenum] 1627 (end_pos, stack) = FindEndOfExpressionInLine(line, 0, stack) 1628 if end_pos > -1: 1629 return (line, linenum, end_pos) 1630 1631 # Did not find end of expression before end of file, give up 1632 return (line, clean_lines.NumLines(), -1) 1633 1634 1635def FindStartOfExpressionInLine(line, endpos, stack): 1636 """Find position at the matching start of current expression. 1637 1638 This is almost the reverse of FindEndOfExpressionInLine, but note 1639 that the input position and returned position differs by 1. 1640 1641 Args: 1642 line: a CleansedLines line. 1643 endpos: start searching at this position. 1644 stack: nesting stack at endpos. 1645 1646 Returns: 1647 On finding matching start: (index at matching start, None) 1648 On finding an unclosed expression: (-1, None) 1649 Otherwise: (-1, new stack at beginning of this line) 1650 """ 1651 i = endpos 1652 while i >= 0: 1653 char = line[i] 1654 if char in ')]}': 1655 # Found end of expression, push to expression stack 1656 stack.append(char) 1657 elif char == '>': 1658 # Found potential end of template argument list. 1659 # 1660 # Ignore it if it's a "->" or ">=" or "operator>" 1661 if (i > 0 and 1662 (line[i - 1] == '-' or 1663 Match(r'\s>=\s', line[i - 1:]) or 1664 Search(r'\boperator\s*$', line[0:i]))): 1665 i -= 1 1666 else: 1667 stack.append('>') 1668 elif char == '<': 1669 # Found potential start of template argument list 1670 if i > 0 and line[i - 1] == '<': 1671 # Left shift operator 1672 i -= 1 1673 else: 1674 # If there is a matching '>', we can pop the expression stack. 1675 # Otherwise, ignore this '<' since it must be an operator. 1676 if stack and stack[-1] == '>': 1677 stack.pop() 1678 if not stack: 1679 return (i, None) 1680 elif char in '([{': 1681 # Found start of expression. 1682 # 1683 # If there are any unmatched '>' on the stack, they must be 1684 # operators. Remove those. 1685 while stack and stack[-1] == '>': 1686 stack.pop() 1687 if not stack: 1688 return (-1, None) 1689 if ((char == '(' and stack[-1] == ')') or 1690 (char == '[' and stack[-1] == ']') or 1691 (char == '{' and stack[-1] == '}')): 1692 stack.pop() 1693 if not stack: 1694 return (i, None) 1695 else: 1696 # Mismatched parentheses 1697 return (-1, None) 1698 elif char == ';': 1699 # Found something that look like end of statements. If we are currently 1700 # expecting a '<', the matching '>' must have been an operator, since 1701 # template argument list should not contain statements. 1702 while stack and stack[-1] == '>': 1703 stack.pop() 1704 if not stack: 1705 return (-1, None) 1706 1707 i -= 1 1708 1709 return (-1, stack) 1710 1711 1712def ReverseCloseExpression(clean_lines, linenum, pos): 1713 """If input points to ) or } or ] or >, finds the position that opens it. 1714 1715 If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the 1716 linenum/pos that correspond to the opening of the expression. 1717 1718 Args: 1719 clean_lines: A CleansedLines instance containing the file. 1720 linenum: The number of the line to check. 1721 pos: A position on the line. 1722 1723 Returns: 1724 A tuple (line, linenum, pos) pointer *at* the opening brace, or 1725 (line, 0, -1) if we never find the matching opening brace. Note 1726 we ignore strings and comments when matching; and the line we 1727 return is the 'cleansed' line at linenum. 1728 """ 1729 line = clean_lines.elided[linenum] 1730 if line[pos] not in ')}]>': 1731 return (line, 0, -1) 1732 1733 # Check last line 1734 (start_pos, stack) = FindStartOfExpressionInLine(line, pos, []) 1735 if start_pos > -1: 1736 return (line, linenum, start_pos) 1737 1738 # Continue scanning backward 1739 while stack and linenum > 0: 1740 linenum -= 1 1741 line = clean_lines.elided[linenum] 1742 (start_pos, stack) = FindStartOfExpressionInLine(line, len(line) - 1, stack) 1743 if start_pos > -1: 1744 return (line, linenum, start_pos) 1745 1746 # Did not find start of expression before beginning of file, give up 1747 return (line, 0, -1) 1748 1749 1750def CheckForCopyright(filename, lines, error): 1751 """Logs an error if no Copyright message appears at the top of the file.""" 1752 1753 # We'll say it should occur by line 10. Don't forget there's a 1754 # dummy line at the front. 1755 for line in xrange(1, min(len(lines), 11)): 1756 if re.search(r'Copyright', lines[line], re.I): break 1757 else: # means no copyright line was found 1758 error(filename, 0, 'legal/copyright', 5, 1759 'No copyright message found. ' 1760 'You should have a line: "Copyright [year] <Copyright Owner>"') 1761 1762 1763def GetIndentLevel(line): 1764 """Return the number of leading spaces in line. 1765 1766 Args: 1767 line: A string to check. 1768 1769 Returns: 1770 An integer count of leading spaces, possibly zero. 1771 """ 1772 indent = Match(r'^( *)\S', line) 1773 if indent: 1774 return len(indent.group(1)) 1775 else: 1776 return 0 1777 1778def PathSplitToList(path): 1779 """Returns the path split into a list by the separator. 1780 1781 Args: 1782 path: An absolute or relative path (e.g. '/a/b/c/' or '../a') 1783 1784 Returns: 1785 A list of path components (e.g. ['a', 'b', 'c]). 1786 """ 1787 lst = [] 1788 while True: 1789 (head, tail) = os.path.split(path) 1790 if head == path: # absolute paths end 1791 lst.append(head) 1792 break 1793 if tail == path: # relative paths end 1794 lst.append(tail) 1795 break 1796 1797 path = head 1798 lst.append(tail) 1799 1800 lst.reverse() 1801 return lst 1802 1803def GetHeaderGuardCPPVariable(filename): 1804 """Returns the CPP variable that should be used as a header guard. 1805 1806 Args: 1807 filename: The name of a C++ header file. 1808 1809 Returns: 1810 The CPP variable that should be used as a header guard in the 1811 named file. 1812 1813 """ 1814 1815 # Restores original filename in case that cpplint is invoked from Emacs's 1816 # flymake. 1817 filename = re.sub(r'_flymake\.h$', '.h', filename) 1818 filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) 1819 # Replace 'c++' with 'cpp'. 1820 filename = filename.replace('C++', 'cpp').replace('c++', 'cpp') 1821 1822 fileinfo = FileInfo(filename) 1823 file_path_from_root = fileinfo.RepositoryName() 1824 1825 def FixupPathFromRoot(): 1826 if _root_debug: 1827 sys.stderr.write("\n_root fixup, _root = '%s', repository name = '%s'\n" 1828 %(_root, fileinfo.RepositoryName())) 1829 1830 # Process the file path with the --root flag if it was set. 1831 if not _root: 1832 if _root_debug: 1833 sys.stderr.write("_root unspecified\n") 1834 return file_path_from_root 1835 1836 def StripListPrefix(lst, prefix): 1837 # f(['x', 'y'], ['w, z']) -> None (not a valid prefix) 1838 if lst[:len(prefix)] != prefix: 1839 return None 1840 # f(['a, 'b', 'c', 'd'], ['a', 'b']) -> ['c', 'd'] 1841 return lst[(len(prefix)):] 1842 1843 # root behavior: 1844 # --root=subdir , lstrips subdir from the header guard 1845 maybe_path = StripListPrefix(PathSplitToList(file_path_from_root), 1846 PathSplitToList(_root)) 1847 1848 if _root_debug: 1849 sys.stderr.write("_root lstrip (maybe_path=%s, file_path_from_root=%s," + 1850 " _root=%s)\n" %(maybe_path, file_path_from_root, _root)) 1851 1852 if maybe_path: 1853 return os.path.join(*maybe_path) 1854 1855 # --root=.. , will prepend the outer directory to the header guard 1856 full_path = fileinfo.FullName() 1857 root_abspath = os.path.abspath(_root) 1858 1859 maybe_path = StripListPrefix(PathSplitToList(full_path), 1860 PathSplitToList(root_abspath)) 1861 1862 if _root_debug: 1863 sys.stderr.write("_root prepend (maybe_path=%s, full_path=%s, " + 1864 "root_abspath=%s)\n" %(maybe_path, full_path, root_abspath)) 1865 1866 if maybe_path: 1867 return os.path.join(*maybe_path) 1868 1869 if _root_debug: 1870 sys.stderr.write("_root ignore, returning %s\n" %(file_path_from_root)) 1871 1872 # --root=FAKE_DIR is ignored 1873 return file_path_from_root 1874 1875 file_path_from_root = FixupPathFromRoot() 1876 return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_' 1877 1878 1879def CheckForHeaderGuard(filename, clean_lines, error): 1880 """Checks that the file contains a header guard. 1881 1882 Logs an error if no #ifndef header guard is present. For other 1883 headers, checks that the full pathname is used. 1884 1885 Args: 1886 filename: The name of the C++ header file. 1887 clean_lines: A CleansedLines instance containing the file. 1888 error: The function to call with any errors found. 1889 """ 1890 1891 # Don't check for header guards if there are error suppression 1892 # comments somewhere in this file. 1893 # 1894 # Because this is silencing a warning for a nonexistent line, we 1895 # only support the very specific NOLINT(build/header_guard) syntax, 1896 # and not the general NOLINT or NOLINT(*) syntax. 1897 raw_lines = clean_lines.lines_without_raw_strings 1898 for i in raw_lines: 1899 if Search(r'//\s*NOLINT\(build/header_guard\)', i): 1900 return 1901 1902 cppvar = GetHeaderGuardCPPVariable(filename) 1903 1904 ifndef = '' 1905 ifndef_linenum = 0 1906 define = '' 1907 endif = '' 1908 endif_linenum = 0 1909 for linenum, line in enumerate(raw_lines): 1910 linesplit = line.split() 1911 if len(linesplit) >= 2: 1912 # find the first occurrence of #ifndef and #define, save arg 1913 if not ifndef and linesplit[0] == '#ifndef': 1914 # set ifndef to the header guard presented on the #ifndef line. 1915 ifndef = linesplit[1] 1916 ifndef_linenum = linenum 1917 if not define and linesplit[0] == '#define': 1918 define = linesplit[1] 1919 # find the last occurrence of #endif, save entire line 1920 if line.startswith('#endif'): 1921 endif = line 1922 endif_linenum = linenum 1923 1924 if not ifndef or not define or ifndef != define: 1925 error(filename, 0, 'build/header_guard', 5, 1926 'No #ifndef header guard found, suggested CPP variable is: %s' % 1927 cppvar) 1928 return 1929 1930 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ 1931 # for backward compatibility. 1932 if ifndef != cppvar: 1933 error_level = 0 1934 if ifndef != cppvar + '_': 1935 error_level = 5 1936 1937 ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum, 1938 error) 1939 error(filename, ifndef_linenum, 'build/header_guard', error_level, 1940 '#ifndef header guard has wrong style, please use: %s' % cppvar) 1941 1942 # Check for "//" comments on endif line. 1943 # ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum, 1944 # error) 1945 # match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif) 1946 # if match: 1947 # if match.group(1) == '_': 1948 # # Issue low severity warning for deprecated double trailing underscore 1949 # error(filename, endif_linenum, 'build/header_guard', 0, 1950 # '#endif line should be "#endif // %s"' % cppvar) 1951 # return 1952 1953 # Didn't find the corresponding "//" comment. If this file does not 1954 # contain any "//" comments at all, it could be that the compiler 1955 # only wants "/**/" comments, look for those instead. 1956 # no_single_line_comments = True 1957 # for i in xrange(1, len(raw_lines) - 1): 1958 # line = raw_lines[i] 1959 # if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): 1960 # no_single_line_comments = False 1961 # break 1962 1963 # if no_single_line_comments: 1964 # match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif) 1965 # if match: 1966 # if match.group(1) == '_': 1967 # # Low severity warning for double trailing underscore 1968 # error(filename, endif_linenum, 'build/header_guard', 0, 1969 # '#endif line should be "#endif /* %s */"' % cppvar) 1970 # return 1971 1972 # # Didn't find anything 1973 # error(filename, endif_linenum, 'build/header_guard', 5, 1974 # '#endif line should be "#endif // %s"' % cppvar) 1975 1976 1977def CheckHeaderFileIncluded(filename, include_state, error): 1978 """Logs an error if a .cc file does not include its header.""" 1979 1980 # Do not check test files 1981 fileinfo = FileInfo(filename) 1982 if Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()): 1983 return 1984 1985 headerfile = filename[0:len(filename) - len(fileinfo.Extension())] + '.h' 1986 if not os.path.exists(headerfile): 1987 return 1988 headername = FileInfo(headerfile).RepositoryName() 1989 first_include = 0 1990 for section_list in include_state.include_list: 1991 for f in section_list: 1992 if headername in f[0] or f[0] in headername: 1993 return 1994 if not first_include: 1995 first_include = f[1] 1996 1997 error(filename, first_include, 'build/include', 5, 1998 '%s should include its header file %s' % (fileinfo.RepositoryName(), 1999 headername)) 2000 2001 2002def CheckForBadCharacters(filename, lines, error): 2003 """Logs an error for each line containing bad characters. 2004 2005 Two kinds of bad characters: 2006 2007 1. Unicode replacement characters: These indicate that either the file 2008 contained invalid UTF-8 (likely) or Unicode replacement characters (which 2009 it shouldn't). Note that it's possible for this to throw off line 2010 numbering if the invalid UTF-8 occurred adjacent to a newline. 2011 2012 2. NUL bytes. These are problematic for some tools. 2013 2014 Args: 2015 filename: The name of the current file. 2016 lines: An array of strings, each representing a line of the file. 2017 error: The function to call with any errors found. 2018 """ 2019 for linenum, line in enumerate(lines): 2020 if u'\ufffd' in line: 2021 error(filename, linenum, 'readability/utf8', 5, 2022 'Line contains invalid UTF-8 (or Unicode replacement character).') 2023 if '\0' in line: 2024 error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.') 2025 2026 2027def CheckForNewlineAtEOF(filename, lines, error): 2028 """Logs an error if there is no newline char at the end of the file. 2029 2030 Args: 2031 filename: The name of the current file. 2032 lines: An array of strings, each representing a line of the file. 2033 error: The function to call with any errors found. 2034 """ 2035 2036 # The array lines() was created by adding two newlines to the 2037 # original file (go figure), then splitting on \n. 2038 # To verify that the file ends in \n, we just have to make sure the 2039 # last-but-two element of lines() exists and is empty. 2040 if len(lines) < 3 or lines[-2]: 2041 error(filename, len(lines) - 2, 'whitespace/ending_newline', 5, 2042 'Could not find a newline character at the end of the file.') 2043 2044 2045def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error): 2046 """Logs an error if we see /* ... */ or "..." that extend past one line. 2047 2048 /* ... */ comments are legit inside macros, for one line. 2049 Otherwise, we prefer // comments, so it's ok to warn about the 2050 other. Likewise, it's ok for strings to extend across multiple 2051 lines, as long as a line continuation character (backslash) 2052 terminates each line. Although not currently prohibited by the C++ 2053 style guide, it's ugly and unnecessary. We don't do well with either 2054 in this lint program, so we warn about both. 2055 2056 Args: 2057 filename: The name of the current file. 2058 clean_lines: A CleansedLines instance containing the file. 2059 linenum: The number of the line to check. 2060 error: The function to call with any errors found. 2061 """ 2062 line = clean_lines.elided[linenum] 2063 2064 # Remove all \\ (escaped backslashes) from the line. They are OK, and the 2065 # second (escaped) slash may trigger later \" detection erroneously. 2066 line = line.replace('\\\\', '') 2067 2068 if line.count('/*') > line.count('*/'): 2069 error(filename, linenum, 'readability/multiline_comment', 5, 2070 'Complex multi-line /*...*/-style comment found. ' 2071 'Lint may give bogus warnings. ' 2072 'Consider replacing these with //-style comments, ' 2073 'with #if 0...#endif, ' 2074 'or with more clearly structured multi-line comments.') 2075 2076 if (line.count('"') - line.count('\\"')) % 2: 2077 error(filename, linenum, 'readability/multiline_string', 5, 2078 'Multi-line string ("...") found. This lint script doesn\'t ' 2079 'do well with such strings, and may give bogus warnings. ' 2080 'Use C++11 raw strings or concatenation instead.') 2081 2082 2083# (non-threadsafe name, thread-safe alternative, validation pattern) 2084# 2085# The validation pattern is used to eliminate false positives such as: 2086# _rand(); // false positive due to substring match. 2087# ->rand(); // some member function rand(). 2088# ACMRandom rand(seed); // some variable named rand. 2089# ISAACRandom rand(); // another variable named rand. 2090# 2091# Basically we require the return value of these functions to be used 2092# in some expression context on the same line by matching on some 2093# operator before the function name. This eliminates constructors and 2094# member function calls. 2095_UNSAFE_FUNC_PREFIX = r'(?:[-+*/=%^&|(<]\s*|>\s+)' 2096_THREADING_LIST = ( 2097 ('asctime(', 'asctime_r(', _UNSAFE_FUNC_PREFIX + r'asctime\([^)]+\)'), 2098 ('ctime(', 'ctime_r(', _UNSAFE_FUNC_PREFIX + r'ctime\([^)]+\)'), 2099 ('getgrgid(', 'getgrgid_r(', _UNSAFE_FUNC_PREFIX + r'getgrgid\([^)]+\)'), 2100 ('getgrnam(', 'getgrnam_r(', _UNSAFE_FUNC_PREFIX + r'getgrnam\([^)]+\)'), 2101 ('getlogin(', 'getlogin_r(', _UNSAFE_FUNC_PREFIX + r'getlogin\(\)'), 2102 ('getpwnam(', 'getpwnam_r(', _UNSAFE_FUNC_PREFIX + r'getpwnam\([^)]+\)'), 2103 ('getpwuid(', 'getpwuid_r(', _UNSAFE_FUNC_PREFIX + r'getpwuid\([^)]+\)'), 2104 ('gmtime(', 'gmtime_r(', _UNSAFE_FUNC_PREFIX + r'gmtime\([^)]+\)'), 2105 ('localtime(', 'localtime_r(', _UNSAFE_FUNC_PREFIX + r'localtime\([^)]+\)'), 2106 ('rand(', 'rand_r(', _UNSAFE_FUNC_PREFIX + r'rand\(\)'), 2107 ('strtok(', 'strtok_r(', 2108 _UNSAFE_FUNC_PREFIX + r'strtok\([^)]+\)'), 2109 ('ttyname(', 'ttyname_r(', _UNSAFE_FUNC_PREFIX + r'ttyname\([^)]+\)'), 2110 ) 2111 2112 2113def CheckPosixThreading(filename, clean_lines, linenum, error): 2114 """Checks for calls to thread-unsafe functions. 2115 2116 Much code has been originally written without consideration of 2117 multi-threading. Also, engineers are relying on their old experience; 2118 they have learned posix before threading extensions were added. These 2119 tests guide the engineers to use thread-safe functions (when using 2120 posix directly). 2121 2122 Args: 2123 filename: The name of the current file. 2124 clean_lines: A CleansedLines instance containing the file. 2125 linenum: The number of the line to check. 2126 error: The function to call with any errors found. 2127 """ 2128 line = clean_lines.elided[linenum] 2129 for single_thread_func, multithread_safe_func, pattern in _THREADING_LIST: 2130 # Additional pattern matching check to confirm that this is the 2131 # function we are looking for 2132 if Search(pattern, line): 2133 error(filename, linenum, 'runtime/threadsafe_fn', 2, 2134 'Consider using ' + multithread_safe_func + 2135 '...) instead of ' + single_thread_func + 2136 '...) for improved thread safety.') 2137 2138 2139def CheckVlogArguments(filename, clean_lines, linenum, error): 2140 """Checks that VLOG() is only used for defining a logging level. 2141 2142 For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and 2143 VLOG(FATAL) are not. 2144 2145 Args: 2146 filename: The name of the current file. 2147 clean_lines: A CleansedLines instance containing the file. 2148 linenum: The number of the line to check. 2149 error: The function to call with any errors found. 2150 """ 2151 line = clean_lines.elided[linenum] 2152 if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line): 2153 error(filename, linenum, 'runtime/vlog', 5, 2154 'VLOG() should be used with numeric verbosity level. ' 2155 'Use LOG() if you want symbolic severity levels.') 2156 2157# Matches invalid increment: *count++, which moves pointer instead of 2158# incrementing a value. 2159_RE_PATTERN_INVALID_INCREMENT = re.compile( 2160 r'^\s*\*\w+(\+\+|--);') 2161 2162 2163def CheckInvalidIncrement(filename, clean_lines, linenum, error): 2164 """Checks for invalid increment *count++. 2165 2166 For example following function: 2167 void increment_counter(int* count) { 2168 *count++; 2169 } 2170 is invalid, because it effectively does count++, moving pointer, and should 2171 be replaced with ++*count, (*count)++ or *count += 1. 2172 2173 Args: 2174 filename: The name of the current file. 2175 clean_lines: A CleansedLines instance containing the file. 2176 linenum: The number of the line to check. 2177 error: The function to call with any errors found. 2178 """ 2179 line = clean_lines.elided[linenum] 2180 if _RE_PATTERN_INVALID_INCREMENT.match(line): 2181 error(filename, linenum, 'runtime/invalid_increment', 5, 2182 'Changing pointer instead of value (or unused value of operator*).') 2183 2184 2185def IsMacroDefinition(clean_lines, linenum): 2186 if Search(r'^#define', clean_lines[linenum]): 2187 return True 2188 2189 if linenum > 0 and Search(r'\\$', clean_lines[linenum - 1]): 2190 return True 2191 2192 return False 2193 2194 2195def IsForwardClassDeclaration(clean_lines, linenum): 2196 return Match(r'^\s*(\btemplate\b)*.*class\s+\w+;\s*$', clean_lines[linenum]) 2197 2198 2199class _BlockInfo(object): 2200 """Stores information about a generic block of code.""" 2201 2202 def __init__(self, linenum, seen_open_brace): 2203 self.starting_linenum = linenum 2204 self.seen_open_brace = seen_open_brace 2205 self.open_parentheses = 0 2206 self.inline_asm = _NO_ASM 2207 self.check_namespace_indentation = False 2208 2209 def CheckBegin(self, filename, clean_lines, linenum, error): 2210 """Run checks that applies to text up to the opening brace. 2211 2212 This is mostly for checking the text after the class identifier 2213 and the "{", usually where the base class is specified. For other 2214 blocks, there isn't much to check, so we always pass. 2215 2216 Args: 2217 filename: The name of the current file. 2218 clean_lines: A CleansedLines instance containing the file. 2219 linenum: The number of the line to check. 2220 error: The function to call with any errors found. 2221 """ 2222 pass 2223 2224 def CheckEnd(self, filename, clean_lines, linenum, error): 2225 """Run checks that applies to text after the closing brace. 2226 2227 This is mostly used for checking end of namespace comments. 2228 2229 Args: 2230 filename: The name of the current file. 2231 clean_lines: A CleansedLines instance containing the file. 2232 linenum: The number of the line to check. 2233 error: The function to call with any errors found. 2234 """ 2235 pass 2236 2237 def IsBlockInfo(self): 2238 """Returns true if this block is a _BlockInfo. 2239 2240 This is convenient for verifying that an object is an instance of 2241 a _BlockInfo, but not an instance of any of the derived classes. 2242 2243 Returns: 2244 True for this class, False for derived classes. 2245 """ 2246 return self.__class__ == _BlockInfo 2247 2248 2249class _ExternCInfo(_BlockInfo): 2250 """Stores information about an 'extern "C"' block.""" 2251 2252 def __init__(self, linenum): 2253 _BlockInfo.__init__(self, linenum, True) 2254 2255 2256class _ClassInfo(_BlockInfo): 2257 """Stores information about a class.""" 2258 2259 def __init__(self, name, class_or_struct, clean_lines, linenum): 2260 _BlockInfo.__init__(self, linenum, False) 2261 self.name = name 2262 self.is_derived = False 2263 self.check_namespace_indentation = True 2264 if class_or_struct == 'struct': 2265 self.access = 'public' 2266 self.is_struct = True 2267 else: 2268 self.access = 'private' 2269 self.is_struct = False 2270 2271 # Remember initial indentation level for this class. Using raw_lines here 2272 # instead of elided to account for leading comments. 2273 self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) 2274 2275 # Try to find the end of the class. This will be confused by things like: 2276 # class A { 2277 # } *x = { ... 2278 # 2279 # But it's still good enough for CheckSectionSpacing. 2280 self.last_line = 0 2281 depth = 0 2282 for i in range(linenum, clean_lines.NumLines()): 2283 line = clean_lines.elided[i] 2284 depth += line.count('{') - line.count('}') 2285 if not depth: 2286 self.last_line = i 2287 break 2288 2289 def CheckBegin(self, filename, clean_lines, linenum, error): 2290 # Look for a bare ':' 2291 if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): 2292 self.is_derived = True 2293 2294 def CheckEnd(self, filename, clean_lines, linenum, error): 2295 # If there is a DISALLOW macro, it should appear near the end of 2296 # the class. 2297 seen_last_thing_in_class = False 2298 for i in xrange(linenum - 1, self.starting_linenum, -1): 2299 match = Search( 2300 r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + 2301 self.name + r'\)', 2302 clean_lines.elided[i]) 2303 if match: 2304 if seen_last_thing_in_class: 2305 error(filename, i, 'readability/constructors', 3, 2306 match.group(1) + ' should be the last thing in the class') 2307 break 2308 2309 if not Match(r'^\s*$', clean_lines.elided[i]): 2310 seen_last_thing_in_class = True 2311 2312 # Check that closing brace is aligned with beginning of the class. 2313 # Only do this if the closing brace is indented by only whitespaces. 2314 # This means we will not check single-line class definitions. 2315 indent = Match(r'^( *)\}', clean_lines.elided[linenum]) 2316 if indent and len(indent.group(1)) != self.class_indent: 2317 if self.is_struct: 2318 parent = 'struct ' + self.name 2319 else: 2320 parent = 'class ' + self.name 2321 error(filename, linenum, 'whitespace/indent', 3, 2322 'Closing brace should be aligned with beginning of %s' % parent) 2323 2324 2325class _NamespaceInfo(_BlockInfo): 2326 """Stores information about a namespace.""" 2327 2328 def __init__(self, name, linenum): 2329 _BlockInfo.__init__(self, linenum, False) 2330 self.name = name or '' 2331 self.check_namespace_indentation = True 2332 2333 def CheckEnd(self, filename, clean_lines, linenum, error): 2334 """Check end of namespace comments.""" 2335 line = clean_lines.raw_lines[linenum] 2336 2337 # Check how many lines is enclosed in this namespace. Don't issue 2338 # warning for missing namespace comments if there aren't enough 2339 # lines. However, do apply checks if there is already an end of 2340 # namespace comment and it's incorrect. 2341 # 2342 # TODO(unknown): We always want to check end of namespace comments 2343 # if a namespace is large, but sometimes we also want to apply the 2344 # check if a short namespace contained nontrivial things (something 2345 # other than forward declarations). There is currently no logic on 2346 # deciding what these nontrivial things are, so this check is 2347 # triggered by namespace size only, which works most of the time. 2348 if (linenum - self.starting_linenum < 10 2349 and not Match(r'^\s*};*\s*(//|/\*).*\bnamespace\b', line)): 2350 return 2351 2352 # Look for matching comment at end of namespace. 2353 # 2354 # Note that we accept C style "/* */" comments for terminating 2355 # namespaces, so that code that terminate namespaces inside 2356 # preprocessor macros can be cpplint clean. 2357 # 2358 # We also accept stuff like "// end of namespace <name>." with the 2359 # period at the end. 2360 # 2361 # Besides these, we don't accept anything else, otherwise we might 2362 # get false negatives when existing comment is a substring of the 2363 # expected namespace. 2364 # if self.name: 2365 # return 2366 # else: 2367 # # Anonymous namespace 2368 # if not Match(r'^\s*};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): 2369 # # If "// namespace anonymous" or "// anonymous namespace (more text)", 2370 # # mention "// anonymous namespace" as an acceptable form 2371 # if Match(r'^\s*}.*\b(namespace anonymous|anonymous namespace)\b', line): 2372 # error(filename, linenum, 'readability/namespace', 5, 2373 # 'Anonymous namespace should be terminated with "// namespace"' 2374 # ' or "// anonymous namespace"') 2375 # else: 2376 # error(filename, linenum, 'readability/namespace', 5, 2377 # 'Anonymous namespace should be terminated with "// namespace"') 2378 2379 2380class _PreprocessorInfo(object): 2381 """Stores checkpoints of nesting stacks when #if/#else is seen.""" 2382 2383 def __init__(self, stack_before_if): 2384 # The entire nesting stack before #if 2385 self.stack_before_if = stack_before_if 2386 2387 # The entire nesting stack up to #else 2388 self.stack_before_else = [] 2389 2390 # Whether we have already seen #else or #elif 2391 self.seen_else = False 2392 2393 2394class NestingState(object): 2395 """Holds states related to parsing braces.""" 2396 2397 def __init__(self): 2398 # Stack for tracking all braces. An object is pushed whenever we 2399 # see a "{", and popped when we see a "}". Only 3 types of 2400 # objects are possible: 2401 # - _ClassInfo: a class or struct. 2402 # - _NamespaceInfo: a namespace. 2403 # - _BlockInfo: some other type of block. 2404 self.stack = [] 2405 2406 # Top of the previous stack before each Update(). 2407 # 2408 # Because the nesting_stack is updated at the end of each line, we 2409 # had to do some convoluted checks to find out what is the current 2410 # scope at the beginning of the line. This check is simplified by 2411 # saving the previous top of nesting stack. 2412 # 2413 # We could save the full stack, but we only need the top. Copying 2414 # the full nesting stack would slow down cpplint by ~10%. 2415 self.previous_stack_top = [] 2416 2417 # Stack of _PreprocessorInfo objects. 2418 self.pp_stack = [] 2419 2420 def SeenOpenBrace(self): 2421 """Check if we have seen the opening brace for the innermost block. 2422 2423 Returns: 2424 True if we have seen the opening brace, False if the innermost 2425 block is still expecting an opening brace. 2426 """ 2427 return (not self.stack) or self.stack[-1].seen_open_brace 2428 2429 def InNamespaceBody(self): 2430 """Check if we are currently one level inside a namespace body. 2431 2432 Returns: 2433 True if top of the stack is a namespace block, False otherwise. 2434 """ 2435 return self.stack and isinstance(self.stack[-1], _NamespaceInfo) 2436 2437 def InExternC(self): 2438 """Check if we are currently one level inside an 'extern "C"' block. 2439 2440 Returns: 2441 True if top of the stack is an extern block, False otherwise. 2442 """ 2443 return self.stack and isinstance(self.stack[-1], _ExternCInfo) 2444 2445 def InClassDeclaration(self): 2446 """Check if we are currently one level inside a class or struct declaration. 2447 2448 Returns: 2449 True if top of the stack is a class/struct, False otherwise. 2450 """ 2451 return self.stack and isinstance(self.stack[-1], _ClassInfo) 2452 2453 def InAsmBlock(self): 2454 """Check if we are currently one level inside an inline ASM block. 2455 2456 Returns: 2457 True if the top of the stack is a block containing inline ASM. 2458 """ 2459 return self.stack and self.stack[-1].inline_asm != _NO_ASM 2460 2461 def InTemplateArgumentList(self, clean_lines, linenum, pos): 2462 """Check if current position is inside template argument list. 2463 2464 Args: 2465 clean_lines: A CleansedLines instance containing the file. 2466 linenum: The number of the line to check. 2467 pos: position just after the suspected template argument. 2468 Returns: 2469 True if (linenum, pos) is inside template arguments. 2470 """ 2471 while linenum < clean_lines.NumLines(): 2472 # Find the earliest character that might indicate a template argument 2473 line = clean_lines.elided[linenum] 2474 match = Match(r'^[^{};=\[\]\.<>]*(.)', line[pos:]) 2475 if not match: 2476 linenum += 1 2477 pos = 0 2478 continue 2479 token = match.group(1) 2480 pos += len(match.group(0)) 2481 2482 # These things do not look like template argument list: 2483 # class Suspect { 2484 # class Suspect x; } 2485 if token in ('{', '}', ';'): return False 2486 2487 # These things look like template argument list: 2488 # template <class Suspect> 2489 # template <class Suspect = default_value> 2490 # template <class Suspect[]> 2491 # template <class Suspect...> 2492 if token in ('>', '=', '[', ']', '.'): return True 2493 2494 # Check if token is an unmatched '<'. 2495 # If not, move on to the next character. 2496 if token != '<': 2497 pos += 1 2498 if pos >= len(line): 2499 linenum += 1 2500 pos = 0 2501 continue 2502 2503 # We can't be sure if we just find a single '<', and need to 2504 # find the matching '>'. 2505 (_, end_line, end_pos) = CloseExpression(clean_lines, linenum, pos - 1) 2506 if end_pos < 0: 2507 # Not sure if template argument list or syntax error in file 2508 return False 2509 linenum = end_line 2510 pos = end_pos 2511 return False 2512 2513 def UpdatePreprocessor(self, line): 2514 """Update preprocessor stack. 2515 2516 We need to handle preprocessors due to classes like this: 2517 #ifdef SWIG 2518 struct ResultDetailsPageElementExtensionPoint { 2519 #else 2520 struct ResultDetailsPageElementExtensionPoint : public Extension { 2521 #endif 2522 2523 We make the following assumptions (good enough for most files): 2524 - Preprocessor condition evaluates to true from #if up to first 2525 #else/#elif/#endif. 2526 2527 - Preprocessor condition evaluates to false from #else/#elif up 2528 to #endif. We still perform lint checks on these lines, but 2529 these do not affect nesting stack. 2530 2531 Args: 2532 line: current line to check. 2533 """ 2534 if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line): 2535 # Beginning of #if block, save the nesting stack here. The saved 2536 # stack will allow us to restore the parsing state in the #else case. 2537 self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack))) 2538 elif Match(r'^\s*#\s*(else|elif)\b', line): 2539 # Beginning of #else block 2540 if self.pp_stack: 2541 if not self.pp_stack[-1].seen_else: 2542 # This is the first #else or #elif block. Remember the 2543 # whole nesting stack up to this point. This is what we 2544 # keep after the #endif. 2545 self.pp_stack[-1].seen_else = True 2546 self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack) 2547 2548 # Restore the stack to how it was before the #if 2549 self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if) 2550 else: 2551 # TODO(unknown): unexpected #else, issue warning? 2552 pass 2553 elif Match(r'^\s*#\s*endif\b', line): 2554 # End of #if or #else blocks. 2555 if self.pp_stack: 2556 # If we saw an #else, we will need to restore the nesting 2557 # stack to its former state before the #else, otherwise we 2558 # will just continue from where we left off. 2559 if self.pp_stack[-1].seen_else: 2560 # Here we can just use a shallow copy since we are the last 2561 # reference to it. 2562 self.stack = self.pp_stack[-1].stack_before_else 2563 # Drop the corresponding #if 2564 self.pp_stack.pop() 2565 else: 2566 # TODO(unknown): unexpected #endif, issue warning? 2567 pass 2568 2569 # TODO(unknown): Update() is too long, but we will refactor later. 2570 def Update(self, filename, clean_lines, linenum, error): 2571 """Update nesting state with current line. 2572 2573 Args: 2574 filename: The name of the current file. 2575 clean_lines: A CleansedLines instance containing the file. 2576 linenum: The number of the line to check. 2577 error: The function to call with any errors found. 2578 """ 2579 line = clean_lines.elided[linenum] 2580 2581 # Remember top of the previous nesting stack. 2582 # 2583 # The stack is always pushed/popped and not modified in place, so 2584 # we can just do a shallow copy instead of copy.deepcopy. Using 2585 # deepcopy would slow down cpplint by ~28%. 2586 if self.stack: 2587 self.previous_stack_top = self.stack[-1] 2588 else: 2589 self.previous_stack_top = None 2590 2591 # Update pp_stack 2592 self.UpdatePreprocessor(line) 2593 2594 # Count parentheses. This is to avoid adding struct arguments to 2595 # the nesting stack. 2596 if self.stack: 2597 inner_block = self.stack[-1] 2598 depth_change = line.count('(') - line.count(')') 2599 inner_block.open_parentheses += depth_change 2600 2601 # Also check if we are starting or ending an inline assembly block. 2602 if inner_block.inline_asm in (_NO_ASM, _END_ASM): 2603 if (depth_change != 0 and 2604 inner_block.open_parentheses == 1 and 2605 _MATCH_ASM.match(line)): 2606 # Enter assembly block 2607 inner_block.inline_asm = _INSIDE_ASM 2608 else: 2609 # Not entering assembly block. If previous line was _END_ASM, 2610 # we will now shift to _NO_ASM state. 2611 inner_block.inline_asm = _NO_ASM 2612 elif (inner_block.inline_asm == _INSIDE_ASM and 2613 inner_block.open_parentheses == 0): 2614 # Exit assembly block 2615 inner_block.inline_asm = _END_ASM 2616 2617 # Consume namespace declaration at the beginning of the line. Do 2618 # this in a loop so that we catch same line declarations like this: 2619 # namespace proto2 { namespace bridge { class MessageSet; } } 2620 while True: 2621 # Match start of namespace. The "\b\s*" below catches namespace 2622 # declarations even if it weren't followed by a whitespace, this 2623 # is so that we don't confuse our namespace checker. The 2624 # missing spaces will be flagged by CheckSpacing. 2625 namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line) 2626 if not namespace_decl_match: 2627 break 2628 2629 new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum) 2630 self.stack.append(new_namespace) 2631 2632 line = namespace_decl_match.group(2) 2633 if line.find('{') != -1: 2634 new_namespace.seen_open_brace = True 2635 line = line[line.find('{') + 1:] 2636 2637 # Look for a class declaration in whatever is left of the line 2638 # after parsing namespaces. The regexp accounts for decorated classes 2639 # such as in: 2640 # class LOCKABLE API Object { 2641 # }; 2642 class_decl_match = Match( 2643 r'^(\s*(?:template\s*<[\w\s<>,:]*>\s*)?' 2644 r'(class|struct)\s+(?:[A-Z_]+\s+)*(\w+(?:::\w+)*))' 2645 r'(.*)$', line) 2646 if (class_decl_match and 2647 (not self.stack or self.stack[-1].open_parentheses == 0)): 2648 # We do not want to accept classes that are actually template arguments: 2649 # template <class Ignore1, 2650 # class Ignore2 = Default<Args>, 2651 # template <Args> class Ignore3> 2652 # void Function() {}; 2653 # 2654 # To avoid template argument cases, we scan forward and look for 2655 # an unmatched '>'. If we see one, assume we are inside a 2656 # template argument list. 2657 end_declaration = len(class_decl_match.group(1)) 2658 if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration): 2659 self.stack.append(_ClassInfo( 2660 class_decl_match.group(3), class_decl_match.group(2), 2661 clean_lines, linenum)) 2662 line = class_decl_match.group(4) 2663 2664 # If we have not yet seen the opening brace for the innermost block, 2665 # run checks here. 2666 if not self.SeenOpenBrace(): 2667 self.stack[-1].CheckBegin(filename, clean_lines, linenum, error) 2668 2669 # Update access control if we are inside a class/struct 2670 if self.stack and isinstance(self.stack[-1], _ClassInfo): 2671 classinfo = self.stack[-1] 2672 access_match = Match( 2673 r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?' 2674 r':(?:[^:]|$)', 2675 line) 2676 if access_match: 2677 classinfo.access = access_match.group(2) 2678 2679 # Check that access keywords are indented +2 space. Skip this 2680 # check if the keywords are not preceded by whitespaces. 2681 indent = access_match.group(1) 2682 if (len(indent) != classinfo.class_indent + 2 and 2683 Match(r'^\s*$', indent)): 2684 if classinfo.is_struct: 2685 parent = 'struct ' + classinfo.name 2686 else: 2687 parent = 'class ' + classinfo.name 2688 slots = '' 2689 if access_match.group(3): 2690 slots = access_match.group(3) 2691 error(filename, linenum, 'whitespace/indent', 3, 2692 '%s%s: should be indented +1 space inside %s' % ( 2693 access_match.group(2), slots, parent)) 2694 2695 # Consume braces or semicolons from what's left of the line 2696 while True: 2697 # Match first brace, semicolon, or closed parenthesis. 2698 matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line) 2699 if not matched: 2700 break 2701 2702 token = matched.group(1) 2703 if token == '{': 2704 # If namespace or class hasn't seen a opening brace yet, mark 2705 # namespace/class head as complete. Push a new block onto the 2706 # stack otherwise. 2707 if not self.SeenOpenBrace(): 2708 self.stack[-1].seen_open_brace = True 2709 elif Match(r'^extern\s*"[^"]*"\s*\{', line): 2710 self.stack.append(_ExternCInfo(linenum)) 2711 else: 2712 self.stack.append(_BlockInfo(linenum, True)) 2713 if _MATCH_ASM.match(line): 2714 self.stack[-1].inline_asm = _BLOCK_ASM 2715 2716 elif token == ';' or token == ')': 2717 # If we haven't seen an opening brace yet, but we already saw 2718 # a semicolon, this is probably a forward declaration. Pop 2719 # the stack for these. 2720 # 2721 # Similarly, if we haven't seen an opening brace yet, but we 2722 # already saw a closing parenthesis, then these are probably 2723 # function arguments with extra "class" or "struct" keywords. 2724 # Also pop these stack for these. 2725 if not self.SeenOpenBrace(): 2726 self.stack.pop() 2727 else: # token == '}' 2728 # Perform end of block checks and pop the stack. 2729 if self.stack: 2730 self.stack[-1].CheckEnd(filename, clean_lines, linenum, error) 2731 self.stack.pop() 2732 line = matched.group(2) 2733 2734 def InnermostClass(self): 2735 """Get class info on the top of the stack. 2736 2737 Returns: 2738 A _ClassInfo object if we are inside a class, or None otherwise. 2739 """ 2740 for i in range(len(self.stack), 0, -1): 2741 classinfo = self.stack[i - 1] 2742 if isinstance(classinfo, _ClassInfo): 2743 return classinfo 2744 return None 2745 2746 def CheckCompletedBlocks(self, filename, error): 2747 """Checks that all classes and namespaces have been completely parsed. 2748 2749 Call this when all lines in a file have been processed. 2750 Args: 2751 filename: The name of the current file. 2752 error: The function to call with any errors found. 2753 """ 2754 # Note: This test can result in false positives if #ifdef constructs 2755 # get in the way of brace matching. See the testBuildClass test in 2756 # cpplint_unittest.py for an example of this. 2757 for obj in self.stack: 2758 if isinstance(obj, _ClassInfo): 2759 error(filename, obj.starting_linenum, 'build/class', 5, 2760 'Failed to find complete declaration of class %s' % 2761 obj.name) 2762 elif isinstance(obj, _NamespaceInfo): 2763 error(filename, obj.starting_linenum, 'build/namespaces', 5, 2764 'Failed to find complete declaration of namespace %s' % 2765 obj.name) 2766 2767 2768def CheckForNonStandardConstructs(filename, clean_lines, linenum, 2769 nesting_state, error): 2770 r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2. 2771 2772 Complain about several constructs which gcc-2 accepts, but which are 2773 not standard C++. Warning about these in lint is one way to ease the 2774 transition to new compilers. 2775 - put storage class first (e.g. "static const" instead of "const static"). 2776 - "%lld" instead of %qd" in printf-type functions. 2777 - "%1$d" is non-standard in printf-type functions. 2778 - "\%" is an undefined character escape sequence. 2779 - text after #endif is not allowed. 2780 - invalid inner-style forward declaration. 2781 - >? and <? operators, and their >?= and <?= cousins. 2782 2783 Additionally, check for constructor/destructor style violations and reference 2784 members, as it is very convenient to do so while checking for 2785 gcc-2 compliance. 2786 2787 Args: 2788 filename: The name of the current file. 2789 clean_lines: A CleansedLines instance containing the file. 2790 linenum: The number of the line to check. 2791 nesting_state: A NestingState instance which maintains information about 2792 the current stack of nested blocks being parsed. 2793 error: A callable to which errors are reported, which takes 4 arguments: 2794 filename, line number, error level, and message 2795 """ 2796 2797 # Remove comments from the line, but leave in strings for now. 2798 line = clean_lines.lines[linenum] 2799 2800 if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line): 2801 error(filename, linenum, 'runtime/printf_format', 3, 2802 '%q in format strings is deprecated. Use %ll instead.') 2803 2804 if Search(r'printf\s*\(.*".*%\d+\$', line): 2805 error(filename, linenum, 'runtime/printf_format', 2, 2806 '%N$ formats are unconventional. Try rewriting to avoid them.') 2807 2808 # Remove escaped backslashes before looking for undefined escapes. 2809 line = line.replace('\\\\', '') 2810 2811 if Search(r'("|\').*\\(%|\[|\(|{)', line): 2812 error(filename, linenum, 'build/printf_format', 3, 2813 '%, [, (, and { are undefined character escapes. Unescape them.') 2814 2815 # For the rest, work with both comments and strings removed. 2816 line = clean_lines.elided[linenum] 2817 2818 if Search(r'\b(const|volatile|void|char|short|int|long' 2819 r'|float|double|signed|unsigned' 2820 r'|schar|u?int8|u?int16|u?int32|u?int64)' 2821 r'\s+(register|static|extern|typedef)\b', 2822 line): 2823 error(filename, linenum, 'build/storage_class', 5, 2824 'Storage-class specifier (static, extern, typedef, etc) should be ' 2825 'at the beginning of the declaration.') 2826 2827 if Match(r'\s*#\s*endif\s*[^/\s]+', line): 2828 error(filename, linenum, 'build/endif_comment', 5, 2829 'Uncommented text after #endif is non-standard. Use a comment.') 2830 2831 if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line): 2832 error(filename, linenum, 'build/forward_decl', 5, 2833 'Inner-style forward declarations are invalid. Remove this line.') 2834 2835 if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', 2836 line): 2837 error(filename, linenum, 'build/deprecated', 3, 2838 '>? and <? (max and min) operators are non-standard and deprecated.') 2839 2840 if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line): 2841 # TODO(unknown): Could it be expanded safely to arbitrary references, 2842 # without triggering too many false positives? The first 2843 # attempt triggered 5 warnings for mostly benign code in the regtest, hence 2844 # the restriction. 2845 # Here's the original regexp, for the reference: 2846 # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?' 2847 # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;' 2848 error(filename, linenum, 'runtime/member_string_references', 2, 2849 'const string& members are dangerous. It is much better to use ' 2850 'alternatives, such as pointers or simple constants.') 2851 2852 # Everything else in this function operates on class declarations. 2853 # Return early if the top of the nesting stack is not a class, or if 2854 # the class head is not completed yet. 2855 classinfo = nesting_state.InnermostClass() 2856 if not classinfo or not classinfo.seen_open_brace: 2857 return 2858 2859 # The class may have been declared with namespace or classname qualifiers. 2860 # The constructor and destructor will not have those qualifiers. 2861 base_classname = classinfo.name.split('::')[-1] 2862 2863 # Look for single-argument constructors that aren't marked explicit. 2864 # Technically a valid construct, but against style. 2865 explicit_constructor_match = Match( 2866 r'\s+(?:(?:inline|constexpr)\s+)*(explicit\s+)?' 2867 r'(?:(?:inline|constexpr)\s+)*%s\s*' 2868 r'\(((?:[^()]|\([^()]*\))*)\)' 2869 % re.escape(base_classname), 2870 line) 2871 2872 if explicit_constructor_match: 2873 is_marked_explicit = explicit_constructor_match.group(1) 2874 2875 if not explicit_constructor_match.group(2): 2876 constructor_args = [] 2877 else: 2878 constructor_args = explicit_constructor_match.group(2).split(',') 2879 2880 # collapse arguments so that commas in template parameter lists and function 2881 # argument parameter lists don't split arguments in two 2882 i = 0 2883 while i < len(constructor_args): 2884 constructor_arg = constructor_args[i] 2885 while (constructor_arg.count('<') > constructor_arg.count('>') or 2886 constructor_arg.count('(') > constructor_arg.count(')')): 2887 constructor_arg += ',' + constructor_args[i + 1] 2888 del constructor_args[i + 1] 2889 constructor_args[i] = constructor_arg 2890 i += 1 2891 2892 defaulted_args = [arg for arg in constructor_args if '=' in arg] 2893 noarg_constructor = (not constructor_args or # empty arg list 2894 # 'void' arg specifier 2895 (len(constructor_args) == 1 and 2896 constructor_args[0].strip() == 'void')) 2897 onearg_constructor = ((len(constructor_args) == 1 and # exactly one arg 2898 not noarg_constructor) or 2899 # all but at most one arg defaulted 2900 (len(constructor_args) >= 1 and 2901 not noarg_constructor and 2902 len(defaulted_args) >= len(constructor_args) - 1)) 2903 initializer_list_constructor = bool( 2904 onearg_constructor and 2905 Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0])) 2906 copy_constructor = bool( 2907 onearg_constructor and 2908 Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&' 2909 % re.escape(base_classname), constructor_args[0].strip())) 2910 2911 if (not is_marked_explicit and 2912 onearg_constructor and 2913 not initializer_list_constructor and 2914 not copy_constructor): 2915 if defaulted_args: 2916 error(filename, linenum, 'runtime/explicit', 5, 2917 'Constructors callable with one argument ' 2918 'should be marked explicit.') 2919 else: 2920 error(filename, linenum, 'runtime/explicit', 5, 2921 'Single-parameter constructors should be marked explicit.') 2922 elif is_marked_explicit and not onearg_constructor: 2923 if noarg_constructor: 2924 error(filename, linenum, 'runtime/explicit', 5, 2925 'Zero-parameter constructors should not be marked explicit.') 2926 2927 2928def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): 2929 """Checks for the correctness of various spacing around function calls. 2930 2931 Args: 2932 filename: The name of the current file. 2933 clean_lines: A CleansedLines instance containing the file. 2934 linenum: The number of the line to check. 2935 error: The function to call with any errors found. 2936 """ 2937 line = clean_lines.elided[linenum] 2938 2939 # Since function calls often occur inside if/for/while/switch 2940 # expressions - which have their own, more liberal conventions - we 2941 # first see if we should be looking inside such an expression for a 2942 # function call, to which we can apply more strict standards. 2943 fncall = line # if there's no control flow construct, look at whole line 2944 for pattern in (r'\bif\s*\((.*)\)\s*{', 2945 r'\bfor\s*\((.*)\)\s*{', 2946 r'\bwhile\s*\((.*)\)\s*[{;]', 2947 r'\bswitch\s*\((.*)\)\s*{'): 2948 match = Search(pattern, line) 2949 if match: 2950 fncall = match.group(1) # look inside the parens for function calls 2951 break 2952 2953 # Except in if/for/while/switch, there should never be space 2954 # immediately inside parens (eg "f( 3, 4 )"). We make an exception 2955 # for nested parens ( (a+b) + c ). Likewise, there should never be 2956 # a space before a ( when it's a function argument. I assume it's a 2957 # function argument when the char before the whitespace is legal in 2958 # a function name (alnum + _) and we're not starting a macro. Also ignore 2959 # pointers and references to arrays and functions coz they're too tricky: 2960 # we use a very simple way to recognize these: 2961 # " (something)(maybe-something)" or 2962 # " (something)(maybe-something," or 2963 # " (something)[something]" 2964 # Note that we assume the contents of [] to be short enough that 2965 # they'll never need to wrap. 2966 if ( # Ignore control structures. 2967 not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b', 2968 fncall) and 2969 # Ignore pointers/references to functions. 2970 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and 2971 # Ignore pointers/references to arrays. 2972 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): 2973 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call 2974 error(filename, linenum, 'whitespace/parens', 4, 2975 'Extra space after ( in function call') 2976 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): 2977 error(filename, linenum, 'whitespace/parens', 2, 2978 'Extra space after (') 2979 if (Search(r'\w\s+\(', fncall) and 2980 not Search(r'_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(', fncall) and 2981 not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and 2982 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and 2983 not Search(r'\bcase\s+\(', fncall)): 2984 # TODO(unknown): Space after an operator function seem to be a common 2985 # error, silence those for now by restricting them to highest verbosity. 2986 if Search(r'\boperator_*\b', line): 2987 error(filename, linenum, 'whitespace/parens', 0, 2988 'Extra space before ( in function call') 2989 # If < and > are present, then we assume fncall is a function pointer. 2990 elif not Search(r'\<.*\>', fncall): 2991 error(filename, linenum, 'whitespace/parens', 4, 2992 'Extra space before ( in function call') 2993 # If the ) is followed only by a newline or a { + newline, assume it's 2994 # part of a control statement (if/while/etc), and don't complain 2995 if Search(r'[^)]\s+\)\s*[^{\s]', fncall): 2996 # If the closing parenthesis is preceded by only whitespaces, 2997 # try to give a more descriptive error message. 2998 if Search(r'^\s+\)', fncall): 2999 error(filename, linenum, 'whitespace/parens', 2, 3000 'Closing ) should be moved to the previous line') 3001 else: 3002 error(filename, linenum, 'whitespace/parens', 2, 3003 'Extra space before )') 3004 3005 3006def IsBlankLine(line): 3007 """Returns true if the given line is blank. 3008 3009 We consider a line to be blank if the line is empty or consists of 3010 only white spaces. 3011 3012 Args: 3013 line: A line of a string. 3014 3015 Returns: 3016 True, if the given line is blank. 3017 """ 3018 return not line or line.isspace() 3019 3020 3021def CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line, 3022 error): 3023 is_namespace_indent_item = ( 3024 len(nesting_state.stack) > 1 and 3025 nesting_state.stack[-1].check_namespace_indentation and 3026 isinstance(nesting_state.previous_stack_top, _NamespaceInfo) and 3027 nesting_state.previous_stack_top == nesting_state.stack[-2]) 3028 3029 if ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item, 3030 clean_lines.elided, line): 3031 CheckItemIndentationInNamespace(filename, clean_lines.elided, 3032 line, error) 3033 3034 3035def CheckForFunctionLengths(filename, clean_lines, linenum, 3036 function_state, error): 3037 """Reports for long function bodies. 3038 3039 For an overview why this is done, see: 3040 https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions 3041 3042 Uses a simplistic algorithm assuming other style guidelines 3043 (especially spacing) are followed. 3044 Only checks unindented functions, so class members are unchecked. 3045 Trivial bodies are unchecked, so constructors with huge initializer lists 3046 may be missed. 3047 Blank/comment lines are not counted so as to avoid encouraging the removal 3048 of vertical space and comments just to get through a lint check. 3049 NOLINT *on the last line of a function* disables this check. 3050 3051 Args: 3052 filename: The name of the current file. 3053 clean_lines: A CleansedLines instance containing the file. 3054 linenum: The number of the line to check. 3055 function_state: Current function name and lines in body so far. 3056 error: The function to call with any errors found. 3057 """ 3058 lines = clean_lines.lines 3059 line = lines[linenum] 3060 joined_line = '' 3061 3062 starting_func = False 3063 regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... 3064 match_result = Match(regexp, line) 3065 if match_result: 3066 # If the name is all caps and underscores, figure it's a macro and 3067 # ignore it, unless it's TEST or TEST_F. 3068 function_name = match_result.group(1).split()[-1] 3069 if function_name == 'TEST' or function_name == 'TEST_F' or ( 3070 not Match(r'[A-Z_]+$', function_name)): 3071 starting_func = True 3072 3073 if starting_func: 3074 body_found = False 3075 for start_linenum in xrange(linenum, clean_lines.NumLines()): 3076 start_line = lines[start_linenum] 3077 joined_line += ' ' + start_line.lstrip() 3078 if Search(r'(;|})', start_line): # Declarations and trivial functions 3079 body_found = True 3080 break # ... ignore 3081 elif Search(r'{', start_line): 3082 body_found = True 3083 function = Search(r'((\w|:)*)\(', line).group(1) 3084 if Match(r'TEST', function): # Handle TEST... macros 3085 parameter_regexp = Search(r'(\(.*\))', joined_line) 3086 if parameter_regexp: # Ignore bad syntax 3087 function += parameter_regexp.group(1) 3088 else: 3089 function += '()' 3090 function_state.Begin(function) 3091 break 3092 if not body_found: 3093 # No body for the function (or evidence of a non-function) was found. 3094 error(filename, linenum, 'readability/fn_size', 5, 3095 'Lint failed to find start of function body.') 3096 elif Match(r'^\}\s*$', line): # function end 3097 function_state.Check(error, filename, linenum) 3098 function_state.End() 3099 elif not Match(r'^\s*$', line): 3100 function_state.Count() # Count non-blank/non-comment lines. 3101 3102 3103_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') 3104 3105 3106def CheckComment(line, filename, linenum, next_line_start, error): 3107 """Checks for common mistakes in comments. 3108 3109 Args: 3110 line: The line in question. 3111 filename: The name of the current file. 3112 linenum: The number of the line to check. 3113 next_line_start: The first non-whitespace column of the next line. 3114 error: The function to call with any errors found. 3115 """ 3116 commentpos = line.find('//') 3117 if commentpos != -1: 3118 # Check if the // may be in quotes. If so, ignore it 3119 if re.sub(r'\\.', '', line[0:commentpos]).count('"') % 2 == 0: 3120 # Allow one space for new scopes, two spaces otherwise: 3121 if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and 3122 ((commentpos >= 1 and 3123 line[commentpos-1] not in string.whitespace) or 3124 (commentpos >= 2 and 3125 line[commentpos-2] not in string.whitespace))): 3126 error(filename, linenum, 'whitespace/comments', 2, 3127 'At least two spaces is best between code and comments') 3128 3129 # Checks for common mistakes in TODO comments. 3130 comment = line[commentpos:] 3131 match = _RE_PATTERN_TODO.match(comment) 3132 if match: 3133 # One whitespace is correct; zero whitespace is handled elsewhere. 3134 leading_whitespace = match.group(1) 3135 if len(leading_whitespace) > 1: 3136 error(filename, linenum, 'whitespace/todo', 2, 3137 'Too many spaces before TODO') 3138 3139 username = match.group(2) 3140 if not username: 3141 error(filename, linenum, 'readability/todo', 2, 3142 'Missing username in TODO; it should look like ' 3143 '"// TODO(my_username): Stuff."') 3144 3145 middle_whitespace = match.group(3) 3146 # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison 3147 if middle_whitespace != ' ' and middle_whitespace != '': 3148 error(filename, linenum, 'whitespace/todo', 2, 3149 'TODO(my_username) should be followed by a space') 3150 3151 # If the comment contains an alphanumeric character, there 3152 # should be a space somewhere between it and the // unless 3153 # it's a /// or //! Doxygen comment. 3154 if (Match(r'//[^ ]*\w', comment) and 3155 not Match(r'(///|//\!)(\s+|$)', comment)): 3156 error(filename, linenum, 'whitespace/comments', 4, 3157 'Should have a space between // and comment') 3158 3159 3160def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): 3161 """Checks for the correctness of various spacing issues in the code. 3162 3163 Things we check for: spaces around operators, spaces after 3164 if/for/while/switch, no spaces around parens in function calls, two 3165 spaces between code and comment, don't start a block with a blank 3166 line, don't end a function with a blank line, don't add a blank line 3167 after public/protected/private, don't have too many blank lines in a row. 3168 3169 Args: 3170 filename: The name of the current file. 3171 clean_lines: A CleansedLines instance containing the file. 3172 linenum: The number of the line to check. 3173 nesting_state: A NestingState instance which maintains information about 3174 the current stack of nested blocks being parsed. 3175 error: The function to call with any errors found. 3176 """ 3177 3178 # Don't use "elided" lines here, otherwise we can't check commented lines. 3179 # Don't want to use "raw" either, because we don't want to check inside C++11 3180 # raw strings, 3181 raw = clean_lines.lines_without_raw_strings 3182 line = raw[linenum] 3183 3184 # Before nixing comments, check if the line is blank for no good 3185 # reason. This includes the first line after a block is opened, and 3186 # blank lines at the end of a function (ie, right before a line like '}' 3187 # 3188 # Skip all the blank line checks if we are immediately inside a 3189 # namespace body. In other words, don't issue blank line warnings 3190 # for this block: 3191 # namespace { 3192 # 3193 # } 3194 # 3195 # A warning about missing end of namespace comments will be issued instead. 3196 # 3197 # Also skip blank line checks for 'extern "C"' blocks, which are formatted 3198 # like namespaces. 3199 if (IsBlankLine(line) and 3200 not nesting_state.InNamespaceBody() and 3201 not nesting_state.InExternC()): 3202 elided = clean_lines.elided 3203 prev_line = elided[linenum - 1] 3204 prevbrace = prev_line.rfind('{') 3205 # TODO(unknown): Don't complain if line before blank line, and line after, 3206 # both start with alnums and are indented the same amount. 3207 # This ignores whitespace at the start of a namespace block 3208 # because those are not usually indented. 3209 if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: 3210 # OK, we have a blank line at the start of a code block. Before we 3211 # complain, we check if it is an exception to the rule: The previous 3212 # non-empty line has the parameters of a function header that are indented 3213 # 4 spaces (because they did not fit in a 80 column line when placed on 3214 # the same line as the function name). We also check for the case where 3215 # the previous line is indented 6 spaces, which may happen when the 3216 # initializers of a constructor do not fit into a 80 column line. 3217 exception = False 3218 if Match(r' {6}\w', prev_line): # Initializer list? 3219 # We are looking for the opening column of initializer list, which 3220 # should be indented 4 spaces to cause 6 space indentation afterwards. 3221 search_position = linenum-2 3222 while (search_position >= 0 3223 and Match(r' {6}\w', elided[search_position])): 3224 search_position -= 1 3225 exception = (search_position >= 0 3226 and elided[search_position][:5] == ' :') 3227 else: 3228 # Search for the function arguments or an initializer list. We use a 3229 # simple heuristic here: If the line is indented 4 spaces; and we have a 3230 # closing paren, without the opening paren, followed by an opening brace 3231 # or colon (for initializer lists) we assume that it is the last line of 3232 # a function header. If we have a colon indented 4 spaces, it is an 3233 # initializer list. 3234 exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', 3235 prev_line) 3236 or Match(r' {4}:', prev_line)) 3237 3238 if not exception: 3239 error(filename, linenum, 'whitespace/blank_line', 2, 3240 'Redundant blank line at the start of a code block ' 3241 'should be deleted.') 3242 # Ignore blank lines at the end of a block in a long if-else 3243 # chain, like this: 3244 # if (condition1) { 3245 # // Something followed by a blank line 3246 # 3247 # } else if (condition2) { 3248 # // Something else 3249 # } 3250 if linenum + 1 < clean_lines.NumLines(): 3251 next_line = raw[linenum + 1] 3252 if (next_line 3253 and Match(r'\s*}', next_line) 3254 and next_line.find('} else ') == -1): 3255 error(filename, linenum, 'whitespace/blank_line', 3, 3256 'Redundant blank line at the end of a code block ' 3257 'should be deleted.') 3258 3259 matched = Match(r'\s*(public|protected|private):', prev_line) 3260 # if matched: 3261 # error(filename, linenum, 'whitespace/blank_line', 3, 3262 # 'Do not leave a blank line after "%s:"' % matched.group(1)) 3263 3264 # Next, check comments 3265 next_line_start = 0 3266 if linenum + 1 < clean_lines.NumLines(): 3267 next_line = raw[linenum + 1] 3268 next_line_start = len(next_line) - len(next_line.lstrip()) 3269 CheckComment(line, filename, linenum, next_line_start, error) 3270 3271 # get rid of comments and strings 3272 line = clean_lines.elided[linenum] 3273 3274 # You shouldn't have spaces before your brackets, except maybe after 3275 # 'delete []' or 'return []() {};' 3276 if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line): 3277 error(filename, linenum, 'whitespace/braces', 5, 3278 'Extra space before [') 3279 3280 # In range-based for, we wanted spaces before and after the colon, but 3281 # not around "::" tokens that might appear. 3282 if (Search(r'for *\(.*[^:]:[^: ]', line) or 3283 Search(r'for *\(.*[^: ]:[^:]', line)): 3284 error(filename, linenum, 'whitespace/forcolon', 2, 3285 'Missing space around colon in range-based for loop') 3286 3287 3288def CheckOperatorSpacing(filename, clean_lines, linenum, error): 3289 """Checks for horizontal spacing around operators. 3290 3291 Args: 3292 filename: The name of the current file. 3293 clean_lines: A CleansedLines instance containing the file. 3294 linenum: The number of the line to check. 3295 error: The function to call with any errors found. 3296 """ 3297 line = clean_lines.elided[linenum] 3298 3299 # Don't try to do spacing checks for operator methods. Do this by 3300 # replacing the troublesome characters with something else, 3301 # preserving column position for all other characters. 3302 # 3303 # The replacement is done repeatedly to avoid false positives from 3304 # operators that call operators. 3305 while True: 3306 match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line) 3307 if match: 3308 line = match.group(1) + ('_' * len(match.group(2))) + match.group(3) 3309 else: 3310 break 3311 3312 # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". 3313 # Otherwise not. Note we only check for non-spaces on *both* sides; 3314 # sometimes people put non-spaces on one side when aligning ='s among 3315 # many lines (not that this is behavior that I approve of...) 3316 if ((Search(r'[\w.]=', line) or 3317 Search(r'=[\w.]', line)) 3318 and not Search(r'\b(if|while|for) ', line) 3319 # Operators taken from [lex.operators] in C++11 standard. 3320 and not Search(r'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)', line) 3321 and not Search(r'operator=', line)): 3322 error(filename, linenum, 'whitespace/operators', 4, 3323 'Missing spaces around =') 3324 3325 # It's ok not to have spaces around binary operators like + - * /, but if 3326 # there's too little whitespace, we get concerned. It's hard to tell, 3327 # though, so we punt on this one for now. TODO. 3328 3329 # You should always have whitespace around binary operators. 3330 # 3331 # Check <= and >= first to avoid false positives with < and >, then 3332 # check non-include lines for spacing around < and >. 3333 # 3334 # If the operator is followed by a comma, assume it's be used in a 3335 # macro context and don't do any checks. This avoids false 3336 # positives. 3337 # 3338 # Note that && is not included here. This is because there are too 3339 # many false positives due to RValue references. 3340 match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line) 3341 if match: 3342 error(filename, linenum, 'whitespace/operators', 3, 3343 'Missing spaces around %s' % match.group(1)) 3344 elif not Match(r'#.*include', line): 3345 # Look for < that is not surrounded by spaces. This is only 3346 # triggered if both sides are missing spaces, even though 3347 # technically should should flag if at least one side is missing a 3348 # space. This is done to avoid some false positives with shifts. 3349 match = Match(r'^(.*[^\s<])<[^\s=<,]', line) 3350 if match: 3351 (_, _, end_pos) = CloseExpression( 3352 clean_lines, linenum, len(match.group(1))) 3353 if end_pos <= -1: 3354 error(filename, linenum, 'whitespace/operators', 3, 3355 'Missing spaces around <') 3356 3357 # Look for > that is not surrounded by spaces. Similar to the 3358 # above, we only trigger if both sides are missing spaces to avoid 3359 # false positives with shifts. 3360 match = Match(r'^(.*[^-\s>])>[^\s=>,]', line) 3361 if match: 3362 (_, _, start_pos) = ReverseCloseExpression( 3363 clean_lines, linenum, len(match.group(1))) 3364 if start_pos <= -1: 3365 error(filename, linenum, 'whitespace/operators', 3, 3366 'Missing spaces around >') 3367 3368 # We allow no-spaces around << when used like this: 10<<20, but 3369 # not otherwise (particularly, not when used as streams) 3370 # 3371 # We also allow operators following an opening parenthesis, since 3372 # those tend to be macros that deal with operators. 3373 match = Search(r'(operator|[^\s(<])(?:L|UL|LL|ULL|l|ul|ll|ull)?<<([^\s,=<])', line) 3374 if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and 3375 not (match.group(1) == 'operator' and match.group(2) == ';')): 3376 error(filename, linenum, 'whitespace/operators', 3, 3377 'Missing spaces around <<') 3378 3379 # We allow no-spaces around >> for almost anything. This is because 3380 # C++11 allows ">>" to close nested templates, which accounts for 3381 # most cases when ">>" is not followed by a space. 3382 # 3383 # We still warn on ">>" followed by alpha character, because that is 3384 # likely due to ">>" being used for right shifts, e.g.: 3385 # value >> alpha 3386 # 3387 # When ">>" is used to close templates, the alphanumeric letter that 3388 # follows would be part of an identifier, and there should still be 3389 # a space separating the template type and the identifier. 3390 # type<type<type>> alpha 3391 match = Search(r'>>[a-zA-Z_]', line) 3392 if match: 3393 error(filename, linenum, 'whitespace/operators', 3, 3394 'Missing spaces around >>') 3395 3396 # There shouldn't be space around unary operators 3397 match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) 3398 if match: 3399 error(filename, linenum, 'whitespace/operators', 4, 3400 'Extra space for operator %s' % match.group(1)) 3401 3402 3403def CheckParenthesisSpacing(filename, clean_lines, linenum, error): 3404 """Checks for horizontal spacing around parentheses. 3405 3406 Args: 3407 filename: The name of the current file. 3408 clean_lines: A CleansedLines instance containing the file. 3409 linenum: The number of the line to check. 3410 error: The function to call with any errors found. 3411 """ 3412 line = clean_lines.elided[linenum] 3413 3414 # No spaces after an if, while, switch, or for 3415 match = Search(r' (if\(|for\(|while\(|switch\()', line) 3416 if match: 3417 error(filename, linenum, 'whitespace/parens', 5, 3418 'Missing space before ( in %s' % match.group(1)) 3419 3420 # For if/for/while/switch, the left and right parens should be 3421 # consistent about how many spaces are inside the parens, and 3422 # there should either be zero or one spaces inside the parens. 3423 # We don't want: "if ( foo)" or "if ( foo )". 3424 # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. 3425 match = Search(r'\b(if|for|while|switch)\s*' 3426 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', 3427 line) 3428 if match: 3429 if len(match.group(2)) != len(match.group(4)): 3430 if not (match.group(3) == ';' and 3431 len(match.group(2)) == 1 + len(match.group(4)) or 3432 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): 3433 error(filename, linenum, 'whitespace/parens', 5, 3434 'Mismatching spaces inside () in %s' % match.group(1)) 3435 if len(match.group(2)) not in [0, 1]: 3436 error(filename, linenum, 'whitespace/parens', 5, 3437 'Should have zero or one spaces inside ( and ) in %s' % 3438 match.group(1)) 3439 3440 3441def CheckCommaSpacing(filename, clean_lines, linenum, error): 3442 """Checks for horizontal spacing near commas and semicolons. 3443 3444 Args: 3445 filename: The name of the current file. 3446 clean_lines: A CleansedLines instance containing the file. 3447 linenum: The number of the line to check. 3448 error: The function to call with any errors found. 3449 """ 3450 raw = clean_lines.lines_without_raw_strings 3451 line = clean_lines.elided[linenum] 3452 3453 # You should always have a space after a comma (either as fn arg or operator) 3454 # 3455 # This does not apply when the non-space character following the 3456 # comma is another comma, since the only time when that happens is 3457 # for empty macro arguments. 3458 # 3459 # We run this check in two passes: first pass on elided lines to 3460 # verify that lines contain missing whitespaces, second pass on raw 3461 # lines to confirm that those missing whitespaces are not due to 3462 # elided comments. 3463 if (Search(r',[^,\s]', ReplaceAll(r'\boperator\s*,\s*\(', 'F(', line)) and 3464 Search(r',[^,\s]', raw[linenum])): 3465 error(filename, linenum, 'whitespace/comma', 3, 3466 'Missing space after ,') 3467 3468 # You should always have a space after a semicolon 3469 # except for few corner cases 3470 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more 3471 # space after ; 3472 if Search(r';[^\s};\\)/]', line): 3473 error(filename, linenum, 'whitespace/semicolon', 3, 3474 'Missing space after ;') 3475 3476 3477def _IsType(clean_lines, nesting_state, expr): 3478 """Check if expression looks like a type name, returns true if so. 3479 3480 Args: 3481 clean_lines: A CleansedLines instance containing the file. 3482 nesting_state: A NestingState instance which maintains information about 3483 the current stack of nested blocks being parsed. 3484 expr: The expression to check. 3485 Returns: 3486 True, if token looks like a type. 3487 """ 3488 # Keep only the last token in the expression 3489 last_word = Match(r'^.*(\b\S+)$', expr) 3490 if last_word: 3491 token = last_word.group(1) 3492 else: 3493 token = expr 3494 3495 # Match native types and stdint types 3496 if _TYPES.match(token): 3497 return True 3498 3499 # Try a bit harder to match templated types. Walk up the nesting 3500 # stack until we find something that resembles a typename 3501 # declaration for what we are looking for. 3502 typename_pattern = (r'\b(?:typename|class|struct)\s+' + re.escape(token) + 3503 r'\b') 3504 block_index = len(nesting_state.stack) - 1 3505 while block_index >= 0: 3506 if isinstance(nesting_state.stack[block_index], _NamespaceInfo): 3507 return False 3508 3509 # Found where the opening brace is. We want to scan from this 3510 # line up to the beginning of the function, minus a few lines. 3511 # template <typename Type1, // stop scanning here 3512 # ...> 3513 # class C 3514 # : public ... { // start scanning here 3515 last_line = nesting_state.stack[block_index].starting_linenum 3516 3517 next_block_start = 0 3518 if block_index > 0: 3519 next_block_start = nesting_state.stack[block_index - 1].starting_linenum 3520 first_line = last_line 3521 while first_line >= next_block_start: 3522 if clean_lines.elided[first_line].find('template') >= 0: 3523 break 3524 first_line -= 1 3525 if first_line < next_block_start: 3526 # Didn't find any "template" keyword before reaching the next block, 3527 # there are probably no template things to check for this block 3528 block_index -= 1 3529 continue 3530 3531 # Look for typename in the specified range 3532 for i in xrange(first_line, last_line + 1, 1): 3533 if Search(typename_pattern, clean_lines.elided[i]): 3534 return True 3535 block_index -= 1 3536 3537 return False 3538 3539 3540def CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error): 3541 """Checks for horizontal spacing near commas. 3542 3543 Args: 3544 filename: The name of the current file. 3545 clean_lines: A CleansedLines instance containing the file. 3546 linenum: The number of the line to check. 3547 nesting_state: A NestingState instance which maintains information about 3548 the current stack of nested blocks being parsed. 3549 error: The function to call with any errors found. 3550 """ 3551 line = clean_lines.elided[linenum] 3552 3553 # Except after an opening paren, or after another opening brace (in case of 3554 # an initializer list, for instance), you should have spaces before your 3555 # braces when they are delimiting blocks, classes, namespaces etc. 3556 # And since you should never have braces at the beginning of a line, 3557 # this is an easy test. Except that braces used for initialization don't 3558 # follow the same rule; we often don't want spaces before those. 3559 match = Match(r'^(.*[^ ({>]){', line) 3560 3561 if match: 3562 # Try a bit harder to check for brace initialization. This 3563 # happens in one of the following forms: 3564 # Constructor() : initializer_list_{} { ... } 3565 # Constructor{}.MemberFunction() 3566 # Type variable{}; 3567 # FunctionCall(type{}, ...); 3568 # LastArgument(..., type{}); 3569 # LOG(INFO) << type{} << " ..."; 3570 # map_of_type[{...}] = ...; 3571 # ternary = expr ? new type{} : nullptr; 3572 # OuterTemplate<InnerTemplateConstructor<Type>{}> 3573 # 3574 # We check for the character following the closing brace, and 3575 # silence the warning if it's one of those listed above, i.e. 3576 # "{.;,)<>]:". 3577 # 3578 # To account for nested initializer list, we allow any number of 3579 # closing braces up to "{;,)<". We can't simply silence the 3580 # warning on first sight of closing brace, because that would 3581 # cause false negatives for things that are not initializer lists. 3582 # Silence this: But not this: 3583 # Outer{ if (...) { 3584 # Inner{...} if (...){ // Missing space before { 3585 # }; } 3586 # 3587 # There is a false negative with this approach if people inserted 3588 # spurious semicolons, e.g. "if (cond){};", but we will catch the 3589 # spurious semicolon with a separate check. 3590 leading_text = match.group(1) 3591 (endline, endlinenum, endpos) = CloseExpression( 3592 clean_lines, linenum, len(match.group(1))) 3593 trailing_text = '' 3594 if endpos > -1: 3595 trailing_text = endline[endpos:] 3596 for offset in xrange(endlinenum + 1, 3597 min(endlinenum + 3, clean_lines.NumLines() - 1)): 3598 trailing_text += clean_lines.elided[offset] 3599 # We also suppress warnings for `uint64_t{expression}` etc., as the style 3600 # guide recommends brace initialization for integral types to avoid 3601 # overflow/truncation. 3602 if (not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text) 3603 and not _IsType(clean_lines, nesting_state, leading_text)): 3604 error(filename, linenum, 'whitespace/braces', 5, 3605 'Missing space before {') 3606 3607 # Make sure '} else {' has spaces. 3608 if Search(r'}else', line): 3609 error(filename, linenum, 'whitespace/braces', 5, 3610 'Missing space before else') 3611 3612 # You shouldn't have a space before a semicolon at the end of the line. 3613 # There's a special case for "for" since the style guide allows space before 3614 # the semicolon there. 3615 if Search(r':\s*;\s*$', line): 3616 error(filename, linenum, 'whitespace/semicolon', 5, 3617 'Semicolon defining empty statement. Use {} instead.') 3618 elif Search(r'^\s*;\s*$', line): 3619 error(filename, linenum, 'whitespace/semicolon', 5, 3620 'Line contains only semicolon. If this should be an empty statement, ' 3621 'use {} instead.') 3622 elif (Search(r'\s+;\s*$', line) and 3623 not Search(r'\bfor\b', line)): 3624 error(filename, linenum, 'whitespace/semicolon', 5, 3625 'Extra space before last semicolon. If this should be an empty ' 3626 'statement, use {} instead.') 3627 3628 3629def IsDecltype(clean_lines, linenum, column): 3630 """Check if the token ending on (linenum, column) is decltype(). 3631 3632 Args: 3633 clean_lines: A CleansedLines instance containing the file. 3634 linenum: the number of the line to check. 3635 column: end column of the token to check. 3636 Returns: 3637 True if this token is decltype() expression, False otherwise. 3638 """ 3639 (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column) 3640 if start_col < 0: 3641 return False 3642 if Search(r'\bdecltype\s*$', text[0:start_col]): 3643 return True 3644 return False 3645 3646 3647def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): 3648 """Checks for additional blank line issues related to sections. 3649 3650 Currently the only thing checked here is blank line before protected/private. 3651 3652 Args: 3653 filename: The name of the current file. 3654 clean_lines: A CleansedLines instance containing the file. 3655 class_info: A _ClassInfo objects. 3656 linenum: The number of the line to check. 3657 error: The function to call with any errors found. 3658 """ 3659 # Skip checks if the class is small, where small means 25 lines or less. 3660 # 25 lines seems like a good cutoff since that's the usual height of 3661 # terminals, and any class that can't fit in one screen can't really 3662 # be considered "small". 3663 # 3664 # Also skip checks if we are on the first line. This accounts for 3665 # classes that look like 3666 # class Foo { public: ... }; 3667 # 3668 # If we didn't find the end of the class, last_line would be zero, 3669 # and the check will be skipped by the first condition. 3670 if (class_info.last_line - class_info.starting_linenum <= 24 or 3671 linenum <= class_info.starting_linenum): 3672 return 3673 3674 matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum]) 3675 if matched: 3676 # Issue warning if the line before public/protected/private was 3677 # not a blank line, but don't do this if the previous line contains 3678 # "class" or "struct". This can happen two ways: 3679 # - We are at the beginning of the class. 3680 # - We are forward-declaring an inner class that is semantically 3681 # private, but needed to be public for implementation reasons. 3682 # Also ignores cases where the previous line ends with a backslash as can be 3683 # common when defining classes in C macros. 3684 prev_line = clean_lines.lines[linenum - 1] 3685 if (not IsBlankLine(prev_line) and 3686 not Search(r'\b(class|struct)\b', prev_line) and 3687 not Search(r'\\$', prev_line)): 3688 # Try a bit harder to find the beginning of the class. This is to 3689 # account for multi-line base-specifier lists, e.g.: 3690 # class Derived 3691 # : public Base { 3692 end_class_head = class_info.starting_linenum 3693 for i in range(class_info.starting_linenum, linenum): 3694 if Search(r'\{\s*$', clean_lines.lines[i]): 3695 end_class_head = i 3696 break 3697 if end_class_head < linenum - 1: 3698 error(filename, linenum, 'whitespace/blank_line', 3, 3699 '"%s:" should be preceded by a blank line' % matched.group(1)) 3700 3701 3702def GetPreviousNonBlankLine(clean_lines, linenum): 3703 """Return the most recent non-blank line and its line number. 3704 3705 Args: 3706 clean_lines: A CleansedLines instance containing the file contents. 3707 linenum: The number of the line to check. 3708 3709 Returns: 3710 A tuple with two elements. The first element is the contents of the last 3711 non-blank line before the current line, or the empty string if this is the 3712 first non-blank line. The second is the line number of that line, or -1 3713 if this is the first non-blank line. 3714 """ 3715 3716 prevlinenum = linenum - 1 3717 while prevlinenum >= 0: 3718 prevline = clean_lines.elided[prevlinenum] 3719 if not IsBlankLine(prevline): # if not a blank line... 3720 return (prevline, prevlinenum) 3721 prevlinenum -= 1 3722 return ('', -1) 3723 3724 3725def CheckBraces(filename, clean_lines, linenum, error): 3726 """Looks for misplaced braces (e.g. at the end of line). 3727 3728 Args: 3729 filename: The name of the current file. 3730 clean_lines: A CleansedLines instance containing the file. 3731 linenum: The number of the line to check. 3732 error: The function to call with any errors found. 3733 """ 3734 3735 line = clean_lines.elided[linenum] # get rid of comments and strings 3736 3737 if Match(r'\s*{\s*$', line): 3738 # We allow an open brace to start a line in the case where someone is using 3739 # braces in a block to explicitly create a new scope, which is commonly used 3740 # to control the lifetime of stack-allocated variables. Braces are also 3741 # used for brace initializers inside function calls. We don't detect this 3742 # perfectly: we just don't complain if the last non-whitespace character on 3743 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the 3744 # previous line starts a preprocessor block. We also allow a brace on the 3745 # following line if it is part of an array initialization and would not fit 3746 # within the 80 character limit of the preceding line. 3747 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 3748 # if (not Search(r'[,;:}{(]\s*$', prevline) and 3749 # not Match(r'\s*#', prevline) and 3750 # not (GetLineWidth(prevline) > _line_length - 2 and '[]' in prevline)): 3751 # error(filename, linenum, 'whitespace/braces', 4, 3752 # '{ should almost always be at the end of the previous line') 3753 3754 # An else clause should be on the same line as the preceding closing brace. 3755 if Match(r'\s*}\s*else\b\s*(?:if\b|\{|$)', line): 3756 error(filename, linenum, 'whitespace/newline', 4, 3757 'An else should appear on a new line after }') 3758 3759 # If braces come on one side of an else, they should be on both. 3760 # However, we have to worry about "else if" that spans multiple lines! 3761 if Search(r'else if\s*\(', line): # could be multi-line if 3762 brace_on_left = bool(Search(r'}\s*else if\s*\(', line)) 3763 # find the ( after the if 3764 pos = line.find('else if') 3765 pos = line.find('(', pos) 3766 if pos > 0: 3767 (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) 3768 brace_on_right = endline[endpos:].find('{') != -1 3769 if brace_on_left != brace_on_right: # must be brace after if 3770 error(filename, linenum, 'readability/braces', 5, 3771 'If an else has a brace on one side, it should have it on both') 3772 elif Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): 3773 error(filename, linenum, 'readability/braces', 5, 3774 'If an else has a brace on one side, it should have it on both') 3775 3776 # Likewise, an else should never have the else clause on the same line 3777 if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): 3778 error(filename, linenum, 'whitespace/newline', 4, 3779 'Else clause should never be on same line as else (use 2 lines)') 3780 3781 # In the same way, a do/while should never be on one line 3782 if Match(r'\s*do [^\s{]', line): 3783 error(filename, linenum, 'whitespace/newline', 4, 3784 'do/while clauses should not be on a single line') 3785 3786 # Check single-line if/else bodies. The style guide says 'curly braces are not 3787 # required for single-line statements'. We additionally allow multi-line, 3788 # single statements, but we reject anything with more than one semicolon in 3789 # it. This means that the first semicolon after the if should be at the end of 3790 # its line, and the line after that should have an indent level equal to or 3791 # lower than the if. We also check for ambiguous if/else nesting without 3792 # braces. 3793 if_else_match = Search(r'\b(if\s*\(|else\b)', line) 3794 if if_else_match and not Match(r'\s*#', line): 3795 if_indent = GetIndentLevel(line) 3796 endline, endlinenum, endpos = line, linenum, if_else_match.end() 3797 if_match = Search(r'\bif\s*\(', line) 3798 if if_match: 3799 # This could be a multiline if condition, so find the end first. 3800 pos = if_match.end() - 1 3801 (endline, endlinenum, endpos) = CloseExpression(clean_lines, linenum, pos) 3802 # Check for an opening brace, either directly after the if or on the next 3803 # line. If found, this isn't a single-statement conditional. 3804 if (not Match(r'\s*{', endline[endpos:]) 3805 and not (Match(r'\s*$', endline[endpos:]) 3806 and endlinenum < (len(clean_lines.elided) - 1) 3807 and Match(r'\s*{', clean_lines.elided[endlinenum + 1]))): 3808 while (endlinenum < len(clean_lines.elided) 3809 and ';' not in clean_lines.elided[endlinenum][endpos:]): 3810 endlinenum += 1 3811 endpos = 0 3812 if endlinenum < len(clean_lines.elided): 3813 endline = clean_lines.elided[endlinenum] 3814 # We allow a mix of whitespace and closing braces (e.g. for one-liner 3815 # methods) and a single \ after the semicolon (for macros) 3816 endpos = endline.find(';') 3817 if not Match(r';[\s}]*(\\?)$', endline[endpos:]): 3818 # Semicolon isn't the last character, there's something trailing. 3819 # Output a warning if the semicolon is not contained inside 3820 # a lambda expression. 3821 if not Match(r'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}]*\}\s*\)*[;,]\s*$', 3822 endline): 3823 error(filename, linenum, 'readability/braces', 4, 3824 'If/else bodies with multiple statements require braces') 3825 elif endlinenum < len(clean_lines.elided) - 1: 3826 # Make sure the next line is dedented 3827 next_line = clean_lines.elided[endlinenum + 1] 3828 next_indent = GetIndentLevel(next_line) 3829 # With ambiguous nested if statements, this will error out on the 3830 # if that *doesn't* match the else, regardless of whether it's the 3831 # inner one or outer one. 3832 if (if_match and Match(r'\s*else\b', next_line) 3833 and next_indent != if_indent): 3834 error(filename, linenum, 'readability/braces', 4, 3835 'Else clause should be indented at the same level as if. ' 3836 'Ambiguous nested if/else chains require braces.') 3837 elif next_indent > if_indent: 3838 error(filename, linenum, 'readability/braces', 4, 3839 'If/else bodies with multiple statements require braces') 3840 3841 3842def CheckTrailingSemicolon(filename, clean_lines, linenum, error): 3843 """Looks for redundant trailing semicolon. 3844 3845 Args: 3846 filename: The name of the current file. 3847 clean_lines: A CleansedLines instance containing the file. 3848 linenum: The number of the line to check. 3849 error: The function to call with any errors found. 3850 """ 3851 3852 line = clean_lines.elided[linenum] 3853 3854 # Block bodies should not be followed by a semicolon. Due to C++11 3855 # brace initialization, there are more places where semicolons are 3856 # required than not, so we use a whitelist approach to check these 3857 # rather than a blacklist. These are the places where "};" should 3858 # be replaced by just "}": 3859 # 1. Some flavor of block following closing parenthesis: 3860 # for (;;) {}; 3861 # while (...) {}; 3862 # switch (...) {}; 3863 # Function(...) {}; 3864 # if (...) {}; 3865 # if (...) else if (...) {}; 3866 # 3867 # 2. else block: 3868 # if (...) else {}; 3869 # 3870 # 3. const member function: 3871 # Function(...) const {}; 3872 # 3873 # 4. Block following some statement: 3874 # x = 42; 3875 # {}; 3876 # 3877 # 5. Block at the beginning of a function: 3878 # Function(...) { 3879 # {}; 3880 # } 3881 # 3882 # Note that naively checking for the preceding "{" will also match 3883 # braces inside multi-dimensional arrays, but this is fine since 3884 # that expression will not contain semicolons. 3885 # 3886 # 6. Block following another block: 3887 # while (true) {} 3888 # {}; 3889 # 3890 # 7. End of namespaces: 3891 # namespace {}; 3892 # 3893 # These semicolons seems far more common than other kinds of 3894 # redundant semicolons, possibly due to people converting classes 3895 # to namespaces. For now we do not warn for this case. 3896 # 3897 # Try matching case 1 first. 3898 match = Match(r'^(.*\)\s*)\{', line) 3899 if match: 3900 # Matched closing parenthesis (case 1). Check the token before the 3901 # matching opening parenthesis, and don't warn if it looks like a 3902 # macro. This avoids these false positives: 3903 # - macro that defines a base class 3904 # - multi-line macro that defines a base class 3905 # - macro that defines the whole class-head 3906 # 3907 # But we still issue warnings for macros that we know are safe to 3908 # warn, specifically: 3909 # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P 3910 # - TYPED_TEST 3911 # - INTERFACE_DEF 3912 # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: 3913 # 3914 # We implement a whitelist of safe macros instead of a blacklist of 3915 # unsafe macros, even though the latter appears less frequently in 3916 # google code and would have been easier to implement. This is because 3917 # the downside for getting the whitelist wrong means some extra 3918 # semicolons, while the downside for getting the blacklist wrong 3919 # would result in compile errors. 3920 # 3921 # In addition to macros, we also don't want to warn on 3922 # - Compound literals 3923 # - Lambdas 3924 # - alignas specifier with anonymous structs 3925 # - decltype 3926 closing_brace_pos = match.group(1).rfind(')') 3927 opening_parenthesis = ReverseCloseExpression( 3928 clean_lines, linenum, closing_brace_pos) 3929 if opening_parenthesis[2] > -1: 3930 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] 3931 macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix) 3932 func = Match(r'^(.*\])\s*$', line_prefix) 3933 if ((macro and 3934 macro.group(1) not in ( 3935 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', 3936 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', 3937 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or 3938 (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or 3939 Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or 3940 Search(r'\bdecltype$', line_prefix) or 3941 Search(r'\s+=\s*$', line_prefix)): 3942 match = None 3943 if (match and 3944 opening_parenthesis[1] > 1 and 3945 Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): 3946 # Multi-line lambda-expression 3947 match = None 3948 3949 else: 3950 # Try matching cases 2-3. 3951 match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) 3952 if not match: 3953 # Try matching cases 4-6. These are always matched on separate lines. 3954 # 3955 # Note that we can't simply concatenate the previous line to the 3956 # current line and do a single match, otherwise we may output 3957 # duplicate warnings for the blank line case: 3958 # if (cond) { 3959 # // blank line 3960 # } 3961 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 3962 if prevline and Search(r'[;{}]\s*$', prevline): 3963 match = Match(r'^(\s*)\{', line) 3964 3965 # Check matching closing brace 3966 if match: 3967 (endline, endlinenum, endpos) = CloseExpression( 3968 clean_lines, linenum, len(match.group(1))) 3969 if endpos > -1 and Match(r'^\s*;', endline[endpos:]): 3970 # Current {} pair is eligible for semicolon check, and we have found 3971 # the redundant semicolon, output warning here. 3972 # 3973 # Note: because we are scanning forward for opening braces, and 3974 # outputting warnings for the matching closing brace, if there are 3975 # nested blocks with trailing semicolons, we will get the error 3976 # messages in reversed order. 3977 3978 # We need to check the line forward for NOLINT 3979 raw_lines = clean_lines.raw_lines 3980 ParseNolintSuppressions(filename, raw_lines[endlinenum-1], endlinenum-1, 3981 error) 3982 ParseNolintSuppressions(filename, raw_lines[endlinenum], endlinenum, 3983 error) 3984 3985 error(filename, endlinenum, 'readability/braces', 4, 3986 "You don't need a ; after a }") 3987 3988 3989def CheckEmptyBlockBody(filename, clean_lines, linenum, error): 3990 """Look for empty loop/conditional body with only a single semicolon. 3991 3992 Args: 3993 filename: The name of the current file. 3994 clean_lines: A CleansedLines instance containing the file. 3995 linenum: The number of the line to check. 3996 error: The function to call with any errors found. 3997 """ 3998 3999 # Search for loop keywords at the beginning of the line. Because only 4000 # whitespaces are allowed before the keywords, this will also ignore most 4001 # do-while-loops, since those lines should start with closing brace. 4002 # 4003 # We also check "if" blocks here, since an empty conditional block 4004 # is likely an error. 4005 line = clean_lines.elided[linenum] 4006 matched = Match(r'\s*(for|while|if)\s*\(', line) 4007 if matched: 4008 # Find the end of the conditional expression. 4009 (end_line, end_linenum, end_pos) = CloseExpression( 4010 clean_lines, linenum, line.find('(')) 4011 4012 # Output warning if what follows the condition expression is a semicolon. 4013 # No warning for all other cases, including whitespace or newline, since we 4014 # have a separate check for semicolons preceded by whitespace. 4015 if end_pos >= 0 and Match(r';', end_line[end_pos:]): 4016 if matched.group(1) == 'if': 4017 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, 4018 'Empty conditional bodies should use {}') 4019 elif matched.group(1) == 'while' and linenum is not 0 \ 4020 and "}" in clean_lines.elided[linenum-1]: 4021 # Don't report an error for do-while loops. Works 4022 # by checking for a closing brace on the previous 4023 # line, since that means it's probably a do-while 4024 # loop. 4025 return 4026 else: 4027 error(filename, end_linenum, 'whitespace/empty_loop_body', 5, 4028 'Empty loop bodies should use {} or continue') 4029 4030 # Check for if statements that have completely empty bodies (no comments) 4031 # and no else clauses. 4032 if end_pos >= 0 and matched.group(1) == 'if': 4033 # Find the position of the opening { for the if statement. 4034 # Return without logging an error if it has no brackets. 4035 opening_linenum = end_linenum 4036 opening_line_fragment = end_line[end_pos:] 4037 # Loop until EOF or find anything that's not whitespace or opening {. 4038 while not Search(r'^\s*\{', opening_line_fragment): 4039 if Search(r'^(?!\s*$)', opening_line_fragment): 4040 # Conditional has no brackets. 4041 return 4042 opening_linenum += 1 4043 if opening_linenum == len(clean_lines.elided): 4044 # Couldn't find conditional's opening { or any code before EOF. 4045 return 4046 opening_line_fragment = clean_lines.elided[opening_linenum] 4047 # Set opening_line (opening_line_fragment may not be entire opening line). 4048 opening_line = clean_lines.elided[opening_linenum] 4049 4050 # Find the position of the closing }. 4051 opening_pos = opening_line_fragment.find('{') 4052 if opening_linenum == end_linenum: 4053 # We need to make opening_pos relative to the start of the entire line. 4054 opening_pos += end_pos 4055 (closing_line, closing_linenum, closing_pos) = CloseExpression( 4056 clean_lines, opening_linenum, opening_pos) 4057 if closing_pos < 0: 4058 return 4059 4060 # Now construct the body of the conditional. This consists of the portion 4061 # of the opening line after the {, all lines until the closing line, 4062 # and the portion of the closing line before the }. 4063 if (clean_lines.raw_lines[opening_linenum] != 4064 CleanseComments(clean_lines.raw_lines[opening_linenum])): 4065 # Opening line ends with a comment, so conditional isn't empty. 4066 return 4067 if closing_linenum > opening_linenum: 4068 # Opening line after the {. Ignore comments here since we checked above. 4069 body = list(opening_line[opening_pos+1:]) 4070 # All lines until closing line, excluding closing line, with comments. 4071 body.extend(clean_lines.raw_lines[opening_linenum+1:closing_linenum]) 4072 # Closing line before the }. Won't (and can't) have comments. 4073 body.append(clean_lines.elided[closing_linenum][:closing_pos-1]) 4074 body = '\n'.join(body) 4075 else: 4076 # If statement has brackets and fits on a single line. 4077 body = opening_line[opening_pos+1:closing_pos-1] 4078 4079 # Check if the body is empty 4080 if not _EMPTY_CONDITIONAL_BODY_PATTERN.search(body): 4081 return 4082 # The body is empty. Now make sure there's not an else clause. 4083 current_linenum = closing_linenum 4084 current_line_fragment = closing_line[closing_pos:] 4085 # Loop until EOF or find anything that's not whitespace or else clause. 4086 while Search(r'^\s*$|^(?=\s*else)', current_line_fragment): 4087 if Search(r'^(?=\s*else)', current_line_fragment): 4088 # Found an else clause, so don't log an error. 4089 return 4090 current_linenum += 1 4091 if current_linenum == len(clean_lines.elided): 4092 break 4093 current_line_fragment = clean_lines.elided[current_linenum] 4094 4095 # The body is empty and there's no else clause until EOF or other code. 4096 error(filename, end_linenum, 'whitespace/empty_if_body', 4, 4097 ('If statement had no body and no else clause')) 4098 4099 4100def FindCheckMacro(line): 4101 """Find a replaceable CHECK-like macro. 4102 4103 Args: 4104 line: line to search on. 4105 Returns: 4106 (macro name, start position), or (None, -1) if no replaceable 4107 macro is found. 4108 """ 4109 for macro in _CHECK_MACROS: 4110 i = line.find(macro) 4111 if i >= 0: 4112 # Find opening parenthesis. Do a regular expression match here 4113 # to make sure that we are matching the expected CHECK macro, as 4114 # opposed to some other macro that happens to contain the CHECK 4115 # substring. 4116 matched = Match(r'^(.*\b' + macro + r'\s*)\(', line) 4117 if not matched: 4118 continue 4119 return (macro, len(matched.group(1))) 4120 return (None, -1) 4121 4122 4123def CheckCheck(filename, clean_lines, linenum, error): 4124 """Checks the use of CHECK and EXPECT macros. 4125 4126 Args: 4127 filename: The name of the current file. 4128 clean_lines: A CleansedLines instance containing the file. 4129 linenum: The number of the line to check. 4130 error: The function to call with any errors found. 4131 """ 4132 4133 # Decide the set of replacement macros that should be suggested 4134 lines = clean_lines.elided 4135 (check_macro, start_pos) = FindCheckMacro(lines[linenum]) 4136 if not check_macro: 4137 return 4138 4139 # Find end of the boolean expression by matching parentheses 4140 (last_line, end_line, end_pos) = CloseExpression( 4141 clean_lines, linenum, start_pos) 4142 if end_pos < 0: 4143 return 4144 4145 # If the check macro is followed by something other than a 4146 # semicolon, assume users will log their own custom error messages 4147 # and don't suggest any replacements. 4148 if not Match(r'\s*;', last_line[end_pos:]): 4149 return 4150 4151 if linenum == end_line: 4152 expression = lines[linenum][start_pos + 1:end_pos - 1] 4153 else: 4154 expression = lines[linenum][start_pos + 1:] 4155 for i in xrange(linenum + 1, end_line): 4156 expression += lines[i] 4157 expression += last_line[0:end_pos - 1] 4158 4159 # Parse expression so that we can take parentheses into account. 4160 # This avoids false positives for inputs like "CHECK((a < 4) == b)", 4161 # which is not replaceable by CHECK_LE. 4162 lhs = '' 4163 rhs = '' 4164 operator = None 4165 while expression: 4166 matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||' 4167 r'==|!=|>=|>|<=|<|\()(.*)$', expression) 4168 if matched: 4169 token = matched.group(1) 4170 if token == '(': 4171 # Parenthesized operand 4172 expression = matched.group(2) 4173 (end, _) = FindEndOfExpressionInLine(expression, 0, ['(']) 4174 if end < 0: 4175 return # Unmatched parenthesis 4176 lhs += '(' + expression[0:end] 4177 expression = expression[end:] 4178 elif token in ('&&', '||'): 4179 # Logical and/or operators. This means the expression 4180 # contains more than one term, for example: 4181 # CHECK(42 < a && a < b); 4182 # 4183 # These are not replaceable with CHECK_LE, so bail out early. 4184 return 4185 elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'): 4186 # Non-relational operator 4187 lhs += token 4188 expression = matched.group(2) 4189 else: 4190 # Relational operator 4191 operator = token 4192 rhs = matched.group(2) 4193 break 4194 else: 4195 # Unparenthesized operand. Instead of appending to lhs one character 4196 # at a time, we do another regular expression match to consume several 4197 # characters at once if possible. Trivial benchmark shows that this 4198 # is more efficient when the operands are longer than a single 4199 # character, which is generally the case. 4200 matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression) 4201 if not matched: 4202 matched = Match(r'^(\s*\S)(.*)$', expression) 4203 if not matched: 4204 break 4205 lhs += matched.group(1) 4206 expression = matched.group(2) 4207 4208 # Only apply checks if we got all parts of the boolean expression 4209 if not (lhs and operator and rhs): 4210 return 4211 4212 # Check that rhs do not contain logical operators. We already know 4213 # that lhs is fine since the loop above parses out && and ||. 4214 if rhs.find('&&') > -1 or rhs.find('||') > -1: 4215 return 4216 4217 # At least one of the operands must be a constant literal. This is 4218 # to avoid suggesting replacements for unprintable things like 4219 # CHECK(variable != iterator) 4220 # 4221 # The following pattern matches decimal, hex integers, strings, and 4222 # characters (in that order). 4223 lhs = lhs.strip() 4224 rhs = rhs.strip() 4225 match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$' 4226 if Match(match_constant, lhs) or Match(match_constant, rhs): 4227 # Note: since we know both lhs and rhs, we can provide a more 4228 # descriptive error message like: 4229 # Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42) 4230 # Instead of: 4231 # Consider using CHECK_EQ instead of CHECK(a == b) 4232 # 4233 # We are still keeping the less descriptive message because if lhs 4234 # or rhs gets long, the error message might become unreadable. 4235 error(filename, linenum, 'readability/check', 2, 4236 'Consider using %s instead of %s(a %s b)' % ( 4237 _CHECK_REPLACEMENT[check_macro][operator], 4238 check_macro, operator)) 4239 4240 4241def CheckAltTokens(filename, clean_lines, linenum, error): 4242 """Check alternative keywords being used in boolean expressions. 4243 4244 Args: 4245 filename: The name of the current file. 4246 clean_lines: A CleansedLines instance containing the file. 4247 linenum: The number of the line to check. 4248 error: The function to call with any errors found. 4249 """ 4250 line = clean_lines.elided[linenum] 4251 4252 # Avoid preprocessor lines 4253 if Match(r'^\s*#', line): 4254 return 4255 4256 # Last ditch effort to avoid multi-line comments. This will not help 4257 # if the comment started before the current line or ended after the 4258 # current line, but it catches most of the false positives. At least, 4259 # it provides a way to workaround this warning for people who use 4260 # multi-line comments in preprocessor macros. 4261 # 4262 # TODO(unknown): remove this once cpplint has better support for 4263 # multi-line comments. 4264 if line.find('/*') >= 0 or line.find('*/') >= 0: 4265 return 4266 4267 for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line): 4268 error(filename, linenum, 'readability/alt_tokens', 2, 4269 'Use operator %s instead of %s' % ( 4270 _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1))) 4271 4272 4273def GetLineWidth(line): 4274 """Determines the width of the line in column positions. 4275 4276 Args: 4277 line: A string, which may be a Unicode string. 4278 4279 Returns: 4280 The width of the line in column positions, accounting for Unicode 4281 combining characters and wide characters. 4282 """ 4283 if isinstance(line, unicode): 4284 width = 0 4285 for uc in unicodedata.normalize('NFC', line): 4286 if unicodedata.east_asian_width(uc) in ('W', 'F'): 4287 width += 2 4288 elif not unicodedata.combining(uc): 4289 width += 1 4290 return width 4291 else: 4292 return len(line) 4293 4294 4295def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, 4296 error): 4297 """Checks rules from the 'C++ style rules' section of cppguide.html. 4298 4299 Most of these rules are hard to test (naming, comment style), but we 4300 do what we can. In particular we check for 2-space indents, line lengths, 4301 tab usage, spaces inside code, etc. 4302 4303 Args: 4304 filename: The name of the current file. 4305 clean_lines: A CleansedLines instance containing the file. 4306 linenum: The number of the line to check. 4307 file_extension: The extension (without the dot) of the filename. 4308 nesting_state: A NestingState instance which maintains information about 4309 the current stack of nested blocks being parsed. 4310 error: The function to call with any errors found. 4311 """ 4312 4313 # Don't use "elided" lines here, otherwise we can't check commented lines. 4314 # Don't want to use "raw" either, because we don't want to check inside C++11 4315 # raw strings, 4316 raw_lines = clean_lines.lines_without_raw_strings 4317 line = raw_lines[linenum] 4318 prev = raw_lines[linenum - 1] if linenum > 0 else '' 4319 4320 if line.find('\t') != -1: 4321 error(filename, linenum, 'whitespace/tab', 1, 4322 'Tab found; better to use spaces') 4323 4324 # One or three blank spaces at the beginning of the line is weird; it's 4325 # hard to reconcile that with 2-space indents. 4326 # NOTE: here are the conditions rob pike used for his tests. Mine aren't 4327 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces 4328 # if(RLENGTH > 20) complain = 0; 4329 # if(match($0, " +(error|private|public|protected):")) complain = 0; 4330 # if(match(prev, "&& *$")) complain = 0; 4331 # if(match(prev, "\\|\\| *$")) complain = 0; 4332 # if(match(prev, "[\",=><] *$")) complain = 0; 4333 # if(match($0, " <<")) complain = 0; 4334 # if(match(prev, " +for \\(")) complain = 0; 4335 # if(prevodd && match(prevprev, " +for \\(")) complain = 0; 4336 scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' 4337 classinfo = nesting_state.InnermostClass() 4338 initial_spaces = 0 4339 cleansed_line = clean_lines.elided[linenum] 4340 while initial_spaces < len(line) and line[initial_spaces] == ' ': 4341 initial_spaces += 1 4342 # There are certain situations we allow one space, notably for 4343 # section labels, and also lines containing multi-line raw strings. 4344 # We also don't check for lines that look like continuation lines 4345 # (of lines ending in double quotes, commas, equals, or angle brackets) 4346 # because the rules for how to indent those are non-trivial. 4347 if (not Search(r'[",=><] *$', prev) and 4348 (initial_spaces == 1 or initial_spaces == 3) and 4349 not Match(scope_or_label_pattern, cleansed_line) and 4350 not (clean_lines.raw_lines[linenum] != line and 4351 Match(r'^\s*""', line))): 4352 error(filename, linenum, 'whitespace/indent', 3, 4353 'Weird number of spaces at line-start. ' 4354 'Are you using a 2-space indent?') 4355 4356 if line and line[-1].isspace(): 4357 error(filename, linenum, 'whitespace/end_of_line', 4, 4358 'Line ends in whitespace. Consider deleting these extra spaces.') 4359 4360 # Check if the line is a header guard. 4361 is_header_guard = False 4362 if IsHeaderExtension(file_extension): 4363 cppvar = GetHeaderGuardCPPVariable(filename) 4364 if (line.startswith('#ifndef %s' % cppvar) or 4365 line.startswith('#define %s' % cppvar) or 4366 line.startswith('#endif // %s' % cppvar)): 4367 is_header_guard = True 4368 # #include lines and header guards can be long, since there's no clean way to 4369 # split them. 4370 # 4371 # URLs can be long too. It's possible to split these, but it makes them 4372 # harder to cut&paste. 4373 # 4374 # The "$Id:...$" comment may also get very long without it being the 4375 # developers fault. 4376 if (not line.startswith('#include') and not is_header_guard and 4377 not Match(r'^\s*//.*http(s?)://\S*$', line) and 4378 not Match(r'^\s*//\s*[^\s]*$', line) and 4379 not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): 4380 line_width = GetLineWidth(line) 4381 if line_width > _line_length: 4382 error(filename, linenum, 'whitespace/line_length', 2, 4383 'Lines should be <= %i characters long' % _line_length) 4384 4385 if (cleansed_line.count(';') > 1 and 4386 # for loops are allowed two ;'s (and may run over two lines). 4387 cleansed_line.find('for') == -1 and 4388 (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or 4389 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and 4390 # It's ok to have many commands in a switch case that fits in 1 line 4391 not ((cleansed_line.find('case ') != -1 or 4392 cleansed_line.find('default:') != -1) and 4393 cleansed_line.find('break;') != -1)): 4394 error(filename, linenum, 'whitespace/newline', 0, 4395 'More than one command on the same line') 4396 4397 # Some more style checks 4398 CheckBraces(filename, clean_lines, linenum, error) 4399 CheckTrailingSemicolon(filename, clean_lines, linenum, error) 4400 CheckEmptyBlockBody(filename, clean_lines, linenum, error) 4401 CheckSpacing(filename, clean_lines, linenum, nesting_state, error) 4402 CheckOperatorSpacing(filename, clean_lines, linenum, error) 4403 CheckParenthesisSpacing(filename, clean_lines, linenum, error) 4404 CheckCommaSpacing(filename, clean_lines, linenum, error) 4405 CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error) 4406 CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) 4407 CheckCheck(filename, clean_lines, linenum, error) 4408 CheckAltTokens(filename, clean_lines, linenum, error) 4409 classinfo = nesting_state.InnermostClass() 4410 if classinfo: 4411 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) 4412 4413 4414_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') 4415# Matches the first component of a filename delimited by -s and _s. That is: 4416# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' 4417# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' 4418# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' 4419# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' 4420_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') 4421 4422 4423def _DropCommonSuffixes(filename): 4424 """Drops common suffixes like _test.cc or -inl.h from filename. 4425 4426 For example: 4427 >>> _DropCommonSuffixes('foo/foo-inl.h') 4428 'foo/foo' 4429 >>> _DropCommonSuffixes('foo/bar/foo.cc') 4430 'foo/bar/foo' 4431 >>> _DropCommonSuffixes('foo/foo_internal.h') 4432 'foo/foo' 4433 >>> _DropCommonSuffixes('foo/foo_unusualinternal.h') 4434 'foo/foo_unusualinternal' 4435 4436 Args: 4437 filename: The input filename. 4438 4439 Returns: 4440 The filename with the common suffix removed. 4441 """ 4442 for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', 4443 'inl.h', 'impl.h', 'internal.h'): 4444 if (filename.endswith(suffix) and len(filename) > len(suffix) and 4445 filename[-len(suffix) - 1] in ('-', '_')): 4446 return filename[:-len(suffix) - 1] 4447 return os.path.splitext(filename)[0] 4448 4449 4450def _ClassifyInclude(fileinfo, include, is_system): 4451 """Figures out what kind of header 'include' is. 4452 4453 Args: 4454 fileinfo: The current file cpplint is running over. A FileInfo instance. 4455 include: The path to a #included file. 4456 is_system: True if the #include used <> rather than "". 4457 4458 Returns: 4459 One of the _XXX_HEADER constants. 4460 4461 For example: 4462 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True) 4463 _C_SYS_HEADER 4464 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True) 4465 _CPP_SYS_HEADER 4466 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) 4467 _LIKELY_MY_HEADER 4468 >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), 4469 ... 'bar/foo_other_ext.h', False) 4470 _POSSIBLE_MY_HEADER 4471 >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) 4472 _OTHER_HEADER 4473 """ 4474 # This is a list of all standard c++ header files, except 4475 # those already checked for above. 4476 is_cpp_h = include in _CPP_HEADERS 4477 4478 if is_system: 4479 if is_cpp_h or include.endswith(".hh"): 4480 return _CPP_SYS_HEADER 4481 else: 4482 return _C_SYS_HEADER 4483 4484 # If the target file and the include we're checking share a 4485 # basename when we drop common extensions, and the include 4486 # lives in . , then it's likely to be owned by the target file. 4487 target_dir, target_base = ( 4488 os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName()))) 4489 include_dir, include_base = os.path.split(_DropCommonSuffixes(include)) 4490 if target_base == include_base and ( 4491 include_dir == target_dir or 4492 include_dir == os.path.normpath(target_dir + '/../public')): 4493 return _LIKELY_MY_HEADER 4494 4495 # If the target and include share some initial basename 4496 # component, it's possible the target is implementing the 4497 # include, so it's allowed to be first, but we'll never 4498 # complain if it's not there. 4499 target_first_component = _RE_FIRST_COMPONENT.match(target_base) 4500 include_first_component = _RE_FIRST_COMPONENT.match(include_base) 4501 if (target_first_component and include_first_component and 4502 target_first_component.group(0) == 4503 include_first_component.group(0)): 4504 return _POSSIBLE_MY_HEADER 4505 4506 return _OTHER_HEADER 4507 4508 4509 4510def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): 4511 """Check rules that are applicable to #include lines. 4512 4513 Strings on #include lines are NOT removed from elided line, to make 4514 certain tasks easier. However, to prevent false positives, checks 4515 applicable to #include lines in CheckLanguage must be put here. 4516 4517 Args: 4518 filename: The name of the current file. 4519 clean_lines: A CleansedLines instance containing the file. 4520 linenum: The number of the line to check. 4521 include_state: An _IncludeState instance in which the headers are inserted. 4522 error: The function to call with any errors found. 4523 """ 4524 fileinfo = FileInfo(filename) 4525 line = clean_lines.lines[linenum] 4526 4527 # "include" should use the new style "foo/bar.h" instead of just "bar.h" 4528 # Only do this check if the included header follows google naming 4529 # conventions. If not, assume that it's a 3rd party API that 4530 # requires special include conventions. 4531 # 4532 # We also make an exception for Lua headers, which follow google 4533 # naming convention but not the include convention. 4534 # match = Match(r'#include\s*"([^/]+\.h)"', line) 4535 # if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)): 4536 # error(filename, linenum, 'build/include', 4, 4537 # 'Include the directory when naming .h files') 4538 4539 # we shouldn't include a file more than once. actually, there are a 4540 # handful of instances where doing so is okay, but in general it's 4541 # not. 4542 match = _RE_PATTERN_INCLUDE.search(line) 4543 if match: 4544 include = match.group(2) 4545 is_system = (match.group(1) == '<') 4546 duplicate_line = include_state.FindHeader(include) 4547 if duplicate_line >= 0: 4548 error(filename, linenum, 'build/include', 4, 4549 '"%s" already included at %s:%s' % 4550 (include, filename, duplicate_line)) 4551 elif (include.endswith('.cc') and 4552 os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)): 4553 error(filename, linenum, 'build/include', 4, 4554 'Do not include .cc files from other packages') 4555 elif not _THIRD_PARTY_HEADERS_PATTERN.match(include): 4556 include_state.include_list[-1].append((include, linenum)) 4557 4558 # We want to ensure that headers appear in the right order: 4559 # 1) for foo.cc, foo.h (preferred location) 4560 # 2) c system files 4561 # 3) cpp system files 4562 # 4) for foo.cc, foo.h (deprecated location) 4563 # 5) other google headers 4564 # 4565 # We classify each include statement as one of those 5 types 4566 # using a number of techniques. The include_state object keeps 4567 # track of the highest type seen, and complains if we see a 4568 # lower type after that. 4569 error_message = include_state.CheckNextIncludeOrder( 4570 _ClassifyInclude(fileinfo, include, is_system)) 4571 if error_message: 4572 error(filename, linenum, 'build/include_order', 4, 4573 '%s. Should be: %s.h, c system, c++ system, other.' % 4574 (error_message, fileinfo.BaseName())) 4575 canonical_include = include_state.CanonicalizeAlphabeticalOrder(include) 4576 if not include_state.IsInAlphabeticalOrder( 4577 clean_lines, linenum, canonical_include): 4578 error(filename, linenum, 'build/include_alpha', 4, 4579 'Include "%s" not in alphabetical order' % include) 4580 include_state.SetLastHeader(canonical_include) 4581 4582 4583 4584def _GetTextInside(text, start_pattern): 4585 r"""Retrieves all the text between matching open and close parentheses. 4586 4587 Given a string of lines and a regular expression string, retrieve all the text 4588 following the expression and between opening punctuation symbols like 4589 (, [, or {, and the matching close-punctuation symbol. This properly nested 4590 occurrences of the punctuations, so for the text like 4591 printf(a(), b(c())); 4592 a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. 4593 start_pattern must match string having an open punctuation symbol at the end. 4594 4595 Args: 4596 text: The lines to extract text. Its comments and strings must be elided. 4597 It can be single line and can span multiple lines. 4598 start_pattern: The regexp string indicating where to start extracting 4599 the text. 4600 Returns: 4601 The extracted text. 4602 None if either the opening string or ending punctuation could not be found. 4603 """ 4604 # TODO(unknown): Audit cpplint.py to see what places could be profitably 4605 # rewritten to use _GetTextInside (and use inferior regexp matching today). 4606 4607 # Give opening punctuations to get the matching close-punctuations. 4608 matching_punctuation = {'(': ')', '{': '}', '[': ']'} 4609 closing_punctuation = set(matching_punctuation.itervalues()) 4610 4611 # Find the position to start extracting text. 4612 match = re.search(start_pattern, text, re.M) 4613 if not match: # start_pattern not found in text. 4614 return None 4615 start_position = match.end(0) 4616 4617 assert start_position > 0, ( 4618 'start_pattern must ends with an opening punctuation.') 4619 assert text[start_position - 1] in matching_punctuation, ( 4620 'start_pattern must ends with an opening punctuation.') 4621 # Stack of closing punctuations we expect to have in text after position. 4622 punctuation_stack = [matching_punctuation[text[start_position - 1]]] 4623 position = start_position 4624 while punctuation_stack and position < len(text): 4625 if text[position] == punctuation_stack[-1]: 4626 punctuation_stack.pop() 4627 elif text[position] in closing_punctuation: 4628 # A closing punctuation without matching opening punctuations. 4629 return None 4630 elif text[position] in matching_punctuation: 4631 punctuation_stack.append(matching_punctuation[text[position]]) 4632 position += 1 4633 if punctuation_stack: 4634 # Opening punctuations left without matching close-punctuations. 4635 return None 4636 # punctuations match. 4637 return text[start_position:position - 1] 4638 4639 4640# Patterns for matching call-by-reference parameters. 4641# 4642# Supports nested templates up to 2 levels deep using this messy pattern: 4643# < (?: < (?: < [^<>]* 4644# > 4645# | [^<>] )* 4646# > 4647# | [^<>] )* 4648# > 4649_RE_PATTERN_IDENT = r'[_a-zA-Z]\w*' # =~ [[:alpha:]][[:alnum:]]* 4650_RE_PATTERN_TYPE = ( 4651 r'(?:const\s+)?(?:typename\s+|class\s+|struct\s+|union\s+|enum\s+)?' 4652 r'(?:\w|' 4653 r'\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|' 4654 r'::)+') 4655# A call-by-reference parameter ends with '& identifier'. 4656_RE_PATTERN_REF_PARAM = re.compile( 4657 r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*' 4658 r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]') 4659# A call-by-const-reference parameter either ends with 'const& identifier' 4660# or looks like 'const type& identifier' when 'type' is atomic. 4661_RE_PATTERN_CONST_REF_PARAM = ( 4662 r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT + 4663 r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')') 4664# Stream types. 4665_RE_PATTERN_REF_STREAM_PARAM = ( 4666 r'(?:.*stream\s*&\s*' + _RE_PATTERN_IDENT + r')') 4667 4668 4669def CheckLanguage(filename, clean_lines, linenum, file_extension, 4670 include_state, nesting_state, error): 4671 """Checks rules from the 'C++ language rules' section of cppguide.html. 4672 4673 Some of these rules are hard to test (function overloading, using 4674 uint32 inappropriately), but we do the best we can. 4675 4676 Args: 4677 filename: The name of the current file. 4678 clean_lines: A CleansedLines instance containing the file. 4679 linenum: The number of the line to check. 4680 file_extension: The extension (without the dot) of the filename. 4681 include_state: An _IncludeState instance in which the headers are inserted. 4682 nesting_state: A NestingState instance which maintains information about 4683 the current stack of nested blocks being parsed. 4684 error: The function to call with any errors found. 4685 """ 4686 # If the line is empty or consists of entirely a comment, no need to 4687 # check it. 4688 line = clean_lines.elided[linenum] 4689 if not line: 4690 return 4691 4692 match = _RE_PATTERN_INCLUDE.search(line) 4693 if match: 4694 CheckIncludeLine(filename, clean_lines, linenum, include_state, error) 4695 return 4696 4697 # Reset include state across preprocessor directives. This is meant 4698 # to silence warnings for conditional includes. 4699 match = Match(r'^\s*#\s*(if|ifdef|ifndef|elif|else|endif)\b', line) 4700 if match: 4701 include_state.ResetSection(match.group(1)) 4702 4703 # Make Windows paths like Unix. 4704 fullname = os.path.abspath(filename).replace('\\', '/') 4705 4706 # Perform other checks now that we are sure that this is not an include line 4707 CheckCasts(filename, clean_lines, linenum, error) 4708 CheckGlobalStatic(filename, clean_lines, linenum, error) 4709 CheckPrintf(filename, clean_lines, linenum, error) 4710 4711 if IsHeaderExtension(file_extension): 4712 # TODO(unknown): check that 1-arg constructors are explicit. 4713 # How to tell it's a constructor? 4714 # (handled in CheckForNonStandardConstructs for now) 4715 # TODO(unknown): check that classes declare or disable copy/assign 4716 # (level 1 error) 4717 pass 4718 4719 # Check if people are using the verboten C basic types. The only exception 4720 # we regularly allow is "unsigned short port" for port. 4721 if Search(r'\bshort port\b', line): 4722 if not Search(r'\bunsigned short port\b', line): 4723 error(filename, linenum, 'runtime/int', 4, 4724 'Use "unsigned short" for ports, not "short"') 4725 else: 4726 match = Search(r'\b(short|long(?! +double)|long long)\b', line) 4727 if match: 4728 error(filename, linenum, 'runtime/int', 4, 4729 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) 4730 4731 # Check if some verboten operator overloading is going on 4732 # TODO(unknown): catch out-of-line unary operator&: 4733 # class X {}; 4734 # int operator&(const X& x) { return 42; } // unary operator& 4735 # The trick is it's hard to tell apart from binary operator&: 4736 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& 4737 if Search(r'\boperator\s*&\s*\(\s*\)', line): 4738 error(filename, linenum, 'runtime/operator', 4, 4739 'Unary operator& is dangerous. Do not use it.') 4740 4741 # Check for suspicious usage of "if" like 4742 # } if (a == b) { 4743 if Search(r'\}\s*if\s*\(', line): 4744 error(filename, linenum, 'readability/braces', 4, 4745 'Did you mean "else if"? If not, start a new line for "if".') 4746 4747 # Check for potential format string bugs like printf(foo). 4748 # We constrain the pattern not to pick things like DocidForPrintf(foo). 4749 # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) 4750 # TODO(unknown): Catch the following case. Need to change the calling 4751 # convention of the whole function to process multiple line to handle it. 4752 # printf( 4753 # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line); 4754 printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(') 4755 if printf_args: 4756 match = Match(r'([\w.\->()]+)$', printf_args) 4757 if match and match.group(1) != '__VA_ARGS__': 4758 function_name = re.search(r'\b((?:string)?printf)\s*\(', 4759 line, re.I).group(1) 4760 error(filename, linenum, 'runtime/printf', 4, 4761 'Potential format string bug. Do %s("%%s", %s) instead.' 4762 % (function_name, match.group(1))) 4763 4764 # Check for potential memset bugs like memset(buf, sizeof(buf), 0). 4765 match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) 4766 if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)): 4767 error(filename, linenum, 'runtime/memset', 4, 4768 'Did you mean "memset(%s, 0, %s)"?' 4769 % (match.group(1), match.group(2))) 4770 4771 # if Search(r'\busing namespace\b', line): 4772 # error(filename, linenum, 'build/namespaces', 5, 4773 # 'Do not use namespace using-directives. ' 4774 # 'Use using-declarations instead.') 4775 4776 # Detect variable-length arrays. 4777 match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) 4778 if (match and match.group(2) != 'return' and match.group(2) != 'delete' and 4779 match.group(3).find(']') == -1): 4780 # Split the size using space and arithmetic operators as delimiters. 4781 # If any of the resulting tokens are not compile time constants then 4782 # report the error. 4783 tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3)) 4784 is_const = True 4785 skip_next = False 4786 for tok in tokens: 4787 if skip_next: 4788 skip_next = False 4789 continue 4790 4791 if Search(r'sizeof\(.+\)', tok): continue 4792 if Search(r'arraysize\(\w+\)', tok): continue 4793 4794 tok = tok.lstrip('(') 4795 tok = tok.rstrip(')') 4796 if not tok: continue 4797 if Match(r'\d+', tok): continue 4798 if Match(r'0[xX][0-9a-fA-F]+', tok): continue 4799 if Match(r'k[A-Z0-9]\w*', tok): continue 4800 if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue 4801 if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue 4802 # A catch all for tricky sizeof cases, including 'sizeof expression', 4803 # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)' 4804 # requires skipping the next token because we split on ' ' and '*'. 4805 if tok.startswith('sizeof'): 4806 skip_next = True 4807 continue 4808 is_const = False 4809 break 4810 if not is_const: 4811 error(filename, linenum, 'runtime/arrays', 1, 4812 'Do not use variable-length arrays. Use an appropriately named ' 4813 "('k' followed by CamelCase) compile-time constant for the size.") 4814 4815 # Check for use of unnamed namespaces in header files. Registration 4816 # macros are typically OK, so we allow use of "namespace {" on lines 4817 # that end with backslashes. 4818 if (IsHeaderExtension(file_extension) 4819 and Search(r'\bnamespace\s*{', line) 4820 and line[-1] != '\\'): 4821 error(filename, linenum, 'build/namespaces', 4, 4822 'Do not use unnamed namespaces in header files. See ' 4823 'https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' 4824 ' for more information.') 4825 4826 4827def CheckGlobalStatic(filename, clean_lines, linenum, error): 4828 """Check for unsafe global or static objects. 4829 4830 Args: 4831 filename: The name of the current file. 4832 clean_lines: A CleansedLines instance containing the file. 4833 linenum: The number of the line to check. 4834 error: The function to call with any errors found. 4835 """ 4836 line = clean_lines.elided[linenum] 4837 4838 # Match two lines at a time to support multiline declarations 4839 if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): 4840 line += clean_lines.elided[linenum + 1].strip() 4841 4842 # Check for people declaring static/global STL strings at the top level. 4843 # This is dangerous because the C++ language does not guarantee that 4844 # globals with constructors are initialized before the first access, and 4845 # also because globals can be destroyed when some threads are still running. 4846 # TODO(unknown): Generalize this to also find static unique_ptr instances. 4847 # TODO(unknown): File bugs for clang-tidy to find these. 4848 match = Match( 4849 r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +' 4850 r'([a-zA-Z0-9_:]+)\b(.*)', 4851 line) 4852 4853 # Remove false positives: 4854 # - String pointers (as opposed to values). 4855 # string *pointer 4856 # const string *pointer 4857 # string const *pointer 4858 # string *const pointer 4859 # 4860 # - Functions and template specializations. 4861 # string Function<Type>(... 4862 # string Class<Type>::Method(... 4863 # 4864 # - Operators. These are matched separately because operator names 4865 # cross non-word boundaries, and trying to match both operators 4866 # and functions at the same time would decrease accuracy of 4867 # matching identifiers. 4868 # string Class::operator*() 4869 if (match and 4870 not Search(r'\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w', line) and 4871 not Search(r'\boperator\W', line) and 4872 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(4))): 4873 if Search(r'\bconst\b', line): 4874 error(filename, linenum, 'runtime/string', 4, 4875 'For a static/global string constant, use a C style string ' 4876 'instead: "%schar%s %s[]".' % 4877 (match.group(1), match.group(2) or '', match.group(3))) 4878 else: 4879 error(filename, linenum, 'runtime/string', 4, 4880 'Static/global string variables are not permitted.') 4881 4882 if (Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line) or 4883 Search(r'\b([A-Za-z0-9_]*_)\(CHECK_NOTNULL\(\1\)\)', line)): 4884 error(filename, linenum, 'runtime/init', 4, 4885 'You seem to be initializing a member variable with itself.') 4886 4887 4888def CheckPrintf(filename, clean_lines, linenum, error): 4889 """Check for printf related issues. 4890 4891 Args: 4892 filename: The name of the current file. 4893 clean_lines: A CleansedLines instance containing the file. 4894 linenum: The number of the line to check. 4895 error: The function to call with any errors found. 4896 """ 4897 line = clean_lines.elided[linenum] 4898 4899 # When snprintf is used, the second argument shouldn't be a literal. 4900 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) 4901 if match and match.group(2) != '0': 4902 # If 2nd arg is zero, snprintf is used to calculate size. 4903 error(filename, linenum, 'runtime/printf', 3, 4904 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' 4905 'to snprintf.' % (match.group(1), match.group(2))) 4906 4907 # Check if some verboten C functions are being used. 4908 if Search(r'\bsprintf\s*\(', line): 4909 error(filename, linenum, 'runtime/printf', 5, 4910 'Never use sprintf. Use snprintf instead.') 4911 match = Search(r'\b(strcpy|strcat)\s*\(', line) 4912 if match: 4913 error(filename, linenum, 'runtime/printf', 4, 4914 'Almost always, snprintf is better than %s' % match.group(1)) 4915 4916 4917def IsDerivedFunction(clean_lines, linenum): 4918 """Check if current line contains an inherited function. 4919 4920 Args: 4921 clean_lines: A CleansedLines instance containing the file. 4922 linenum: The number of the line to check. 4923 Returns: 4924 True if current line contains a function with "override" 4925 virt-specifier. 4926 """ 4927 # Scan back a few lines for start of current function 4928 for i in xrange(linenum, max(-1, linenum - 10), -1): 4929 match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) 4930 if match: 4931 # Look for "override" after the matching closing parenthesis 4932 line, _, closing_paren = CloseExpression( 4933 clean_lines, i, len(match.group(1))) 4934 return (closing_paren >= 0 and 4935 Search(r'\boverride\b', line[closing_paren:])) 4936 return False 4937 4938 4939def IsOutOfLineMethodDefinition(clean_lines, linenum): 4940 """Check if current line contains an out-of-line method definition. 4941 4942 Args: 4943 clean_lines: A CleansedLines instance containing the file. 4944 linenum: The number of the line to check. 4945 Returns: 4946 True if current line contains an out-of-line method definition. 4947 """ 4948 # Scan back a few lines for start of current function 4949 for i in xrange(linenum, max(-1, linenum - 10), -1): 4950 if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]): 4951 return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None 4952 return False 4953 4954 4955def IsInitializerList(clean_lines, linenum): 4956 """Check if current line is inside constructor initializer list. 4957 4958 Args: 4959 clean_lines: A CleansedLines instance containing the file. 4960 linenum: The number of the line to check. 4961 Returns: 4962 True if current line appears to be inside constructor initializer 4963 list, False otherwise. 4964 """ 4965 for i in xrange(linenum, 1, -1): 4966 line = clean_lines.elided[i] 4967 if i == linenum: 4968 remove_function_body = Match(r'^(.*)\{\s*$', line) 4969 if remove_function_body: 4970 line = remove_function_body.group(1) 4971 4972 if Search(r'\s:\s*\w+[({]', line): 4973 # A lone colon tend to indicate the start of a constructor 4974 # initializer list. It could also be a ternary operator, which 4975 # also tend to appear in constructor initializer lists as 4976 # opposed to parameter lists. 4977 return True 4978 if Search(r'\}\s*,\s*$', line): 4979 # A closing brace followed by a comma is probably the end of a 4980 # brace-initialized member in constructor initializer list. 4981 return True 4982 if Search(r'[{};]\s*$', line): 4983 # Found one of the following: 4984 # - A closing brace or semicolon, probably the end of the previous 4985 # function. 4986 # - An opening brace, probably the start of current class or namespace. 4987 # 4988 # Current line is probably not inside an initializer list since 4989 # we saw one of those things without seeing the starting colon. 4990 return False 4991 4992 # Got to the beginning of the file without seeing the start of 4993 # constructor initializer list. 4994 return False 4995 4996 4997def CheckForNonConstReference(filename, clean_lines, linenum, 4998 nesting_state, error): 4999 """Check for non-const references. 5000 5001 Separate from CheckLanguage since it scans backwards from current 5002 line, instead of scanning forward. 5003 5004 Args: 5005 filename: The name of the current file. 5006 clean_lines: A CleansedLines instance containing the file. 5007 linenum: The number of the line to check. 5008 nesting_state: A NestingState instance which maintains information about 5009 the current stack of nested blocks being parsed. 5010 error: The function to call with any errors found. 5011 """ 5012 # Do nothing if there is no '&' on current line. 5013 line = clean_lines.elided[linenum] 5014 if '&' not in line: 5015 return 5016 5017 # If a function is inherited, current function doesn't have much of 5018 # a choice, so any non-const references should not be blamed on 5019 # derived function. 5020 if IsDerivedFunction(clean_lines, linenum): 5021 return 5022 5023 # Don't warn on out-of-line method definitions, as we would warn on the 5024 # in-line declaration, if it isn't marked with 'override'. 5025 if IsOutOfLineMethodDefinition(clean_lines, linenum): 5026 return 5027 5028 # Long type names may be broken across multiple lines, usually in one 5029 # of these forms: 5030 # LongType 5031 # ::LongTypeContinued &identifier 5032 # LongType:: 5033 # LongTypeContinued &identifier 5034 # LongType< 5035 # ...>::LongTypeContinued &identifier 5036 # 5037 # If we detected a type split across two lines, join the previous 5038 # line to current line so that we can match const references 5039 # accordingly. 5040 # 5041 # Note that this only scans back one line, since scanning back 5042 # arbitrary number of lines would be expensive. If you have a type 5043 # that spans more than 2 lines, please use a typedef. 5044 if linenum > 1: 5045 previous = None 5046 if Match(r'\s*::(?:[\w<>]|::)+\s*&\s*\S', line): 5047 # previous_line\n + ::current_line 5048 previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$', 5049 clean_lines.elided[linenum - 1]) 5050 elif Match(r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S', line): 5051 # previous_line::\n + current_line 5052 previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$', 5053 clean_lines.elided[linenum - 1]) 5054 if previous: 5055 line = previous.group(1) + line.lstrip() 5056 else: 5057 # Check for templated parameter that is split across multiple lines 5058 endpos = line.rfind('>') 5059 if endpos > -1: 5060 (_, startline, startpos) = ReverseCloseExpression( 5061 clean_lines, linenum, endpos) 5062 if startpos > -1 and startline < linenum: 5063 # Found the matching < on an earlier line, collect all 5064 # pieces up to current line. 5065 line = '' 5066 for i in xrange(startline, linenum + 1): 5067 line += clean_lines.elided[i].strip() 5068 5069 # Check for non-const references in function parameters. A single '&' may 5070 # found in the following places: 5071 # inside expression: binary & for bitwise AND 5072 # inside expression: unary & for taking the address of something 5073 # inside declarators: reference parameter 5074 # We will exclude the first two cases by checking that we are not inside a 5075 # function body, including one that was just introduced by a trailing '{'. 5076 # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. 5077 if (nesting_state.previous_stack_top and 5078 not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or 5079 isinstance(nesting_state.previous_stack_top, _NamespaceInfo))): 5080 # Not at toplevel, not within a class, and not within a namespace 5081 return 5082 5083 # Avoid initializer lists. We only need to scan back from the 5084 # current line for something that starts with ':'. 5085 # 5086 # We don't need to check the current line, since the '&' would 5087 # appear inside the second set of parentheses on the current line as 5088 # opposed to the first set. 5089 if linenum > 0: 5090 for i in xrange(linenum - 1, max(0, linenum - 10), -1): 5091 previous_line = clean_lines.elided[i] 5092 if not Search(r'[),]\s*$', previous_line): 5093 break 5094 if Match(r'^\s*:\s+\S', previous_line): 5095 return 5096 5097 # Avoid preprocessors 5098 if Search(r'\\\s*$', line): 5099 return 5100 5101 # Avoid constructor initializer lists 5102 if IsInitializerList(clean_lines, linenum): 5103 return 5104 5105 # We allow non-const references in a few standard places, like functions 5106 # called "swap()" or iostream operators like "<<" or ">>". Do not check 5107 # those function parameters. 5108 # 5109 # We also accept & in static_assert, which looks like a function but 5110 # it's actually a declaration expression. 5111 whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|' 5112 r'operator\s*[<>][<>]|' 5113 r'static_assert|COMPILE_ASSERT' 5114 r')\s*\(') 5115 if Search(whitelisted_functions, line): 5116 return 5117 elif not Search(r'\S+\([^)]*$', line): 5118 # Don't see a whitelisted function on this line. Actually we 5119 # didn't see any function name on this line, so this is likely a 5120 # multi-line parameter list. Try a bit harder to catch this case. 5121 for i in xrange(2): 5122 if (linenum > i and 5123 Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): 5124 return 5125 5126 decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body 5127 # for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): 5128 # if (not Match(_RE_PATTERN_CONST_REF_PARAM, parameter) and 5129 # not Match(_RE_PATTERN_REF_STREAM_PARAM, parameter)): 5130 # error(filename, linenum, 'runtime/references', 2, 5131 # 'Is this a non-const reference? ' 5132 # 'If so, make const or use a pointer: ' + 5133 # ReplaceAll(' *<', '<', parameter)) 5134 5135 5136def CheckCasts(filename, clean_lines, linenum, error): 5137 """Various cast related checks. 5138 5139 Args: 5140 filename: The name of the current file. 5141 clean_lines: A CleansedLines instance containing the file. 5142 linenum: The number of the line to check. 5143 error: The function to call with any errors found. 5144 """ 5145 line = clean_lines.elided[linenum] 5146 5147 # Check to see if they're using an conversion function cast. 5148 # I just try to capture the most common basic types, though there are more. 5149 # Parameterless conversion functions, such as bool(), are allowed as they are 5150 # probably a member operator declaration or default constructor. 5151 match = Search( 5152 r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' 5153 r'(int|float|double|bool|char|int32|uint32|int64|uint64)' 5154 r'(\([^)].*)', line) 5155 expecting_function = ExpectingFunctionArgs(clean_lines, linenum) 5156 if match and not expecting_function: 5157 matched_type = match.group(2) 5158 5159 # matched_new_or_template is used to silence two false positives: 5160 # - New operators 5161 # - Template arguments with function types 5162 # 5163 # For template arguments, we match on types immediately following 5164 # an opening bracket without any spaces. This is a fast way to 5165 # silence the common case where the function type is the first 5166 # template argument. False negative with less-than comparison is 5167 # avoided because those operators are usually followed by a space. 5168 # 5169 # function<double(double)> // bracket + no space = false positive 5170 # value < double(42) // bracket + space = true positive 5171 matched_new_or_template = match.group(1) 5172 5173 # Avoid arrays by looking for brackets that come after the closing 5174 # parenthesis. 5175 if Match(r'\([^()]+\)\s*\[', match.group(3)): 5176 return 5177 5178 # Other things to ignore: 5179 # - Function pointers 5180 # - Casts to pointer types 5181 # - Placement new 5182 # - Alias declarations 5183 matched_funcptr = match.group(3) 5184 if (matched_new_or_template is None and 5185 not (matched_funcptr and 5186 (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', 5187 matched_funcptr) or 5188 matched_funcptr.startswith('(*)'))) and 5189 not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and 5190 not Search(r'new\(\S+\)\s*' + matched_type, line)): 5191 error(filename, linenum, 'readability/casting', 4, 5192 'Using deprecated casting style. ' 5193 'Use static_cast<%s>(...) instead' % 5194 matched_type) 5195 5196 if not expecting_function: 5197 CheckCStyleCast(filename, clean_lines, linenum, 'static_cast', 5198 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) 5199 5200 # This doesn't catch all cases. Consider (const char * const)"hello". 5201 # 5202 # (char *) "foo" should always be a const_cast (reinterpret_cast won't 5203 # compile). 5204 if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast', 5205 r'\((char\s?\*+\s?)\)\s*"', error): 5206 pass 5207 else: 5208 # Check pointer casts for other than string constants 5209 CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast', 5210 r'\((\w+\s?\*+\s?)\)', error) 5211 5212 # In addition, we look for people taking the address of a cast. This 5213 # is dangerous -- casts can assign to temporaries, so the pointer doesn't 5214 # point where you think. 5215 # 5216 # Some non-identifier character is required before the '&' for the 5217 # expression to be recognized as a cast. These are casts: 5218 # expression = &static_cast<int*>(temporary()); 5219 # function(&(int*)(temporary())); 5220 # 5221 # This is not a cast: 5222 # reference_type&(int* function_param); 5223 match = Search( 5224 r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|' 5225 r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line) 5226 if match: 5227 # Try a better error message when the & is bound to something 5228 # dereferenced by the casted pointer, as opposed to the casted 5229 # pointer itself. 5230 parenthesis_error = False 5231 match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) 5232 if match: 5233 _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) 5234 if x1 >= 0 and clean_lines.elided[y1][x1] == '(': 5235 _, y2, x2 = CloseExpression(clean_lines, y1, x1) 5236 if x2 >= 0: 5237 extended_line = clean_lines.elided[y2][x2:] 5238 if y2 < clean_lines.NumLines() - 1: 5239 extended_line += clean_lines.elided[y2 + 1] 5240 if Match(r'\s*(?:->|\[)', extended_line): 5241 parenthesis_error = True 5242 5243 if parenthesis_error: 5244 error(filename, linenum, 'readability/casting', 4, 5245 ('Are you taking an address of something dereferenced ' 5246 'from a cast? Wrapping the dereferenced expression in ' 5247 'parentheses will make the binding more obvious')) 5248 else: 5249 error(filename, linenum, 'runtime/casting', 4, 5250 ('Are you taking an address of a cast? ' 5251 'This is dangerous: could be a temp var. ' 5252 'Take the address before doing the cast, rather than after')) 5253 5254 5255def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): 5256 """Checks for a C-style cast by looking for the pattern. 5257 5258 Args: 5259 filename: The name of the current file. 5260 clean_lines: A CleansedLines instance containing the file. 5261 linenum: The number of the line to check. 5262 cast_type: The string for the C++ cast to recommend. This is either 5263 reinterpret_cast, static_cast, or const_cast, depending. 5264 pattern: The regular expression used to find C-style casts. 5265 error: The function to call with any errors found. 5266 5267 Returns: 5268 True if an error was emitted. 5269 False otherwise. 5270 """ 5271 line = clean_lines.elided[linenum] 5272 match = Search(pattern, line) 5273 if not match: 5274 return False 5275 5276 # Exclude lines with keywords that tend to look like casts 5277 context = line[0:match.start(1) - 1] 5278 if Match(r'^\s*(private|public):.*$', context): 5279 return False 5280 if Match(r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$', context): 5281 return False 5282 5283 # Try expanding current context to see if we one level of 5284 # parentheses inside a macro. 5285 if linenum > 0: 5286 for i in xrange(linenum - 1, max(0, linenum - 5), -1): 5287 context = clean_lines.elided[i] + context 5288 if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): 5289 return False 5290 5291 # operator++(int) and operator--(int) 5292 if context.endswith(' operator++') or context.endswith(' operator--'): 5293 return False 5294 5295 # A single unnamed argument for a function tends to look like old style cast. 5296 # If we see those, don't issue warnings for deprecated casts. 5297 remainder = line[match.end(0):] 5298 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', 5299 remainder): 5300 return False 5301 5302 # At this point, all that should be left is actual casts. 5303 error(filename, linenum, 'readability/casting', 4, 5304 'Using C-style cast. Use %s<%s>(...) instead' % 5305 (cast_type, match.group(1))) 5306 5307 return True 5308 5309 5310def ExpectingFunctionArgs(clean_lines, linenum): 5311 """Checks whether where function type arguments are expected. 5312 5313 Args: 5314 clean_lines: A CleansedLines instance containing the file. 5315 linenum: The number of the line to check. 5316 5317 Returns: 5318 True if the line at 'linenum' is inside something that expects arguments 5319 of function types. 5320 """ 5321 line = clean_lines.elided[linenum] 5322 return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or 5323 (linenum >= 2 and 5324 (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$', 5325 clean_lines.elided[linenum - 1]) or 5326 Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$', 5327 clean_lines.elided[linenum - 2]) or 5328 Search(r'\bstd::m?function\s*\<\s*$', 5329 clean_lines.elided[linenum - 1])))) 5330 5331 5332_HEADERS_CONTAINING_TEMPLATES = ( 5333 ('<deque>', ('deque',)), 5334 ('<functional>', ('unary_function', 'binary_function', 5335 'plus', 'minus', 'multiplies', 'divides', 'modulus', 5336 'negate', 5337 'equal_to', 'not_equal_to', 'greater', 'less', 5338 'greater_equal', 'less_equal', 5339 'logical_and', 'logical_or', 'logical_not', 5340 'unary_negate', 'not1', 'binary_negate', 'not2', 5341 'bind1st', 'bind2nd', 5342 'pointer_to_unary_function', 5343 'pointer_to_binary_function', 5344 'ptr_fun', 5345 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', 5346 'mem_fun_ref_t', 5347 'const_mem_fun_t', 'const_mem_fun1_t', 5348 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', 5349 'mem_fun_ref', 5350 )), 5351 ('<limits>', ('numeric_limits',)), 5352 ('<list>', ('list',)), 5353 ('<map>', ('map', 'multimap',)), 5354 ('<memory>', ('allocator', 'make_shared', 'make_unique', 'shared_ptr', 5355 'unique_ptr', 'weak_ptr')), 5356 ('<queue>', ('queue', 'priority_queue',)), 5357 ('<set>', ('set', 'multiset',)), 5358 ('<stack>', ('stack',)), 5359 ('<string>', ('char_traits', 'basic_string',)), 5360 ('<tuple>', ('tuple',)), 5361 ('<unordered_map>', ('unordered_map', 'unordered_multimap')), 5362 ('<unordered_set>', ('unordered_set', 'unordered_multiset')), 5363 ('<utility>', ('pair',)), 5364 ('<vector>', ('vector',)), 5365 5366 # gcc extensions. 5367 # Note: std::hash is their hash, ::hash is our hash 5368 ('<hash_map>', ('hash_map', 'hash_multimap',)), 5369 ('<hash_set>', ('hash_set', 'hash_multiset',)), 5370 ('<slist>', ('slist',)), 5371 ) 5372 5373_HEADERS_MAYBE_TEMPLATES = ( 5374 ('<algorithm>', ('copy', 'max', 'min', 'min_element', 'sort', 5375 'transform', 5376 )), 5377 ('<utility>', ('forward', 'make_pair', 'move', 'swap')), 5378 ) 5379 5380_RE_PATTERN_STRING = re.compile(r'\bstring\b') 5381 5382_re_pattern_headers_maybe_templates = [] 5383for _header, _templates in _HEADERS_MAYBE_TEMPLATES: 5384 for _template in _templates: 5385 # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or 5386 # type::max(). 5387 _re_pattern_headers_maybe_templates.append( 5388 (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), 5389 _template, 5390 _header)) 5391 5392# Other scripts may reach in and modify this pattern. 5393_re_pattern_templates = [] 5394for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: 5395 for _template in _templates: 5396 _re_pattern_templates.append( 5397 (re.compile(r'(\<|\b)' + _template + r'\s*\<'), 5398 _template + '<>', 5399 _header)) 5400 5401 5402def FilesBelongToSameModule(filename_cc, filename_h): 5403 """Check if these two filenames belong to the same module. 5404 5405 The concept of a 'module' here is a as follows: 5406 foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the 5407 same 'module' if they are in the same directory. 5408 some/path/public/xyzzy and some/path/internal/xyzzy are also considered 5409 to belong to the same module here. 5410 5411 If the filename_cc contains a longer path than the filename_h, for example, 5412 '/absolute/path/to/base/sysinfo.cc', and this file would include 5413 'base/sysinfo.h', this function also produces the prefix needed to open the 5414 header. This is used by the caller of this function to more robustly open the 5415 header file. We don't have access to the real include paths in this context, 5416 so we need this guesswork here. 5417 5418 Known bugs: tools/base/bar.cc and base/bar.h belong to the same module 5419 according to this implementation. Because of this, this function gives 5420 some false positives. This should be sufficiently rare in practice. 5421 5422 Args: 5423 filename_cc: is the path for the .cc file 5424 filename_h: is the path for the header path 5425 5426 Returns: 5427 Tuple with a bool and a string: 5428 bool: True if filename_cc and filename_h belong to the same module. 5429 string: the additional prefix needed to open the header file. 5430 """ 5431 5432 fileinfo = FileInfo(filename_cc) 5433 if not fileinfo.IsSource(): 5434 return (False, '') 5435 filename_cc = filename_cc[:-len(fileinfo.Extension())] 5436 matched_test_suffix = Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()) 5437 if matched_test_suffix: 5438 filename_cc = filename_cc[:-len(matched_test_suffix.group(1))] 5439 filename_cc = filename_cc.replace('/public/', '/') 5440 filename_cc = filename_cc.replace('/internal/', '/') 5441 5442 if not filename_h.endswith('.h'): 5443 return (False, '') 5444 filename_h = filename_h[:-len('.h')] 5445 if filename_h.endswith('-inl'): 5446 filename_h = filename_h[:-len('-inl')] 5447 filename_h = filename_h.replace('/public/', '/') 5448 filename_h = filename_h.replace('/internal/', '/') 5449 5450 files_belong_to_same_module = filename_cc.endswith(filename_h) 5451 common_path = '' 5452 if files_belong_to_same_module: 5453 common_path = filename_cc[:-len(filename_h)] 5454 return files_belong_to_same_module, common_path 5455 5456 5457def UpdateIncludeState(filename, include_dict, io=codecs): 5458 """Fill up the include_dict with new includes found from the file. 5459 5460 Args: 5461 filename: the name of the header to read. 5462 include_dict: a dictionary in which the headers are inserted. 5463 io: The io factory to use to read the file. Provided for testability. 5464 5465 Returns: 5466 True if a header was successfully added. False otherwise. 5467 """ 5468 headerfile = None 5469 try: 5470 headerfile = io.open(filename, 'r', 'utf8', 'replace') 5471 except IOError: 5472 return False 5473 linenum = 0 5474 for line in headerfile: 5475 linenum += 1 5476 clean_line = CleanseComments(line) 5477 match = _RE_PATTERN_INCLUDE.search(clean_line) 5478 if match: 5479 include = match.group(2) 5480 include_dict.setdefault(include, linenum) 5481 return True 5482 5483 5484def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, 5485 io=codecs): 5486 """Reports for missing stl includes. 5487 5488 This function will output warnings to make sure you are including the headers 5489 necessary for the stl containers and functions that you use. We only give one 5490 reason to include a header. For example, if you use both equal_to<> and 5491 less<> in a .h file, only one (the latter in the file) of these will be 5492 reported as a reason to include the <functional>. 5493 5494 Args: 5495 filename: The name of the current file. 5496 clean_lines: A CleansedLines instance containing the file. 5497 include_state: An _IncludeState instance. 5498 error: The function to call with any errors found. 5499 io: The IO factory to use to read the header file. Provided for unittest 5500 injection. 5501 """ 5502 required = {} # A map of header name to linenumber and the template entity. 5503 # Example of required: { '<functional>': (1219, 'less<>') } 5504 5505 for linenum in xrange(clean_lines.NumLines()): 5506 line = clean_lines.elided[linenum] 5507 if not line or line[0] == '#': 5508 continue 5509 5510 # String is special -- it is a non-templatized type in STL. 5511 matched = _RE_PATTERN_STRING.search(line) 5512 if matched: 5513 # Don't warn about strings in non-STL namespaces: 5514 # (We check only the first match per line; good enough.) 5515 prefix = line[:matched.start()] 5516 if prefix.endswith('std::') or not prefix.endswith('::'): 5517 required['<string>'] = (linenum, 'string') 5518 5519 for pattern, template, header in _re_pattern_headers_maybe_templates: 5520 if pattern.search(line): 5521 required[header] = (linenum, template) 5522 5523 # The following function is just a speed up, no semantics are changed. 5524 if not '<' in line: # Reduces the cpu time usage by skipping lines. 5525 continue 5526 5527 for pattern, template, header in _re_pattern_templates: 5528 matched = pattern.search(line) 5529 if matched: 5530 # Don't warn about IWYU in non-STL namespaces: 5531 # (We check only the first match per line; good enough.) 5532 prefix = line[:matched.start()] 5533 if prefix.endswith('std::') or not prefix.endswith('::'): 5534 required[header] = (linenum, template) 5535 5536 # The policy is that if you #include something in foo.h you don't need to 5537 # include it again in foo.cc. Here, we will look at possible includes. 5538 # Let's flatten the include_state include_list and copy it into a dictionary. 5539 include_dict = dict([item for sublist in include_state.include_list 5540 for item in sublist]) 5541 5542 # Did we find the header for this file (if any) and successfully load it? 5543 header_found = False 5544 5545 # Use the absolute path so that matching works properly. 5546 abs_filename = FileInfo(filename).FullName() 5547 5548 # For Emacs's flymake. 5549 # If cpplint is invoked from Emacs's flymake, a temporary file is generated 5550 # by flymake and that file name might end with '_flymake.cc'. In that case, 5551 # restore original file name here so that the corresponding header file can be 5552 # found. 5553 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' 5554 # instead of 'foo_flymake.h' 5555 abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) 5556 5557 # include_dict is modified during iteration, so we iterate over a copy of 5558 # the keys. 5559 header_keys = include_dict.keys() 5560 for header in header_keys: 5561 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) 5562 fullpath = common_path + header 5563 if same_module and UpdateIncludeState(fullpath, include_dict, io): 5564 header_found = True 5565 5566 # If we can't find the header file for a .cc, assume it's because we don't 5567 # know where to look. In that case we'll give up as we're not sure they 5568 # didn't include it in the .h file. 5569 # TODO(unknown): Do a better job of finding .h files so we are confident that 5570 # not having the .h file means there isn't one. 5571 if filename.endswith('.cc') and not header_found: 5572 return 5573 5574 # All the lines have been processed, report the errors found. 5575 for required_header_unstripped in required: 5576 template = required[required_header_unstripped][1] 5577 if required_header_unstripped.strip('<>"') not in include_dict: 5578 error(filename, required[required_header_unstripped][0], 5579 'build/include_what_you_use', 4, 5580 'Add #include ' + required_header_unstripped + ' for ' + template) 5581 5582 5583_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') 5584 5585 5586def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): 5587 """Check that make_pair's template arguments are deduced. 5588 5589 G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are 5590 specified explicitly, and such use isn't intended in any case. 5591 5592 Args: 5593 filename: The name of the current file. 5594 clean_lines: A CleansedLines instance containing the file. 5595 linenum: The number of the line to check. 5596 error: The function to call with any errors found. 5597 """ 5598 line = clean_lines.elided[linenum] 5599 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) 5600 if match: 5601 error(filename, linenum, 'build/explicit_make_pair', 5602 4, # 4 = high confidence 5603 'For C++11-compatibility, omit template arguments from make_pair' 5604 ' OR use pair directly OR if appropriate, construct a pair directly') 5605 5606 5607def CheckRedundantVirtual(filename, clean_lines, linenum, error): 5608 """Check if line contains a redundant "virtual" function-specifier. 5609 5610 Args: 5611 filename: The name of the current file. 5612 clean_lines: A CleansedLines instance containing the file. 5613 linenum: The number of the line to check. 5614 error: The function to call with any errors found. 5615 """ 5616 # Look for "virtual" on current line. 5617 line = clean_lines.elided[linenum] 5618 virtual = Match(r'^(.*)(\bvirtual\b)(.*)$', line) 5619 if not virtual: return 5620 5621 # Ignore "virtual" keywords that are near access-specifiers. These 5622 # are only used in class base-specifier and do not apply to member 5623 # functions. 5624 if (Search(r'\b(public|protected|private)\s+$', virtual.group(1)) or 5625 Match(r'^\s+(public|protected|private)\b', virtual.group(3))): 5626 return 5627 5628 # Ignore the "virtual" keyword from virtual base classes. Usually 5629 # there is a column on the same line in these cases (virtual base 5630 # classes are rare in google3 because multiple inheritance is rare). 5631 if Match(r'^.*[^:]:[^:].*$', line): return 5632 5633 # Look for the next opening parenthesis. This is the start of the 5634 # parameter list (possibly on the next line shortly after virtual). 5635 # TODO(unknown): doesn't work if there are virtual functions with 5636 # decltype() or other things that use parentheses, but csearch suggests 5637 # that this is rare. 5638 end_col = -1 5639 end_line = -1 5640 start_col = len(virtual.group(2)) 5641 for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): 5642 line = clean_lines.elided[start_line][start_col:] 5643 parameter_list = Match(r'^([^(]*)\(', line) 5644 if parameter_list: 5645 # Match parentheses to find the end of the parameter list 5646 (_, end_line, end_col) = CloseExpression( 5647 clean_lines, start_line, start_col + len(parameter_list.group(1))) 5648 break 5649 start_col = 0 5650 5651 if end_col < 0: 5652 return # Couldn't find end of parameter list, give up 5653 5654 # Look for "override" or "final" after the parameter list 5655 # (possibly on the next few lines). 5656 for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())): 5657 line = clean_lines.elided[i][end_col:] 5658 match = Search(r'\b(override|final)\b', line) 5659 if match: 5660 error(filename, linenum, 'readability/inheritance', 4, 5661 ('"virtual" is redundant since function is ' 5662 'already declared as "%s"' % match.group(1))) 5663 5664 # Set end_col to check whole lines after we are done with the 5665 # first line. 5666 end_col = 0 5667 if Search(r'[^\w]\s*$', line): 5668 break 5669 5670 5671def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error): 5672 """Check if line contains a redundant "override" or "final" virt-specifier. 5673 5674 Args: 5675 filename: The name of the current file. 5676 clean_lines: A CleansedLines instance containing the file. 5677 linenum: The number of the line to check. 5678 error: The function to call with any errors found. 5679 """ 5680 # Look for closing parenthesis nearby. We need one to confirm where 5681 # the declarator ends and where the virt-specifier starts to avoid 5682 # false positives. 5683 line = clean_lines.elided[linenum] 5684 declarator_end = line.rfind(')') 5685 if declarator_end >= 0: 5686 fragment = line[declarator_end:] 5687 else: 5688 if linenum > 1 and clean_lines.elided[linenum - 1].rfind(')') >= 0: 5689 fragment = line 5690 else: 5691 return 5692 5693 5694 5695 5696# Returns true if we are at a new block, and it is directly 5697# inside of a namespace. 5698def IsBlockInNameSpace(nesting_state, is_forward_declaration): 5699 """Checks that the new block is directly in a namespace. 5700 5701 Args: 5702 nesting_state: The _NestingState object that contains info about our state. 5703 is_forward_declaration: If the class is a forward declared class. 5704 Returns: 5705 Whether or not the new block is directly in a namespace. 5706 """ 5707 if is_forward_declaration: 5708 if len(nesting_state.stack) >= 1 and ( 5709 isinstance(nesting_state.stack[-1], _NamespaceInfo)): 5710 return True 5711 else: 5712 return False 5713 5714 return (len(nesting_state.stack) > 1 and 5715 nesting_state.stack[-1].check_namespace_indentation and 5716 isinstance(nesting_state.stack[-2], _NamespaceInfo)) 5717 5718 5719def ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item, 5720 raw_lines_no_comments, linenum): 5721 """This method determines if we should apply our namespace indentation check. 5722 5723 Args: 5724 nesting_state: The current nesting state. 5725 is_namespace_indent_item: If we just put a new class on the stack, True. 5726 If the top of the stack is not a class, or we did not recently 5727 add the class, False. 5728 raw_lines_no_comments: The lines without the comments. 5729 linenum: The current line number we are processing. 5730 5731 Returns: 5732 True if we should apply our namespace indentation check. Currently, it 5733 only works for classes and namespaces inside of a namespace. 5734 """ 5735 5736 is_forward_declaration = IsForwardClassDeclaration(raw_lines_no_comments, 5737 linenum) 5738 5739 if not (is_namespace_indent_item or is_forward_declaration): 5740 return False 5741 5742 # If we are in a macro, we do not want to check the namespace indentation. 5743 if IsMacroDefinition(raw_lines_no_comments, linenum): 5744 return False 5745 5746 return IsBlockInNameSpace(nesting_state, is_forward_declaration) 5747 5748 5749# Call this method if the line is directly inside of a namespace. 5750# If the line above is blank (excluding comments) or the start of 5751# an inner namespace, it cannot be indented. 5752def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum, 5753 error): 5754 line = raw_lines_no_comments[linenum] 5755 # if Match(r'^\s+', line): 5756 # error(filename, linenum, 'runtime/indentation_namespace', 4, 5757 # 'Do not indent within a namespace') 5758 5759 5760def ProcessLine(filename, file_extension, clean_lines, line, 5761 include_state, function_state, nesting_state, error, 5762 extra_check_functions=[]): 5763 """Processes a single line in the file. 5764 5765 Args: 5766 filename: Filename of the file that is being processed. 5767 file_extension: The extension (dot not included) of the file. 5768 clean_lines: An array of strings, each representing a line of the file, 5769 with comments stripped. 5770 line: Number of line being processed. 5771 include_state: An _IncludeState instance in which the headers are inserted. 5772 function_state: A _FunctionState instance which counts function lines, etc. 5773 nesting_state: A NestingState instance which maintains information about 5774 the current stack of nested blocks being parsed. 5775 error: A callable to which errors are reported, which takes 4 arguments: 5776 filename, line number, error level, and message 5777 extra_check_functions: An array of additional check functions that will be 5778 run on each source line. Each function takes 4 5779 arguments: filename, clean_lines, line, error 5780 """ 5781 raw_lines = clean_lines.raw_lines 5782 ParseNolintSuppressions(filename, raw_lines[line], line, error) 5783 nesting_state.Update(filename, clean_lines, line, error) 5784 CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line, 5785 error) 5786 if nesting_state.InAsmBlock(): return 5787 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) 5788 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) 5789 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) 5790 CheckLanguage(filename, clean_lines, line, file_extension, include_state, 5791 nesting_state, error) 5792 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) 5793 CheckForNonStandardConstructs(filename, clean_lines, line, 5794 nesting_state, error) 5795 CheckVlogArguments(filename, clean_lines, line, error) 5796 CheckPosixThreading(filename, clean_lines, line, error) 5797 CheckInvalidIncrement(filename, clean_lines, line, error) 5798 CheckMakePairUsesDeduction(filename, clean_lines, line, error) 5799 CheckRedundantVirtual(filename, clean_lines, line, error) 5800 CheckRedundantOverrideOrFinal(filename, clean_lines, line, error) 5801 for check_fn in extra_check_functions: 5802 check_fn(filename, clean_lines, line, error) 5803 5804def FlagCxx11Features(filename, clean_lines, linenum, error): 5805 """Flag those c++11 features that we only allow in certain places. 5806 5807 Args: 5808 filename: The name of the current file. 5809 clean_lines: A CleansedLines instance containing the file. 5810 linenum: The number of the line to check. 5811 error: The function to call with any errors found. 5812 """ 5813 line = clean_lines.elided[linenum] 5814 5815 include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) 5816 5817 # Flag unapproved C++ TR1 headers. 5818 if include and include.group(1).startswith('tr1/'): 5819 error(filename, linenum, 'build/c++tr1', 5, 5820 ('C++ TR1 headers such as <%s> are unapproved.') % include.group(1)) 5821 5822 # Flag unapproved C++11 headers. 5823 if include and include.group(1) in ('cfenv', 5824 'fenv.h', 5825 'system_error', 5826 ): 5827 error(filename, linenum, 'build/c++11', 5, 5828 ('<%s> is an unapproved C++11 header.') % include.group(1)) 5829 5830 # The only place where we need to worry about C++11 keywords and library 5831 # features in preprocessor directives is in macro definitions. 5832 if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return 5833 5834 # These are classes and free functions. The classes are always 5835 # mentioned as std::*, but we only catch the free functions if 5836 # they're not found by ADL. They're alphabetical by header. 5837 for top_name in ( 5838 # type_traits 5839 'alignment_of', 5840 'aligned_union', 5841 ): 5842 if Search(r'\bstd::%s\b' % top_name, line): 5843 error(filename, linenum, 'build/c++11', 5, 5844 ('std::%s is an unapproved C++11 class or function. Send c-style ' 5845 'an example of where it would make your code more readable, and ' 5846 'they may let you use it.') % top_name) 5847 5848 5849def FlagCxx14Features(filename, clean_lines, linenum, error): 5850 """Flag those C++14 features that we restrict. 5851 5852 Args: 5853 filename: The name of the current file. 5854 clean_lines: A CleansedLines instance containing the file. 5855 linenum: The number of the line to check. 5856 error: The function to call with any errors found. 5857 """ 5858 line = clean_lines.elided[linenum] 5859 5860 include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) 5861 5862 # Flag unapproved C++14 headers. 5863 if include and include.group(1) in ('scoped_allocator', 'shared_mutex'): 5864 error(filename, linenum, 'build/c++14', 5, 5865 ('<%s> is an unapproved C++14 header.') % include.group(1)) 5866 5867 5868def ProcessFileData(filename, file_extension, lines, error, 5869 extra_check_functions=[]): 5870 """Performs lint checks and reports any errors to the given error function. 5871 5872 Args: 5873 filename: Filename of the file that is being processed. 5874 file_extension: The extension (dot not included) of the file. 5875 lines: An array of strings, each representing a line of the file, with the 5876 last element being empty if the file is terminated with a newline. 5877 error: A callable to which errors are reported, which takes 4 arguments: 5878 filename, line number, error level, and message 5879 extra_check_functions: An array of additional check functions that will be 5880 run on each source line. Each function takes 4 5881 arguments: filename, clean_lines, line, error 5882 """ 5883 lines = (['// marker so line numbers and indices both start at 1'] + lines + 5884 ['// marker so line numbers end in a known way']) 5885 5886 include_state = _IncludeState() 5887 function_state = _FunctionState() 5888 nesting_state = NestingState() 5889 5890 ResetNolintSuppressions() 5891 5892 CheckForCopyright(filename, lines, error) 5893 ProcessGlobalSuppresions(lines) 5894 RemoveMultiLineComments(filename, lines, error) 5895 clean_lines = CleansedLines(lines) 5896 5897 if IsHeaderExtension(file_extension): 5898 CheckForHeaderGuard(filename, clean_lines, error) 5899 5900 for line in xrange(clean_lines.NumLines()): 5901 ProcessLine(filename, file_extension, clean_lines, line, 5902 include_state, function_state, nesting_state, error, 5903 extra_check_functions) 5904 FlagCxx11Features(filename, clean_lines, line, error) 5905 nesting_state.CheckCompletedBlocks(filename, error) 5906 5907 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) 5908 5909 # Check that the .cc file has included its header if it exists. 5910 if _IsSourceExtension(file_extension): 5911 CheckHeaderFileIncluded(filename, include_state, error) 5912 5913 # We check here rather than inside ProcessLine so that we see raw 5914 # lines rather than "cleaned" lines. 5915 CheckForBadCharacters(filename, lines, error) 5916 5917 CheckForNewlineAtEOF(filename, lines, error) 5918 5919def ProcessConfigOverrides(filename): 5920 """ Loads the configuration files and processes the config overrides. 5921 5922 Args: 5923 filename: The name of the file being processed by the linter. 5924 5925 Returns: 5926 False if the current |filename| should not be processed further. 5927 """ 5928 5929 abs_filename = os.path.abspath(filename) 5930 cfg_filters = [] 5931 keep_looking = True 5932 while keep_looking: 5933 abs_path, base_name = os.path.split(abs_filename) 5934 if not base_name: 5935 break # Reached the root directory. 5936 5937 cfg_file = os.path.join(abs_path, "CPPLINT.cfg") 5938 abs_filename = abs_path 5939 if not os.path.isfile(cfg_file): 5940 continue 5941 5942 try: 5943 with open(cfg_file) as file_handle: 5944 for line in file_handle: 5945 line, _, _ = line.partition('#') # Remove comments. 5946 if not line.strip(): 5947 continue 5948 5949 name, _, val = line.partition('=') 5950 name = name.strip() 5951 val = val.strip() 5952 if name == 'set noparent': 5953 keep_looking = False 5954 elif name == 'filter': 5955 cfg_filters.append(val) 5956 elif name == 'exclude_files': 5957 # When matching exclude_files pattern, use the base_name of 5958 # the current file name or the directory name we are processing. 5959 # For example, if we are checking for lint errors in /foo/bar/baz.cc 5960 # and we found the .cfg file at /foo/CPPLINT.cfg, then the config 5961 # file's "exclude_files" filter is meant to be checked against "bar" 5962 # and not "baz" nor "bar/baz.cc". 5963 if base_name: 5964 pattern = re.compile(val) 5965 if pattern.match(base_name): 5966 if _cpplint_state.quiet: 5967 # Suppress "Ignoring file" warning when using --quiet. 5968 return False 5969 sys.stderr.write('Ignoring "%s": file excluded by "%s". ' 5970 'File path component "%s" matches ' 5971 'pattern "%s"\n' % 5972 (filename, cfg_file, base_name, val)) 5973 return False 5974 elif name == 'linelength': 5975 global _line_length 5976 try: 5977 _line_length = int(val) 5978 except ValueError: 5979 sys.stderr.write('Line length must be numeric.') 5980 elif name == 'root': 5981 global _root 5982 # root directories are specified relative to CPPLINT.cfg dir. 5983 _root = os.path.join(os.path.dirname(cfg_file), val) 5984 elif name == 'headers': 5985 ProcessHppHeadersOption(val) 5986 else: 5987 sys.stderr.write( 5988 'Invalid configuration option (%s) in file %s\n' % 5989 (name, cfg_file)) 5990 5991 except IOError: 5992 sys.stderr.write( 5993 "Skipping config file '%s': Can't open for reading\n" % cfg_file) 5994 keep_looking = False 5995 5996 # Apply all the accumulated filters in reverse order (top-level directory 5997 # config options having the least priority). 5998 for filter in reversed(cfg_filters): 5999 _AddFilters(filter) 6000 6001 return True 6002 6003 6004def ProcessFile(filename, vlevel, extra_check_functions=[]): 6005 """Does google-lint on a single file. 6006 6007 Args: 6008 filename: The name of the file to parse. 6009 6010 vlevel: The level of errors to report. Every error of confidence 6011 >= verbose_level will be reported. 0 is a good default. 6012 6013 extra_check_functions: An array of additional check functions that will be 6014 run on each source line. Each function takes 4 6015 arguments: filename, clean_lines, line, error 6016 """ 6017 6018 _SetVerboseLevel(vlevel) 6019 _BackupFilters() 6020 old_errors = _cpplint_state.error_count 6021 6022 if not ProcessConfigOverrides(filename): 6023 _RestoreFilters() 6024 return 6025 6026 lf_lines = [] 6027 crlf_lines = [] 6028 try: 6029 # Support the UNIX convention of using "-" for stdin. Note that 6030 # we are not opening the file with universal newline support 6031 # (which codecs doesn't support anyway), so the resulting lines do 6032 # contain trailing '\r' characters if we are reading a file that 6033 # has CRLF endings. 6034 # If after the split a trailing '\r' is present, it is removed 6035 # below. 6036 if filename == '-': 6037 lines = codecs.StreamReaderWriter(sys.stdin, 6038 codecs.getreader('utf8'), 6039 codecs.getwriter('utf8'), 6040 'replace').read().split('\n') 6041 else: 6042 lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') 6043 6044 # Remove trailing '\r'. 6045 # The -1 accounts for the extra trailing blank line we get from split() 6046 for linenum in range(len(lines) - 1): 6047 if lines[linenum].endswith('\r'): 6048 lines[linenum] = lines[linenum].rstrip('\r') 6049 crlf_lines.append(linenum + 1) 6050 else: 6051 lf_lines.append(linenum + 1) 6052 6053 except IOError: 6054 sys.stderr.write( 6055 "Skipping input '%s': Can't open for reading\n" % filename) 6056 _RestoreFilters() 6057 return 6058 6059 # Note, if no dot is found, this will give the entire filename as the ext. 6060 file_extension = filename[filename.rfind('.') + 1:] 6061 6062 # When reading from stdin, the extension is unknown, so no cpplint tests 6063 # should rely on the extension. 6064 if filename != '-' and file_extension not in _valid_extensions: 6065 if not _Quiet(): 6066 sys.stderr.write('Ignoring %s; not a valid file name ' 6067 '(%s)\n' % (filename, ', '.join(_valid_extensions))) 6068 else: 6069 ProcessFileData(filename, file_extension, lines, Error, 6070 extra_check_functions) 6071 6072 # If end-of-line sequences are a mix of LF and CR-LF, issue 6073 # warnings on the lines with CR. 6074 # 6075 # Don't issue any warnings if all lines are uniformly LF or CR-LF, 6076 # since critique can handle these just fine, and the style guide 6077 # doesn't dictate a particular end of line sequence. 6078 # 6079 # We can't depend on os.linesep to determine what the desired 6080 # end-of-line sequence should be, since that will return the 6081 # server-side end-of-line sequence. 6082 if lf_lines and crlf_lines: 6083 # Warn on every line with CR. An alternative approach might be to 6084 # check whether the file is mostly CRLF or just LF, and warn on the 6085 # minority, we bias toward LF here since most tools prefer LF. 6086 for linenum in crlf_lines: 6087 Error(filename, linenum, 'whitespace/newline', 1, 6088 'Unexpected \\r (^M) found; better to use only \\n') 6089 6090 # Suppress printing anything if --quiet was passed unless the error 6091 # count has increased after processing this file. 6092 # if not _cpplint_state.quiet or old_errors != _cpplint_state.error_count: 6093 # sys.stdout.write('Done processing %s\n' % filename) 6094 _RestoreFilters() 6095 6096 6097def PrintUsage(message): 6098 """Prints a brief usage string and exits, optionally with an error message. 6099 6100 Args: 6101 message: The optional error message. 6102 """ 6103 sys.stderr.write(_USAGE) 6104 if message: 6105 sys.exit('\nFATAL ERROR: ' + message) 6106 else: 6107 sys.exit(1) 6108 6109 6110def PrintCategories(): 6111 """Prints a list of all the error-categories used by error messages. 6112 6113 These are the categories used to filter messages via --filter. 6114 """ 6115 sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES)) 6116 sys.exit(0) 6117 6118 6119def ParseArguments(args): 6120 """Parses the command line arguments. 6121 6122 This may set the output format and verbosity level as side-effects. 6123 6124 Args: 6125 args: The command line arguments: 6126 6127 Returns: 6128 The list of filenames to lint. 6129 """ 6130 try: 6131 (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', 6132 'counting=', 6133 'filter=', 6134 'root=', 6135 'linelength=', 6136 'extensions=', 6137 'headers=', 6138 'quiet']) 6139 except getopt.GetoptError: 6140 PrintUsage('Invalid arguments.') 6141 6142 verbosity = _VerboseLevel() 6143 output_format = _OutputFormat() 6144 filters = '' 6145 quiet = _Quiet() 6146 counting_style = '' 6147 6148 for (opt, val) in opts: 6149 if opt == '--help': 6150 PrintUsage(None) 6151 elif opt == '--output': 6152 if val not in ('emacs', 'vs7', 'eclipse'): 6153 PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.') 6154 output_format = val 6155 elif opt == '--quiet': 6156 quiet = True 6157 elif opt == '--verbose': 6158 verbosity = int(val) 6159 elif opt == '--filter': 6160 filters = val 6161 if not filters: 6162 PrintCategories() 6163 elif opt == '--counting': 6164 if val not in ('total', 'toplevel', 'detailed'): 6165 PrintUsage('Valid counting options are total, toplevel, and detailed') 6166 counting_style = val 6167 elif opt == '--root': 6168 global _root 6169 _root = val 6170 elif opt == '--linelength': 6171 global _line_length 6172 try: 6173 _line_length = int(val) 6174 except ValueError: 6175 PrintUsage('Line length must be digits.') 6176 elif opt == '--extensions': 6177 global _valid_extensions 6178 try: 6179 _valid_extensions = set(val.split(',')) 6180 except ValueError: 6181 PrintUsage('Extensions must be comma seperated list.') 6182 elif opt == '--headers': 6183 ProcessHppHeadersOption(val) 6184 6185 if not filenames: 6186 PrintUsage('No files were specified.') 6187 6188 _SetOutputFormat(output_format) 6189 _SetQuiet(quiet) 6190 _SetVerboseLevel(verbosity) 6191 _SetFilters(filters) 6192 _SetCountingStyle(counting_style) 6193 6194 return filenames 6195 6196 6197def main(): 6198 filenames = ParseArguments(sys.argv[1:]) 6199 6200 # Change stderr to write with replacement characters so we don't die 6201 # if we try to print something containing non-ASCII characters. 6202 sys.stderr = codecs.StreamReaderWriter(sys.stderr, 6203 codecs.getreader('utf8'), 6204 codecs.getwriter('utf8'), 6205 'replace') 6206 6207 _cpplint_state.ResetErrorCounts() 6208 for filename in filenames: 6209 ProcessFile(filename, _cpplint_state.verbose_level) 6210 # If --quiet is passed, suppress printing error count unless there are errors. 6211 if not _cpplint_state.quiet or _cpplint_state.error_count > 0: 6212 _cpplint_state.PrintErrorCounts() 6213 6214 sys.exit(_cpplint_state.error_count > 0) 6215 6216 6217if __name__ == '__main__': 6218 main() 6219