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


roslint
Author(s): Mike Purvis, Jack O'Quin
autogenerated on Wed May 1 2019 02:23:59