2011-06-22 David Levin <levin@chromium.org>
[WebKit-https.git] / Tools / Scripts / webkitpy / style / checkers / cpp.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright (C) 2009, 2010 Google Inc. All rights reserved.
5 # Copyright (C) 2009 Torch Mobile Inc.
6 # Copyright (C) 2009 Apple Inc. All rights reserved.
7 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 #    * Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 #    * Redistributions in binary form must reproduce the above
16 # copyright notice, this list of conditions and the following disclaimer
17 # in the documentation and/or other materials provided with the
18 # distribution.
19 #    * Neither the name of Google Inc. nor the names of its
20 # contributors may be used to endorse or promote products derived from
21 # this software without specific prior written permission.
22 #
23 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 # This is the modified version of Google's cpplint. The original code is
36 # http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py
37
38 """Support for check-webkit-style."""
39
40 import codecs
41 import math  # for log
42 import os
43 import os.path
44 import re
45 import sre_compile
46 import string
47 import sys
48 import unicodedata
49
50 from webkitpy.common.memoized import memoized
51
52 # The key to use to provide a class to fake loading a header file.
53 INCLUDE_IO_INJECTION_KEY = 'include_header_io'
54
55 # Headers that we consider STL headers.
56 _STL_HEADERS = frozenset([
57     'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
58     'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
59     'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h',
60     'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
61     'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
62     'utility', 'vector', 'vector.h',
63     ])
64
65
66 # Non-STL C++ system headers.
67 _CPP_HEADERS = frozenset([
68     'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
69     'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
70     'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
71     'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
72     'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
73     'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
74     'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h',
75     'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
76     'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h',
77     'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h',
78     'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
79     'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
80     'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
81     ])
82
83
84 # Assertion macros.  These are defined in base/logging.h and
85 # testing/base/gunit.h.  Note that the _M versions need to come first
86 # for substring matching to work.
87 _CHECK_MACROS = [
88     'DCHECK', 'CHECK',
89     'EXPECT_TRUE_M', 'EXPECT_TRUE',
90     'ASSERT_TRUE_M', 'ASSERT_TRUE',
91     'EXPECT_FALSE_M', 'EXPECT_FALSE',
92     'ASSERT_FALSE_M', 'ASSERT_FALSE',
93     ]
94
95 # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
96 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
97
98 for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
99                         ('>=', 'GE'), ('>', 'GT'),
100                         ('<=', 'LE'), ('<', 'LT')]:
101     _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
102     _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
103     _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
104     _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
105     _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
106     _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
107
108 for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
109                             ('>=', 'LT'), ('>', 'LE'),
110                             ('<=', 'GT'), ('<', 'GE')]:
111     _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
112     _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
113     _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
114     _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
115
116
117 # These constants define types of headers for use with
118 # _IncludeState.check_next_include_order().
119 _CONFIG_HEADER = 0
120 _PRIMARY_HEADER = 1
121 _OTHER_HEADER = 2
122 _MOC_HEADER = 3
123
124
125 # A dictionary of items customize behavior for unit test. For example,
126 # INCLUDE_IO_INJECTION_KEY allows providing a custom io class which allows
127 # for faking a header file.
128 _unit_test_config = {}
129
130
131 # The regexp compilation caching is inlined in all regexp functions for
132 # performance reasons; factoring it out into a separate function turns out
133 # to be noticeably expensive.
134 _regexp_compile_cache = {}
135
136
137 def match(pattern, s):
138     """Matches the string with the pattern, caching the compiled regexp."""
139     if not pattern in _regexp_compile_cache:
140         _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
141     return _regexp_compile_cache[pattern].match(s)
142
143
144 def search(pattern, s):
145     """Searches the string for the pattern, caching the compiled regexp."""
146     if not pattern in _regexp_compile_cache:
147         _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
148     return _regexp_compile_cache[pattern].search(s)
149
150
151 def sub(pattern, replacement, s):
152     """Substitutes occurrences of a pattern, caching the compiled regexp."""
153     if not pattern in _regexp_compile_cache:
154         _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
155     return _regexp_compile_cache[pattern].sub(replacement, s)
156
157
158 def subn(pattern, replacement, s):
159     """Substitutes occurrences of a pattern, caching the compiled regexp."""
160     if not pattern in _regexp_compile_cache:
161         _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
162     return _regexp_compile_cache[pattern].subn(replacement, s)
163
164
165 def iteratively_replace_matches_with_char(pattern, char_replacement, s):
166     """Returns the string with replacement done.
167
168     Every character in the match is replaced with char.
169     Due to the iterative nature, pattern should not match char or
170     there will be an infinite loop.
171
172     Example:
173       pattern = r'<[^>]>' # template parameters
174       char_replacement =  '_'
175       s =     'A<B<C, D>>'
176       Returns 'A_________'
177
178     Args:
179       pattern: The regex to match.
180       char_replacement: The character to put in place of every
181                         character of the match.
182       s: The string on which to do the replacements.
183
184     Returns:
185       True, if the given line is blank.
186     """
187     while True:
188         matched = search(pattern, s)
189         if not matched:
190             return s
191         start_match_index = matched.start(0)
192         end_match_index = matched.end(0)
193         match_length = end_match_index - start_match_index
194         s = s[:start_match_index] + char_replacement * match_length + s[end_match_index:]
195
196
197 def _rfind_in_lines(regex, lines, start_position, not_found_position):
198     """Does a reverse find starting at start position and going backwards until
199     a match is found.
200
201     Returns the position where the regex ended.
202     """
203     # Put the regex in a group and proceed it with a greedy expression that
204     # matches anything to ensure that we get the last possible match in a line.
205     last_in_line_regex = r'.*(' + regex + ')'
206     current_row = start_position.row
207
208     # Start with the given row and trim off everything past what may be matched.
209     current_line = lines[start_position.row][:start_position.column]
210     while True:
211         found_match = match(last_in_line_regex, current_line)
212         if found_match:
213             return Position(current_row, found_match.end(1))
214
215         # A match was not found so continue backward.
216         current_row -= 1
217         if current_row < 0:
218             return not_found_position
219         current_line = lines[current_row]
220
221
222 def _convert_to_lower_with_underscores(text):
223     """Converts all text strings in camelCase or PascalCase to lowers with underscores."""
224
225     # First add underscores before any capital letter followed by a lower case letter
226     # as long as it is in a word.
227     # (This put an underscore before Password but not P and A in WPAPassword).
228     text = sub(r'(?<=[A-Za-z0-9])([A-Z])(?=[a-z])', r'_\1', text)
229
230     # Next add underscores before capitals at the end of words if it was
231     # preceeded by lower case letter or number.
232     # (This puts an underscore before A in isA but not A in CBA).
233     text = sub(r'(?<=[a-z0-9])([A-Z])(?=\b)', r'_\1', text)
234
235     # Next add underscores when you have a captial letter which is followed by a capital letter
236     # but is not proceeded by one. (This puts an underscore before A in 'WordADay').
237     text = sub(r'(?<=[a-z0-9])([A-Z][A-Z_])', r'_\1', text)
238
239     return text.lower()
240
241
242
243 def _create_acronym(text):
244     """Creates an acronym for the given text."""
245     # Removes all lower case letters except those starting words.
246     text = sub(r'(?<!\b)[a-z]', '', text)
247     return text.upper()
248
249
250 def up_to_unmatched_closing_paren(s):
251     """Splits a string into two parts up to first unmatched ')'.
252
253     Args:
254       s: a string which is a substring of line after '('
255       (e.g., "a == (b + c))").
256
257     Returns:
258       A pair of strings (prefix before first unmatched ')',
259       remainder of s after first unmatched ')'), e.g.,
260       up_to_unmatched_closing_paren("a == (b + c)) { ")
261       returns "a == (b + c)", " {".
262       Returns None, None if there is no unmatched ')'
263
264     """
265     i = 1
266     for pos, c in enumerate(s):
267       if c == '(':
268         i += 1
269       elif c == ')':
270         i -= 1
271         if i == 0:
272           return s[:pos], s[pos + 1:]
273     return None, None
274
275 class _IncludeState(dict):
276     """Tracks line numbers for includes, and the order in which includes appear.
277
278     As a dict, an _IncludeState object serves as a mapping between include
279     filename and line number on which that file was included.
280
281     Call check_next_include_order() once for each header in the file, passing
282     in the type constants defined above. Calls in an illegal order will
283     raise an _IncludeError with an appropriate error message.
284
285     """
286     # self._section will move monotonically through this set. If it ever
287     # needs to move backwards, check_next_include_order will raise an error.
288     _INITIAL_SECTION = 0
289     _CONFIG_SECTION = 1
290     _PRIMARY_SECTION = 2
291     _OTHER_SECTION = 3
292
293     _TYPE_NAMES = {
294         _CONFIG_HEADER: 'WebCore config.h',
295         _PRIMARY_HEADER: 'header this file implements',
296         _OTHER_HEADER: 'other header',
297         _MOC_HEADER: 'moc file',
298         }
299     _SECTION_NAMES = {
300         _INITIAL_SECTION: "... nothing.",
301         _CONFIG_SECTION: "WebCore config.h.",
302         _PRIMARY_SECTION: 'a header this file implements.',
303         _OTHER_SECTION: 'other header.',
304         }
305
306     def __init__(self):
307         dict.__init__(self)
308         self._section = self._INITIAL_SECTION
309         self._visited_primary_section = False
310         self.header_types = dict();
311
312     def visited_primary_section(self):
313         return self._visited_primary_section
314
315     def check_next_include_order(self, header_type, file_is_header, primary_header_exists):
316         """Returns a non-empty error message if the next header is out of order.
317
318         This function also updates the internal state to be ready to check
319         the next include.
320
321         Args:
322           header_type: One of the _XXX_HEADER constants defined above.
323           file_is_header: Whether the file that owns this _IncludeState is itself a header
324
325         Returns:
326           The empty string if the header is in the right order, or an
327           error message describing what's wrong.
328
329         """
330         if header_type == _CONFIG_HEADER and file_is_header:
331             return 'Header file should not contain WebCore config.h.'
332         if header_type == _PRIMARY_HEADER and file_is_header:
333             return 'Header file should not contain itself.'
334         if header_type == _MOC_HEADER:
335             return ''
336
337         error_message = ''
338         if self._section != self._OTHER_SECTION:
339             before_error_message = ('Found %s before %s' %
340                                     (self._TYPE_NAMES[header_type],
341                                      self._SECTION_NAMES[self._section + 1]))
342         after_error_message = ('Found %s after %s' %
343                                 (self._TYPE_NAMES[header_type],
344                                  self._SECTION_NAMES[self._section]))
345
346         if header_type == _CONFIG_HEADER:
347             if self._section >= self._CONFIG_SECTION:
348                 error_message = after_error_message
349             self._section = self._CONFIG_SECTION
350         elif header_type == _PRIMARY_HEADER:
351             if self._section >= self._PRIMARY_SECTION:
352                 error_message = after_error_message
353             elif self._section < self._CONFIG_SECTION:
354                 error_message = before_error_message
355             self._section = self._PRIMARY_SECTION
356             self._visited_primary_section = True
357         else:
358             assert header_type == _OTHER_HEADER
359             if not file_is_header and self._section < self._PRIMARY_SECTION:
360                 if primary_header_exists:
361                     error_message = before_error_message
362             self._section = self._OTHER_SECTION
363
364         return error_message
365
366
367 class Position(object):
368     """Holds the position of something."""
369     def __init__(self, row, column):
370         self.row = row
371         self.column = column
372
373     def __str__(self):
374         return '(%s, %s)' % (self.row, self.column)
375
376     def __cmp__(self, other):
377         return self.row.__cmp__(other.row) or self.column.__cmp__(other.column)
378
379
380 class Parameter(object):
381     """Information about one function parameter."""
382     def __init__(self, parameter, parameter_name_index, row):
383         self.type = parameter[:parameter_name_index].strip()
384         # Remove any initializers from the parameter name (e.g. int i = 5).
385         self.name = sub(r'=.*', '', parameter[parameter_name_index:]).strip()
386         self.row = row
387
388     @memoized
389     def lower_with_underscores_name(self):
390         """Returns the parameter name in the lower with underscores format."""
391         return _convert_to_lower_with_underscores(self.name)
392
393
394 class SingleLineView(object):
395     """Converts multiple lines into a single line (with line breaks replaced by a
396        space) to allow for easier searching."""
397     def __init__(self, lines, start_position, end_position):
398         """Create a SingleLineView instance.
399
400         Args:
401           lines: a list of multiple lines to combine into a single line.
402           start_position: offset within lines of where to start the single line.
403           end_position: just after where to end (like a slice operation).
404         """
405         # Get the rows of interest.
406         trimmed_lines = lines[start_position.row:end_position.row + 1]
407
408         # Remove the columns on the last line that aren't included.
409         trimmed_lines[-1] = trimmed_lines[-1][:end_position.column]
410
411         # Remove the columns on the first line that aren't included.
412         trimmed_lines[0] = trimmed_lines[0][start_position.column:]
413
414         # Create a single line with all of the parameters.
415         self.single_line = ' '.join(trimmed_lines)
416
417         # Keep the row lengths, so we can calculate the original row number
418         # given a column in the single line (adding 1 due to the space added
419         # during the join).
420         self._row_lengths = [len(line) + 1 for line in trimmed_lines]
421         self._starting_row = start_position.row
422
423     def convert_column_to_row(self, single_line_column_number):
424         """Convert the column number from the single line into the original
425         line number.
426
427         Special cases:
428         * Columns in the added spaces are considered part of the previous line.
429         * Columns beyond the end of the line are consider part the last line
430         in the view."""
431         total_columns = 0
432         row_offset = 0
433         while row_offset < len(self._row_lengths) - 1 and single_line_column_number >= total_columns + self._row_lengths[row_offset]:
434             total_columns += self._row_lengths[row_offset]
435             row_offset += 1
436         return self._starting_row + row_offset
437
438
439 def create_skeleton_parameters(all_parameters):
440     """Converts a parameter list to a skeleton version.
441
442     The skeleton only has one word for the parameter name, one word for the type,
443     and commas after each parameter and only there. Everything in the skeleton
444     remains in the same columns as the original."""
445     all_simplifications = (
446         # Remove template parameters, function declaration parameters, etc.
447         r'(<[^<>]*?>)|(\([^\(\)]*?\))|(\{[^\{\}]*?\})',
448         # Remove all initializers.
449         r'=[^,]*',
450         # Remove :: and everything before it.
451         r'[^,]*::',
452         # Remove modifiers like &, *.
453         r'[&*]',
454         # Remove const modifiers.
455         r'\bconst\s+(?=[A-Za-z])',
456         # Remove numerical modifiers like long.
457         r'\b(unsigned|long|short)\s+(?=unsigned|long|short|int|char|double|float)')
458
459     skeleton_parameters = all_parameters
460     for simplification in all_simplifications:
461         skeleton_parameters = iteratively_replace_matches_with_char(simplification, ' ', skeleton_parameters)
462     # If there are any parameters, then add a , after the last one to
463     # make a regular pattern of a , following every parameter.
464     if skeleton_parameters.strip():
465         skeleton_parameters += ','
466     return skeleton_parameters
467
468
469 def find_parameter_name_index(skeleton_parameter):
470     """Determines where the parametere name starts given the skeleton parameter."""
471     # The first space from the right in the simplified parameter is where the parameter
472     # name starts unless the first space is before any content in the simplified parameter.
473     before_name_index = skeleton_parameter.rstrip().rfind(' ')
474     if before_name_index != -1 and skeleton_parameter[:before_name_index].strip():
475         return before_name_index + 1
476     return len(skeleton_parameter)
477
478
479 def parameter_list(elided_lines, start_position, end_position):
480     """Generator for a function's parameters."""
481     # Create new positions that omit the outer parenthesis of the parameters.
482     start_position = Position(row=start_position.row, column=start_position.column + 1)
483     end_position = Position(row=end_position.row, column=end_position.column - 1)
484     single_line_view = SingleLineView(elided_lines, start_position, end_position)
485     skeleton_parameters = create_skeleton_parameters(single_line_view.single_line)
486     end_index = -1
487
488     while True:
489         # Find the end of the next parameter.
490         start_index = end_index + 1
491         end_index = skeleton_parameters.find(',', start_index)
492
493         # No comma means that all parameters have been parsed.
494         if end_index == -1:
495             return
496         row = single_line_view.convert_column_to_row(end_index)
497
498         # Parse the parameter into a type and parameter name.
499         skeleton_parameter = skeleton_parameters[start_index:end_index]
500         name_offset = find_parameter_name_index(skeleton_parameter)
501         parameter = single_line_view.single_line[start_index:end_index]
502         yield Parameter(parameter, name_offset, row)
503
504
505 class _FunctionState(object):
506     """Tracks current function name and the number of lines in its body.
507
508     Attributes:
509       min_confidence: The minimum confidence level to use while checking style.
510
511     """
512
513     _NORMAL_TRIGGER = 250  # for --v=0, 500 for --v=1, etc.
514     _TEST_TRIGGER = 400    # about 50% more than _NORMAL_TRIGGER.
515
516     def __init__(self, min_confidence):
517         self.min_confidence = min_confidence
518         self.current_function = ''
519         self.in_a_function = False
520         self.lines_in_function = 0
521         # Make sure these will not be mistaken for real positions (even when a
522         # small amount is added to them).
523         self.body_start_position = Position(-1000, 0)
524         self.end_position = Position(-1000, 0)
525
526     def begin(self, function_name, function_name_start_position, body_start_position, end_position,
527               parameter_start_position, parameter_end_position, clean_lines):
528         """Start analyzing function body.
529
530         Args:
531             function_name: The name of the function being tracked.
532             function_name_start_position: Position in elided where the function name starts.
533             body_start_position: Position in elided of the { or the ; for a prototype.
534             end_position: Position in elided just after the final } (or ; is.
535             parameter_start_position: Position in elided of the '(' for the parameters.
536             parameter_end_position: Position in elided just after the ')' for the parameters.
537             clean_lines: A CleansedLines instance containing the file.
538         """
539         self.in_a_function = True
540         self.lines_in_function = -1  # Don't count the open brace line.
541         self.current_function = function_name
542         self.function_name_start_position = function_name_start_position
543         self.body_start_position = body_start_position
544         self.end_position = end_position
545         self.is_declaration = clean_lines.elided[body_start_position.row][body_start_position.column] == ';'
546         self.parameter_start_position = parameter_start_position
547         self.parameter_end_position = parameter_end_position
548         self.is_pure = False
549         if self.is_declaration:
550             characters_after_parameters = SingleLineView(clean_lines.elided, parameter_end_position, body_start_position).single_line
551             self.is_pure = bool(match(r'\s*=\s*0\s*', characters_after_parameters))
552         self._clean_lines = clean_lines
553         self._parameter_list = None
554
555     def modifiers_and_return_type(self):
556         """Returns the modifiers and the return type."""
557         # Go backwards from where the function name is until we encounter one of several things:
558         #   ';' or '{' or '}' or 'private:', etc. or '#' or return Position(0, 0)
559         elided = self._clean_lines.elided
560         start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected):)|(#.*)',
561                                           elided, self.parameter_start_position, Position(0, 0))
562         return SingleLineView(elided, start_modifiers, self.function_name_start_position).single_line.strip()
563
564     def parameter_list(self):
565         if not self._parameter_list:
566             # Store the final result as a tuple since that is immutable.
567             self._parameter_list = tuple(parameter_list(self._clean_lines.elided, self.parameter_start_position, self.parameter_end_position))
568
569         return self._parameter_list
570
571     def count(self, line_number):
572         """Count line in current function body."""
573         if self.in_a_function and line_number >= self.body_start_position.row:
574             self.lines_in_function += 1
575
576     def check(self, error, line_number):
577         """Report if too many lines in function body.
578
579         Args:
580           error: The function to call with any errors found.
581           line_number: The number of the line to check.
582         """
583         if match(r'T(EST|est)', self.current_function):
584             base_trigger = self._TEST_TRIGGER
585         else:
586             base_trigger = self._NORMAL_TRIGGER
587         trigger = base_trigger * 2 ** self.min_confidence
588
589         if self.lines_in_function > trigger:
590             error_level = int(math.log(self.lines_in_function / base_trigger, 2))
591             # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
592             if error_level > 5:
593                 error_level = 5
594             error(line_number, 'readability/fn_size', error_level,
595                   'Small and focused functions are preferred:'
596                   ' %s has %d non-comment lines'
597                   ' (error triggered by exceeding %d lines).'  % (
598                       self.current_function, self.lines_in_function, trigger))
599
600     def end(self):
601         """Stop analyzing function body."""
602         self.in_a_function = False
603
604
605 class _IncludeError(Exception):
606     """Indicates a problem with the include order in a file."""
607     pass
608
609
610 class FileInfo:
611     """Provides utility functions for filenames.
612
613     FileInfo provides easy access to the components of a file's path
614     relative to the project root.
615     """
616
617     def __init__(self, filename):
618         self._filename = filename
619
620     def full_name(self):
621         """Make Windows paths like Unix."""
622         return os.path.abspath(self._filename).replace('\\', '/')
623
624     def repository_name(self):
625         """Full name after removing the local path to the repository.
626
627         If we have a real absolute path name here we can try to do something smart:
628         detecting the root of the checkout and truncating /path/to/checkout from
629         the name so that we get header guards that don't include things like
630         "C:\Documents and Settings\..." or "/home/username/..." in them and thus
631         people on different computers who have checked the source out to different
632         locations won't see bogus errors.
633         """
634         fullname = self.full_name()
635
636         if os.path.exists(fullname):
637             project_dir = os.path.dirname(fullname)
638
639             if os.path.exists(os.path.join(project_dir, ".svn")):
640                 # If there's a .svn file in the current directory, we
641                 # recursively look up the directory tree for the top
642                 # of the SVN checkout
643                 root_dir = project_dir
644                 one_up_dir = os.path.dirname(root_dir)
645                 while os.path.exists(os.path.join(one_up_dir, ".svn")):
646                     root_dir = os.path.dirname(root_dir)
647                     one_up_dir = os.path.dirname(one_up_dir)
648
649                 prefix = os.path.commonprefix([root_dir, project_dir])
650                 return fullname[len(prefix) + 1:]
651
652             # Not SVN? Try to find a git top level directory by
653             # searching up from the current path.
654             root_dir = os.path.dirname(fullname)
655             while (root_dir != os.path.dirname(root_dir)
656                    and not os.path.exists(os.path.join(root_dir, ".git"))):
657                 root_dir = os.path.dirname(root_dir)
658                 if os.path.exists(os.path.join(root_dir, ".git")):
659                     prefix = os.path.commonprefix([root_dir, project_dir])
660                     return fullname[len(prefix) + 1:]
661
662         # Don't know what to do; header guard warnings may be wrong...
663         return fullname
664
665     def split(self):
666         """Splits the file into the directory, basename, and extension.
667
668         For 'chrome/browser/browser.cpp', Split() would
669         return ('chrome/browser', 'browser', '.cpp')
670
671         Returns:
672           A tuple of (directory, basename, extension).
673         """
674
675         googlename = self.repository_name()
676         project, rest = os.path.split(googlename)
677         return (project,) + os.path.splitext(rest)
678
679     def base_name(self):
680         """File base name - text after the final slash, before the final period."""
681         return self.split()[1]
682
683     def extension(self):
684         """File extension - text following the final period."""
685         return self.split()[2]
686
687     def no_extension(self):
688         """File has no source file extension."""
689         return '/'.join(self.split()[0:2])
690
691     def is_source(self):
692         """File has a source file extension."""
693         return self.extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
694
695
696 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
697 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
698     r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
699 # Matches strings.  Escape codes should already be removed by ESCAPES.
700 _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
701 # Matches characters.  Escape codes should already be removed by ESCAPES.
702 _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
703 # Matches multi-line C++ comments.
704 # This RE is a little bit more complicated than one might expect, because we
705 # have to take care of space removals tools so we can handle comments inside
706 # statements better.
707 # The current rule is: We only clear spaces from both sides when we're at the
708 # end of the line. Otherwise, we try to remove spaces from the right side,
709 # if this doesn't work we try on left side but only if there's a non-character
710 # on the right.
711 _RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
712     r"""(\s*/\*.*\*/\s*$|
713             /\*.*\*/\s+|
714          \s+/\*.*\*/(?=\W)|
715             /\*.*\*/)""", re.VERBOSE)
716
717
718 def is_cpp_string(line):
719     """Does line terminate so, that the next symbol is in string constant.
720
721     This function does not consider single-line nor multi-line comments.
722
723     Args:
724       line: is a partial line of code starting from the 0..n.
725
726     Returns:
727       True, if next character appended to 'line' is inside a
728       string constant.
729     """
730
731     line = line.replace(r'\\', 'XX')  # after this, \\" does not match to \"
732     return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
733
734
735 def find_next_multi_line_comment_start(lines, line_index):
736     """Find the beginning marker for a multiline comment."""
737     while line_index < len(lines):
738         if lines[line_index].strip().startswith('/*'):
739             # Only return this marker if the comment goes beyond this line
740             if lines[line_index].strip().find('*/', 2) < 0:
741                 return line_index
742         line_index += 1
743     return len(lines)
744
745
746 def find_next_multi_line_comment_end(lines, line_index):
747     """We are inside a comment, find the end marker."""
748     while line_index < len(lines):
749         if lines[line_index].strip().endswith('*/'):
750             return line_index
751         line_index += 1
752     return len(lines)
753
754
755 def remove_multi_line_comments_from_range(lines, begin, end):
756     """Clears a range of lines for multi-line comments."""
757     # Having // dummy comments makes the lines non-empty, so we will not get
758     # unnecessary blank line warnings later in the code.
759     for i in range(begin, end):
760         lines[i] = '// dummy'
761
762
763 def remove_multi_line_comments(lines, error):
764     """Removes multiline (c-style) comments from lines."""
765     line_index = 0
766     while line_index < len(lines):
767         line_index_begin = find_next_multi_line_comment_start(lines, line_index)
768         if line_index_begin >= len(lines):
769             return
770         line_index_end = find_next_multi_line_comment_end(lines, line_index_begin)
771         if line_index_end >= len(lines):
772             error(line_index_begin + 1, 'readability/multiline_comment', 5,
773                   'Could not find end of multi-line comment')
774             return
775         remove_multi_line_comments_from_range(lines, line_index_begin, line_index_end + 1)
776         line_index = line_index_end + 1
777
778
779 def cleanse_comments(line):
780     """Removes //-comments and single-line C-style /* */ comments.
781
782     Args:
783       line: A line of C++ source.
784
785     Returns:
786       The line with single-line comments removed.
787     """
788     comment_position = line.find('//')
789     if comment_position != -1 and not is_cpp_string(line[:comment_position]):
790         line = line[:comment_position]
791     # get rid of /* ... */
792     return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
793
794
795 class CleansedLines(object):
796     """Holds 3 copies of all lines with different preprocessing applied to them.
797
798     1) elided member contains lines without strings and comments,
799     2) lines member contains lines without comments, and
800     3) raw member contains all the lines without processing.
801     All these three members are of <type 'list'>, and of the same length.
802     """
803
804     def __init__(self, lines):
805         self.elided = []
806         self.lines = []
807         self.raw_lines = lines
808         self._num_lines = len(lines)
809         for line_number in range(len(lines)):
810             self.lines.append(cleanse_comments(lines[line_number]))
811             elided = self.collapse_strings(lines[line_number])
812             self.elided.append(cleanse_comments(elided))
813
814     def num_lines(self):
815         """Returns the number of lines represented."""
816         return self._num_lines
817
818     @staticmethod
819     def collapse_strings(elided):
820         """Collapses strings and chars on a line to simple "" or '' blocks.
821
822         We nix strings first so we're not fooled by text like '"http://"'
823
824         Args:
825           elided: The line being processed.
826
827         Returns:
828           The line with collapsed strings.
829         """
830         if not _RE_PATTERN_INCLUDE.match(elided):
831             # Remove escaped characters first to make quote/single quote collapsing
832             # basic.  Things that look like escaped characters shouldn't occur
833             # outside of strings and chars.
834             elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
835             elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
836             elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
837         return elided
838
839
840 def close_expression(elided, position):
841     """If input points to ( or { or [, finds the position that closes it.
842
843     If elided[position.row][position.column] points to a '(' or '{' or '[',
844     finds the line_number/pos that correspond to the closing of the expression.
845
846      Args:
847        elided: A CleansedLines.elided instance containing the file.
848        position: The position of the opening item.
849
850      Returns:
851       The Position *past* the closing brace, or Position(len(elided), -1)
852       if we never find a close. Note we ignore strings and comments when matching.
853     """
854     line = elided[position.row]
855     start_character = line[position.column]
856     if start_character == '(':
857         enclosing_character_regex = r'[\(\)]'
858     elif start_character == '[':
859         enclosing_character_regex = r'[\[\]]'
860     elif start_character == '{':
861         enclosing_character_regex = r'[\{\}]'
862     else:
863         return Position(len(elided), -1)
864
865     current_column = position.column + 1
866     line_number = position.row
867     net_open = 1
868     for line in elided[position.row:]:
869         line = line[current_column:]
870
871         # Search the current line for opening and closing characters.
872         while True:
873             next_enclosing_character = search(enclosing_character_regex, line)
874             # No more on this line.
875             if not next_enclosing_character:
876                 break
877             current_column += next_enclosing_character.end(0)
878             line = line[next_enclosing_character.end(0):]
879             if next_enclosing_character.group(0) == start_character:
880                 net_open += 1
881             else:
882                 net_open -= 1
883                 if not net_open:
884                     return Position(line_number, current_column)
885
886         # Proceed to the next line.
887         line_number += 1
888         current_column = 0
889
890     # The given item was not closed.
891     return Position(len(elided), -1)
892
893 def check_for_copyright(lines, error):
894     """Logs an error if no Copyright message appears at the top of the file."""
895
896     # We'll say it should occur by line 10. Don't forget there's a
897     # dummy line at the front.
898     for line in xrange(1, min(len(lines), 11)):
899         if re.search(r'Copyright', lines[line], re.I):
900             break
901     else:                       # means no copyright line was found
902         error(0, 'legal/copyright', 5,
903               'No copyright message found.  '
904               'You should have a line: "Copyright [year] <Copyright Owner>"')
905
906
907 def get_header_guard_cpp_variable(filename):
908     """Returns the CPP variable that should be used as a header guard.
909
910     Args:
911       filename: The name of a C++ header file.
912
913     Returns:
914       The CPP variable that should be used as a header guard in the
915       named file.
916
917     """
918
919     # Restores original filename in case that style checker is invoked from Emacs's
920     # flymake.
921     filename = re.sub(r'_flymake\.h$', '.h', filename)
922
923     standard_name = sub(r'[-.\s]', '_', os.path.basename(filename))
924
925     # Files under WTF typically have header guards that start with WTF_.
926     if filename.find('/wtf/'):
927         special_name = "WTF_" + standard_name
928     else:
929         special_name = standard_name
930     return (special_name, standard_name)
931
932
933 def check_for_header_guard(filename, lines, error):
934     """Checks that the file contains a header guard.
935
936     Logs an error if no #ifndef header guard is present.  For other
937     headers, checks that the full pathname is used.
938
939     Args:
940       filename: The name of the C++ header file.
941       lines: An array of strings, each representing a line of the file.
942       error: The function to call with any errors found.
943     """
944
945     cppvar = get_header_guard_cpp_variable(filename)
946
947     ifndef = None
948     ifndef_line_number = 0
949     define = None
950     for line_number, line in enumerate(lines):
951         line_split = line.split()
952         if len(line_split) >= 2:
953             # find the first occurrence of #ifndef and #define, save arg
954             if not ifndef and line_split[0] == '#ifndef':
955                 # set ifndef to the header guard presented on the #ifndef line.
956                 ifndef = line_split[1]
957                 ifndef_line_number = line_number
958             if not define and line_split[0] == '#define':
959                 define = line_split[1]
960             if define and ifndef:
961                 break
962
963     if not ifndef or not define or ifndef != define:
964         error(0, 'build/header_guard', 5,
965               'No #ifndef header guard found, suggested CPP variable is: %s' %
966               cppvar[0])
967         return
968
969     # The guard should be File_h.
970     if ifndef not in cppvar:
971         error(ifndef_line_number, 'build/header_guard', 5,
972               '#ifndef header guard has wrong style, please use: %s' % cppvar[0])
973
974
975 def check_for_unicode_replacement_characters(lines, error):
976     """Logs an error for each line containing Unicode replacement characters.
977
978     These indicate that either the file contained invalid UTF-8 (likely)
979     or Unicode replacement characters (which it shouldn't).  Note that
980     it's possible for this to throw off line numbering if the invalid
981     UTF-8 occurred adjacent to a newline.
982
983     Args:
984       lines: An array of strings, each representing a line of the file.
985       error: The function to call with any errors found.
986     """
987     for line_number, line in enumerate(lines):
988         if u'\ufffd' in line:
989             error(line_number, 'readability/utf8', 5,
990                   'Line contains invalid UTF-8 (or Unicode replacement character).')
991
992
993 def check_for_new_line_at_eof(lines, error):
994     """Logs an error if there is no newline char at the end of the file.
995
996     Args:
997       lines: An array of strings, each representing a line of the file.
998       error: The function to call with any errors found.
999     """
1000
1001     # The array lines() was created by adding two newlines to the
1002     # original file (go figure), then splitting on \n.
1003     # To verify that the file ends in \n, we just have to make sure the
1004     # last-but-two element of lines() exists and is empty.
1005     if len(lines) < 3 or lines[-2]:
1006         error(len(lines) - 2, 'whitespace/ending_newline', 5,
1007               'Could not find a newline character at the end of the file.')
1008
1009
1010 def check_for_multiline_comments_and_strings(clean_lines, line_number, error):
1011     """Logs an error if we see /* ... */ or "..." that extend past one line.
1012
1013     /* ... */ comments are legit inside macros, for one line.
1014     Otherwise, we prefer // comments, so it's ok to warn about the
1015     other.  Likewise, it's ok for strings to extend across multiple
1016     lines, as long as a line continuation character (backslash)
1017     terminates each line. Although not currently prohibited by the C++
1018     style guide, it's ugly and unnecessary. We don't do well with either
1019     in this lint program, so we warn about both.
1020
1021     Args:
1022       clean_lines: A CleansedLines instance containing the file.
1023       line_number: The number of the line to check.
1024       error: The function to call with any errors found.
1025     """
1026     line = clean_lines.elided[line_number]
1027
1028     # Remove all \\ (escaped backslashes) from the line. They are OK, and the
1029     # second (escaped) slash may trigger later \" detection erroneously.
1030     line = line.replace('\\\\', '')
1031
1032     if line.count('/*') > line.count('*/'):
1033         error(line_number, 'readability/multiline_comment', 5,
1034               'Complex multi-line /*...*/-style comment found. '
1035               'Lint may give bogus warnings.  '
1036               'Consider replacing these with //-style comments, '
1037               'with #if 0...#endif, '
1038               'or with more clearly structured multi-line comments.')
1039
1040     if (line.count('"') - line.count('\\"')) % 2:
1041         error(line_number, 'readability/multiline_string', 5,
1042               'Multi-line string ("...") found.  This lint script doesn\'t '
1043               'do well with such strings, and may give bogus warnings.  They\'re '
1044               'ugly and unnecessary, and you should use concatenation instead".')
1045
1046
1047 _THREADING_LIST = (
1048     ('asctime(', 'asctime_r('),
1049     ('ctime(', 'ctime_r('),
1050     ('getgrgid(', 'getgrgid_r('),
1051     ('getgrnam(', 'getgrnam_r('),
1052     ('getlogin(', 'getlogin_r('),
1053     ('getpwnam(', 'getpwnam_r('),
1054     ('getpwuid(', 'getpwuid_r('),
1055     ('gmtime(', 'gmtime_r('),
1056     ('localtime(', 'localtime_r('),
1057     ('rand(', 'rand_r('),
1058     ('readdir(', 'readdir_r('),
1059     ('strtok(', 'strtok_r('),
1060     ('ttyname(', 'ttyname_r('),
1061     )
1062
1063
1064 def check_posix_threading(clean_lines, line_number, error):
1065     """Checks for calls to thread-unsafe functions.
1066
1067     Much code has been originally written without consideration of
1068     multi-threading. Also, engineers are relying on their old experience;
1069     they have learned posix before threading extensions were added. These
1070     tests guide the engineers to use thread-safe functions (when using
1071     posix directly).
1072
1073     Args:
1074       clean_lines: A CleansedLines instance containing the file.
1075       line_number: The number of the line to check.
1076       error: The function to call with any errors found.
1077     """
1078     line = clean_lines.elided[line_number]
1079     for single_thread_function, multithread_safe_function in _THREADING_LIST:
1080         index = line.find(single_thread_function)
1081         # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1082         if index >= 0 and (index == 0 or (not line[index - 1].isalnum()
1083                                           and line[index - 1] not in ('_', '.', '>'))):
1084             error(line_number, 'runtime/threadsafe_fn', 2,
1085                   'Consider using ' + multithread_safe_function +
1086                   '...) instead of ' + single_thread_function +
1087                   '...) for improved thread safety.')
1088
1089
1090 # Matches invalid increment: *count++, which moves pointer instead of
1091 # incrementing a value.
1092 _RE_PATTERN_INVALID_INCREMENT = re.compile(
1093     r'^\s*\*\w+(\+\+|--);')
1094
1095
1096 def check_invalid_increment(clean_lines, line_number, error):
1097     """Checks for invalid increment *count++.
1098
1099     For example following function:
1100     void increment_counter(int* count) {
1101         *count++;
1102     }
1103     is invalid, because it effectively does count++, moving pointer, and should
1104     be replaced with ++*count, (*count)++ or *count += 1.
1105
1106     Args:
1107       clean_lines: A CleansedLines instance containing the file.
1108       line_number: The number of the line to check.
1109       error: The function to call with any errors found.
1110     """
1111     line = clean_lines.elided[line_number]
1112     if _RE_PATTERN_INVALID_INCREMENT.match(line):
1113         error(line_number, 'runtime/invalid_increment', 5,
1114               'Changing pointer instead of value (or unused value of operator*).')
1115
1116
1117 class _ClassInfo(object):
1118     """Stores information about a class."""
1119
1120     def __init__(self, name, line_number):
1121         self.name = name
1122         self.line_number = line_number
1123         self.seen_open_brace = False
1124         self.is_derived = False
1125         self.virtual_method_line_number = None
1126         self.has_virtual_destructor = False
1127         self.brace_depth = 0
1128
1129
1130 class _ClassState(object):
1131     """Holds the current state of the parse relating to class declarations.
1132
1133     It maintains a stack of _ClassInfos representing the parser's guess
1134     as to the current nesting of class declarations. The innermost class
1135     is at the top (back) of the stack. Typically, the stack will either
1136     be empty or have exactly one entry.
1137     """
1138
1139     def __init__(self):
1140         self.classinfo_stack = []
1141
1142     def check_finished(self, error):
1143         """Checks that all classes have been completely parsed.
1144
1145         Call this when all lines in a file have been processed.
1146         Args:
1147           error: The function to call with any errors found.
1148         """
1149         if self.classinfo_stack:
1150             # Note: This test can result in false positives if #ifdef constructs
1151             # get in the way of brace matching. See the testBuildClass test in
1152             # cpp_style_unittest.py for an example of this.
1153             error(self.classinfo_stack[0].line_number, 'build/class', 5,
1154                   'Failed to find complete declaration of class %s' %
1155                   self.classinfo_stack[0].name)
1156
1157
1158 class _FileState(object):
1159     def __init__(self, clean_lines, file_extension):
1160         self._did_inside_namespace_indent_warning = False
1161         self._clean_lines = clean_lines
1162         if file_extension in ['m', 'mm']:
1163             self._is_objective_c = True
1164         elif file_extension == 'h':
1165             # In the case of header files, it is unknown if the file
1166             # is objective c or not, so set this value to None and then
1167             # if it is requested, use heuristics to guess the value.
1168             self._is_objective_c = None
1169         else:
1170             self._is_objective_c = False
1171         self._is_c = file_extension == 'c'
1172
1173     def set_did_inside_namespace_indent_warning(self):
1174         self._did_inside_namespace_indent_warning = True
1175
1176     def did_inside_namespace_indent_warning(self):
1177         return self._did_inside_namespace_indent_warning
1178
1179     def is_objective_c(self):
1180         if self._is_objective_c is None:
1181             for line in self._clean_lines.elided:
1182                 # Starting with @ or #import seem like the best indications
1183                 # that we have an Objective C file.
1184                 if line.startswith("@") or line.startswith("#import"):
1185                     self._is_objective_c = True
1186                     break
1187             else:
1188                 self._is_objective_c = False
1189         return self._is_objective_c
1190
1191     def is_c_or_objective_c(self):
1192         """Return whether the file extension corresponds to C or Objective-C."""
1193         return self._is_c or self.is_objective_c()
1194
1195
1196 def check_for_non_standard_constructs(clean_lines, line_number,
1197                                       class_state, error):
1198     """Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
1199
1200     Complain about several constructs which gcc-2 accepts, but which are
1201     not standard C++.  Warning about these in lint is one way to ease the
1202     transition to new compilers.
1203     - put storage class first (e.g. "static const" instead of "const static").
1204     - "%lld" instead of %qd" in printf-type functions.
1205     - "%1$d" is non-standard in printf-type functions.
1206     - "\%" is an undefined character escape sequence.
1207     - text after #endif is not allowed.
1208     - invalid inner-style forward declaration.
1209     - >? and <? operators, and their >?= and <?= cousins.
1210     - classes with virtual methods need virtual destructors (compiler warning
1211         available, but not turned on yet.)
1212
1213     Additionally, check for constructor/destructor style violations as it
1214     is very convenient to do so while checking for gcc-2 compliance.
1215
1216     Args:
1217       clean_lines: A CleansedLines instance containing the file.
1218       line_number: The number of the line to check.
1219       class_state: A _ClassState instance which maintains information about
1220                    the current stack of nested class declarations being parsed.
1221       error: A callable to which errors are reported, which takes parameters:
1222              line number, error level, and message
1223     """
1224
1225     # Remove comments from the line, but leave in strings for now.
1226     line = clean_lines.lines[line_number]
1227
1228     if search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
1229         error(line_number, 'runtime/printf_format', 3,
1230               '%q in format strings is deprecated.  Use %ll instead.')
1231
1232     if search(r'printf\s*\(.*".*%\d+\$', line):
1233         error(line_number, 'runtime/printf_format', 2,
1234               '%N$ formats are unconventional.  Try rewriting to avoid them.')
1235
1236     # Remove escaped backslashes before looking for undefined escapes.
1237     line = line.replace('\\\\', '')
1238
1239     if search(r'("|\').*\\(%|\[|\(|{)', line):
1240         error(line_number, 'build/printf_format', 3,
1241               '%, [, (, and { are undefined character escapes.  Unescape them.')
1242
1243     # For the rest, work with both comments and strings removed.
1244     line = clean_lines.elided[line_number]
1245
1246     if search(r'\b(const|volatile|void|char|short|int|long'
1247               r'|float|double|signed|unsigned'
1248               r'|schar|u?int8|u?int16|u?int32|u?int64)'
1249               r'\s+(auto|register|static|extern|typedef)\b',
1250               line):
1251         error(line_number, 'build/storage_class', 5,
1252               'Storage class (static, extern, typedef, etc) should be first.')
1253
1254     if match(r'\s*#\s*endif\s*[^/\s]+', line):
1255         error(line_number, 'build/endif_comment', 5,
1256               'Uncommented text after #endif is non-standard.  Use a comment.')
1257
1258     if match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
1259         error(line_number, 'build/forward_decl', 5,
1260               'Inner-style forward declarations are invalid.  Remove this line.')
1261
1262     if search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', line):
1263         error(line_number, 'build/deprecated', 3,
1264               '>? and <? (max and min) operators are non-standard and deprecated.')
1265
1266     # Track class entry and exit, and attempt to find cases within the
1267     # class declaration that don't meet the C++ style
1268     # guidelines. Tracking is very dependent on the code matching Google
1269     # style guidelines, but it seems to perform well enough in testing
1270     # to be a worthwhile addition to the checks.
1271     classinfo_stack = class_state.classinfo_stack
1272     # Look for a class declaration
1273     class_decl_match = match(
1274         r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line)
1275     if class_decl_match:
1276         classinfo_stack.append(_ClassInfo(class_decl_match.group(3), line_number))
1277
1278     # Everything else in this function uses the top of the stack if it's
1279     # not empty.
1280     if not classinfo_stack:
1281         return
1282
1283     classinfo = classinfo_stack[-1]
1284
1285     # If the opening brace hasn't been seen look for it and also
1286     # parent class declarations.
1287     if not classinfo.seen_open_brace:
1288         # If the line has a ';' in it, assume it's a forward declaration or
1289         # a single-line class declaration, which we won't process.
1290         if line.find(';') != -1:
1291             classinfo_stack.pop()
1292             return
1293         classinfo.seen_open_brace = (line.find('{') != -1)
1294         # Look for a bare ':'
1295         if search('(^|[^:]):($|[^:])', line):
1296             classinfo.is_derived = True
1297         if not classinfo.seen_open_brace:
1298             return  # Everything else in this function is for after open brace
1299
1300     # The class may have been declared with namespace or classname qualifiers.
1301     # The constructor and destructor will not have those qualifiers.
1302     base_classname = classinfo.name.split('::')[-1]
1303
1304     # Look for single-argument constructors that aren't marked explicit.
1305     # Technically a valid construct, but against style.
1306     args = match(r'(?<!explicit)\s+%s\s*\(([^,()]+)\)'
1307                  % re.escape(base_classname),
1308                  line)
1309     if (args
1310         and args.group(1) != 'void'
1311         and not match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
1312                       args.group(1).strip())):
1313         error(line_number, 'runtime/explicit', 5,
1314               'Single-argument constructors should be marked explicit.')
1315
1316     # Look for methods declared virtual.
1317     if search(r'\bvirtual\b', line):
1318         classinfo.virtual_method_line_number = line_number
1319         # Only look for a destructor declaration on the same line. It would
1320         # be extremely unlikely for the destructor declaration to occupy
1321         # more than one line.
1322         if search(r'~%s\s*\(' % base_classname, line):
1323             classinfo.has_virtual_destructor = True
1324
1325     # Look for class end.
1326     brace_depth = classinfo.brace_depth
1327     brace_depth = brace_depth + line.count('{') - line.count('}')
1328     if brace_depth <= 0:
1329         classinfo = classinfo_stack.pop()
1330         # Try to detect missing virtual destructor declarations.
1331         # For now, only warn if a non-derived class with virtual methods lacks
1332         # a virtual destructor. This is to make it less likely that people will
1333         # declare derived virtual destructors without declaring the base
1334         # destructor virtual.
1335         if ((classinfo.virtual_method_line_number is not None)
1336             and (not classinfo.has_virtual_destructor)
1337             and (not classinfo.is_derived)):  # Only warn for base classes
1338             error(classinfo.line_number, 'runtime/virtual', 4,
1339                   'The class %s probably needs a virtual destructor due to '
1340                   'having virtual method(s), one declared at line %d.'
1341                   % (classinfo.name, classinfo.virtual_method_line_number))
1342     else:
1343         classinfo.brace_depth = brace_depth
1344
1345
1346 def check_spacing_for_function_call(line, line_number, error):
1347     """Checks for the correctness of various spacing around function calls.
1348
1349     Args:
1350       line: The text of the line to check.
1351       line_number: The number of the line to check.
1352       error: The function to call with any errors found.
1353     """
1354
1355     # Since function calls often occur inside if/for/foreach/while/switch
1356     # expressions - which have their own, more liberal conventions - we
1357     # first see if we should be looking inside such an expression for a
1358     # function call, to which we can apply more strict standards.
1359     function_call = line    # if there's no control flow construct, look at whole line
1360     for pattern in (r'\bif\s*\((.*)\)\s*{',
1361                     r'\bfor\s*\((.*)\)\s*{',
1362                     r'\bforeach\s*\((.*)\)\s*{',
1363                     r'\bwhile\s*\((.*)\)\s*[{;]',
1364                     r'\bswitch\s*\((.*)\)\s*{'):
1365         matched = search(pattern, line)
1366         if matched:
1367             function_call = matched.group(1)    # look inside the parens for function calls
1368             break
1369
1370     # Except in if/for/foreach/while/switch, there should never be space
1371     # immediately inside parens (eg "f( 3, 4 )").  We make an exception
1372     # for nested parens ( (a+b) + c ).  Likewise, there should never be
1373     # a space before a ( when it's a function argument.  I assume it's a
1374     # function argument when the char before the whitespace is legal in
1375     # a function name (alnum + _) and we're not starting a macro. Also ignore
1376     # pointers and references to arrays and functions coz they're too tricky:
1377     # we use a very simple way to recognize these:
1378     # " (something)(maybe-something)" or
1379     # " (something)(maybe-something," or
1380     # " (something)[something]"
1381     # Note that we assume the contents of [] to be short enough that
1382     # they'll never need to wrap.
1383     if (  # Ignore control structures.
1384         not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', function_call)
1385         # Ignore pointers/references to functions.
1386         and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call)
1387         # Ignore pointers/references to arrays.
1388         and not search(r' \([^)]+\)\[[^\]]+\]', function_call)):
1389         if search(r'\w\s*\([ \t](?!\s*\\$)', function_call):      # a ( used for a fn call
1390             error(line_number, 'whitespace/parens', 4,
1391                   'Extra space after ( in function call')
1392         elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call):
1393             error(line_number, 'whitespace/parens', 2,
1394                   'Extra space after (')
1395         if (search(r'\w\s+\(', function_call)
1396             and not match(r'\s*(#|typedef)', function_call)):
1397             error(line_number, 'whitespace/parens', 4,
1398                   'Extra space before ( in function call')
1399         # If the ) is followed only by a newline or a { + newline, assume it's
1400         # part of a control statement (if/while/etc), and don't complain
1401         if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call):
1402             error(line_number, 'whitespace/parens', 2,
1403                   'Extra space before )')
1404
1405
1406 def is_blank_line(line):
1407     """Returns true if the given line is blank.
1408
1409     We consider a line to be blank if the line is empty or consists of
1410     only white spaces.
1411
1412     Args:
1413       line: A line of a string.
1414
1415     Returns:
1416       True, if the given line is blank.
1417     """
1418     return not line or line.isspace()
1419
1420
1421 def detect_functions(clean_lines, line_number, function_state, error):
1422     """Finds where functions start and end.
1423
1424     Uses a simplistic algorithm assuming other style guidelines
1425     (especially spacing) are followed.
1426     Trivial bodies are unchecked, so constructors with huge initializer lists
1427     may be missed.
1428
1429     Args:
1430       clean_lines: A CleansedLines instance containing the file.
1431       line_number: The number of the line to check.
1432       function_state: Current function name and lines in body so far.
1433       error: The function to call with any errors found.
1434     """
1435     # Are we now past the end of a function?
1436     if function_state.end_position.row + 1 == line_number:
1437         function_state.end()
1438
1439     # If we're in a function, don't try to detect a new one.
1440     if function_state.in_a_function:
1441         return
1442
1443     lines = clean_lines.lines
1444     line = lines[line_number]
1445     raw = clean_lines.raw_lines
1446     raw_line = raw[line_number]
1447
1448     # Lines ending with a \ indicate a macro. Don't try to check them.
1449     if raw_line.endswith('\\'):
1450         return
1451
1452     regexp = r'\s*(\w(\w|::|\*|\&|\s|<|>|,|~|(operator\s*(/|-|=|!|\+)+))*)\('  # decls * & space::name( ...
1453     match_result = match(regexp, line)
1454     if not match_result:
1455         return
1456
1457     # If the name is all caps and underscores, figure it's a macro and
1458     # ignore it, unless it's TEST or TEST_F.
1459     function_name = match_result.group(1).split()[-1]
1460     if function_name != 'TEST' and function_name != 'TEST_F' and match(r'[A-Z_]+$', function_name):
1461         return
1462
1463     joined_line = ''
1464     for start_line_number in xrange(line_number, clean_lines.num_lines()):
1465         start_line = clean_lines.elided[start_line_number]
1466         joined_line += ' ' + start_line.lstrip()
1467         body_match = search(r'{|;', start_line)
1468         if body_match:
1469             body_start_position = Position(start_line_number, body_match.start(0))
1470
1471             # Replace template constructs with _ so that no spaces remain in the function name,
1472             # while keeping the column numbers of other characters the same as "line".
1473             line_with_no_templates = iteratively_replace_matches_with_char(r'<[^<>]*>', '_', line)
1474             match_function = search(r'((\w|:|<|>|,|~|(operator\s*(/|-|=|!|\+)+))*)\(', line_with_no_templates)
1475             if not match_function:
1476                 return  # The '(' must have been inside of a template.
1477
1478             # Use the column numbers from the modified line to find the
1479             # function name in the original line.
1480             function = line[match_function.start(1):match_function.end(1)]
1481             function_name_start_position = Position(line_number, match_function.start(1))
1482
1483             if match(r'TEST', function):    # Handle TEST... macros
1484                 parameter_regexp = search(r'(\(.*\))', joined_line)
1485                 if parameter_regexp:             # Ignore bad syntax
1486                     function += parameter_regexp.group(1)
1487             else:
1488                 function += '()'
1489
1490             parameter_start_position = Position(line_number, match_function.end(1))
1491             parameter_end_position = close_expression(clean_lines.elided, parameter_start_position)
1492             if parameter_end_position.row == len(clean_lines.elided):
1493                 # No end was found.
1494                 return
1495
1496             if start_line[body_start_position.column] == ';':
1497                 end_position = Position(body_start_position.row, body_start_position.column + 1)
1498             else:
1499                 end_position = close_expression(clean_lines.elided, body_start_position)
1500
1501             # Check for nonsensical positions. (This happens in test cases which check code snippets.)
1502             if parameter_end_position > body_start_position:
1503                 return
1504
1505             function_state.begin(function, function_name_start_position, body_start_position, end_position,
1506                                  parameter_start_position, parameter_end_position, clean_lines)
1507             return
1508
1509     # No body for the function (or evidence of a non-function) was found.
1510     error(line_number, 'readability/fn_size', 5,
1511           'Lint failed to find start of function body.')
1512
1513
1514 def check_for_function_lengths(clean_lines, line_number, function_state, error):
1515     """Reports for long function bodies.
1516
1517     For an overview why this is done, see:
1518     http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
1519
1520     Blank/comment lines are not counted so as to avoid encouraging the removal
1521     of vertical space and commments just to get through a lint check.
1522     NOLINT *on the last line of a function* disables this check.
1523
1524     Args:
1525       clean_lines: A CleansedLines instance containing the file.
1526       line_number: The number of the line to check.
1527       function_state: Current function name and lines in body so far.
1528       error: The function to call with any errors found.
1529     """
1530     lines = clean_lines.lines
1531     line = lines[line_number]
1532     raw = clean_lines.raw_lines
1533     raw_line = raw[line_number]
1534
1535     if function_state.end_position.row == line_number:  # last line
1536         if not search(r'\bNOLINT\b', raw_line):
1537             function_state.check(error, line_number)
1538     elif not match(r'^\s*$', line):
1539         function_state.count(line_number)  # Count non-blank/non-comment lines.
1540
1541
1542 def _check_parameter_name_against_text(parameter, text, error):
1543     """Checks to see if the parameter name is contained within the text.
1544
1545     Return false if the check failed (i.e. an error was produced).
1546     """
1547
1548     # Treat 'lower with underscores' as a canonical form because it is
1549     # case insensitive while still retaining word breaks. (This ensures that
1550     # 'elate' doesn't look like it is duplicating of 'NateLate'.)
1551     canonical_parameter_name = parameter.lower_with_underscores_name()
1552
1553     # Appends "object" to all text to catch variables that did the same (but only
1554     # do this when the parameter name is more than a single character to avoid
1555     # flagging 'b' which may be an ok variable when used in an rgba function).
1556     if len(canonical_parameter_name) > 1:
1557         text = sub(r'(\w)\b', r'\1Object', text)
1558     canonical_text = _convert_to_lower_with_underscores(text)
1559
1560     # Used to detect cases like ec for ExceptionCode.
1561     acronym = _create_acronym(text).lower()
1562     if canonical_text.find(canonical_parameter_name) != -1 or acronym.find(canonical_parameter_name) != -1:
1563         error(parameter.row, 'readability/parameter_name', 5,
1564               'The parameter name "%s" adds no information, so it should be removed.' % parameter.name)
1565         return False
1566     return True
1567
1568
1569 def check_function_definition_and_pass_ptr(type_text, row, location_description, error):
1570     """Check that function definitions for use Pass*Ptr instead of *Ptr.
1571
1572     Args:
1573        type_text: A string containing the type. (For return values, it may contain more than the type.)
1574        row: The row number of the type.
1575        location_description: Used to indicate where the type is. This is either 'parameter' or 'return'.
1576        error: The function to call with any errors found.
1577     """
1578     match_ref_or_own_ptr = '(?=\W|^)(Ref|Own)Ptr(?=\W)'
1579     bad_type_usage = search(match_ref_or_own_ptr, type_text)
1580     if not bad_type_usage:
1581         return
1582     type_name = bad_type_usage.group(0)
1583     error(row, 'readability/pass_ptr', 5,
1584           'The %s type should use Pass%s instead of %s.' % (location_description, type_name, type_name))
1585
1586
1587 def check_function_definition(filename, file_extension, clean_lines, line_number, function_state, error):
1588     """Check that function definitions for style issues.
1589
1590     Specifically, check that parameter names in declarations add information.
1591
1592     Args:
1593        filename: Filename of the file that is being processed.
1594        file_extension: The current file extension, without the leading dot.
1595        clean_lines: A CleansedLines instance containing the file.
1596        line_number: The number of the line to check.
1597        function_state: Current function name and lines in body so far.
1598        error: The function to call with any errors found.
1599     """
1600     if line_number != function_state.body_start_position.row:
1601         return
1602
1603     modifiers_and_return_type = function_state.modifiers_and_return_type()
1604     if filename.find('/chromium/') != -1 and search(r'\bWEBKIT_API\b', modifiers_and_return_type):
1605         if filename.find('/chromium/public/') == -1:
1606             error(function_state.function_name_start_position.row, 'readability/webkit_api', 5,
1607                   'WEBKIT_API should only appear in the chromium public directory.')
1608         elif not file_extension == "h":
1609             error(function_state.function_name_start_position.row, 'readability/webkit_api', 5,
1610                   'WEBKIT_API should only be used in header files.')
1611         elif not function_state.is_declaration or search(r'\binline\b', modifiers_and_return_type):
1612             error(function_state.function_name_start_position.row, 'readability/webkit_api', 5,
1613                   'WEBKIT_API should not be used on a function with a body.')
1614         elif function_state.is_pure:
1615             error(function_state.function_name_start_position.row, 'readability/webkit_api', 5,
1616                   'WEBKIT_API should not be used with a pure virtual function.')
1617
1618     check_function_definition_and_pass_ptr(modifiers_and_return_type, function_state.function_name_start_position.row, 'return', error)
1619
1620     parameter_list = function_state.parameter_list()
1621     for parameter in parameter_list:
1622         check_function_definition_and_pass_ptr(parameter.type, parameter.row, 'parameter', error)
1623
1624         # Do checks specific to function declarations and parameter names.
1625         if not function_state.is_declaration or not parameter.name:
1626             continue
1627
1628         # Check the parameter name against the function name for single parameter set functions.
1629         if len(parameter_list) == 1 and match('set[A-Z]', function_state.current_function):
1630             trimmed_function_name = function_state.current_function[len('set'):]
1631             if not _check_parameter_name_against_text(parameter, trimmed_function_name, error):
1632                 continue  # Since an error was noted for this name, move to the next parameter.
1633
1634         # Check the parameter name against the type.
1635         if not _check_parameter_name_against_text(parameter, parameter.type, error):
1636             continue  # Since an error was noted for this name, move to the next parameter.
1637
1638
1639 def check_pass_ptr_usage(clean_lines, line_number, function_state, error):
1640     """Check for proper usage of Pass*Ptr.
1641
1642     Currently this is limited to detecting declarations of Pass*Ptr
1643     variables inside of functions.
1644
1645     Args:
1646       clean_lines: A CleansedLines instance containing the file.
1647       line_number: The number of the line to check.
1648       function_state: Current function name and lines in body so far.
1649       error: The function to call with any errors found.
1650     """
1651     if not function_state.in_a_function:
1652         return
1653
1654     lines = clean_lines.lines
1655     line = lines[line_number]
1656     if line_number > function_state.body_start_position.row:
1657         matched_pass_ptr = match(r'^\s*Pass([A-Z][A-Za-z]*)Ptr<', line)
1658         if matched_pass_ptr:
1659             type_name = 'Pass%sPtr' % matched_pass_ptr.group(1)
1660             error(line_number, 'readability/pass_ptr', 5,
1661                   'Local variables should never be %s (see '
1662                   'http://webkit.org/coding/RefPtr.html).' % type_name)
1663
1664
1665 def check_spacing(file_extension, clean_lines, line_number, error):
1666     """Checks for the correctness of various spacing issues in the code.
1667
1668     Things we check for: spaces around operators, spaces after
1669     if/for/while/switch, no spaces around parens in function calls, two
1670     spaces between code and comment, don't start a block with a blank
1671     line, don't end a function with a blank line, don't have too many
1672     blank lines in a row.
1673
1674     Args:
1675       file_extension: The current file extension, without the leading dot.
1676       clean_lines: A CleansedLines instance containing the file.
1677       line_number: The number of the line to check.
1678       error: The function to call with any errors found.
1679     """
1680
1681     raw = clean_lines.raw_lines
1682     line = raw[line_number]
1683
1684     # Before nixing comments, check if the line is blank for no good
1685     # reason.  This includes the first line after a block is opened, and
1686     # blank lines at the end of a function (ie, right before a line like '}').
1687     if is_blank_line(line):
1688         elided = clean_lines.elided
1689         previous_line = elided[line_number - 1]
1690         previous_brace = previous_line.rfind('{')
1691         # FIXME: Don't complain if line before blank line, and line after,
1692         #        both start with alnums and are indented the same amount.
1693         #        This ignores whitespace at the start of a namespace block
1694         #        because those are not usually indented.
1695         if (previous_brace != -1 and previous_line[previous_brace:].find('}') == -1
1696             and previous_line[:previous_brace].find('namespace') == -1):
1697             # OK, we have a blank line at the start of a code block.  Before we
1698             # complain, we check if it is an exception to the rule: The previous
1699             # non-empty line has the parameters of a function header that are indented
1700             # 4 spaces (because they did not fit in a 80 column line when placed on
1701             # the same line as the function name).  We also check for the case where
1702             # the previous line is indented 6 spaces, which may happen when the
1703             # initializers of a constructor do not fit into a 80 column line.
1704             exception = False
1705             if match(r' {6}\w', previous_line):  # Initializer list?
1706                 # We are looking for the opening column of initializer list, which
1707                 # should be indented 4 spaces to cause 6 space indentation afterwards.
1708                 search_position = line_number - 2
1709                 while (search_position >= 0
1710                        and match(r' {6}\w', elided[search_position])):
1711                     search_position -= 1
1712                 exception = (search_position >= 0
1713                              and elided[search_position][:5] == '    :')
1714             else:
1715                 # Search for the function arguments or an initializer list.  We use a
1716                 # simple heuristic here: If the line is indented 4 spaces; and we have a
1717                 # closing paren, without the opening paren, followed by an opening brace
1718                 # or colon (for initializer lists) we assume that it is the last line of
1719                 # a function header.  If we have a colon indented 4 spaces, it is an
1720                 # initializer list.
1721                 exception = (match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
1722                                    previous_line)
1723                              or match(r' {4}:', previous_line))
1724
1725             if not exception:
1726                 error(line_number, 'whitespace/blank_line', 2,
1727                       'Blank line at the start of a code block.  Is this needed?')
1728         # This doesn't ignore whitespace at the end of a namespace block
1729         # because that is too hard without pairing open/close braces;
1730         # however, a special exception is made for namespace closing
1731         # brackets which have a comment containing "namespace".
1732         #
1733         # Also, ignore blank lines at the end of a block in a long if-else
1734         # chain, like this:
1735         #   if (condition1) {
1736         #     // Something followed by a blank line
1737         #
1738         #   } else if (condition2) {
1739         #     // Something else
1740         #   }
1741         if line_number + 1 < clean_lines.num_lines():
1742             next_line = raw[line_number + 1]
1743             if (next_line
1744                 and match(r'\s*}', next_line)
1745                 and next_line.find('namespace') == -1
1746                 and next_line.find('} else ') == -1):
1747                 error(line_number, 'whitespace/blank_line', 3,
1748                       'Blank line at the end of a code block.  Is this needed?')
1749
1750     # Next, we check for proper spacing with respect to comments.
1751     comment_position = line.find('//')
1752     if comment_position != -1:
1753         # Check if the // may be in quotes.  If so, ignore it
1754         # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
1755         if (line.count('"', 0, comment_position) - line.count('\\"', 0, comment_position)) % 2 == 0:   # not in quotes
1756             # Allow one space before end of line comment.
1757             if (not match(r'^\s*$', line[:comment_position])
1758                 and (comment_position >= 1
1759                 and ((line[comment_position - 1] not in string.whitespace)
1760                      or (comment_position >= 2
1761                          and line[comment_position - 2] in string.whitespace)))):
1762                 error(line_number, 'whitespace/comments', 5,
1763                       'One space before end of line comments')
1764             # There should always be a space between the // and the comment
1765             commentend = comment_position + 2
1766             if commentend < len(line) and not line[commentend] == ' ':
1767                 # but some lines are exceptions -- e.g. if they're big
1768                 # comment delimiters like:
1769                 # //----------------------------------------------------------
1770                 # or they begin with multiple slashes followed by a space:
1771                 # //////// Header comment
1772                 matched = (search(r'[=/-]{4,}\s*$', line[commentend:])
1773                            or search(r'^/+ ', line[commentend:]))
1774                 if not matched:
1775                     error(line_number, 'whitespace/comments', 4,
1776                           'Should have a space between // and comment')
1777
1778             # There should only be one space after punctuation in a comment.
1779             if search(r'[.!?,;:]\s\s+\w', line[comment_position:]):
1780                 error(line_number, 'whitespace/comments', 5,
1781                       'Should have only a single space after a punctuation in a comment.')
1782
1783     line = clean_lines.elided[line_number]  # get rid of comments and strings
1784
1785     # Don't try to do spacing checks for operator methods
1786     line = sub(r'operator(==|!=|<|<<|<=|>=|>>|>|\+=|-=|\*=|/=|%=|&=|\|=|^=|<<=|>>=)\(', 'operator\(', line)
1787     # Don't try to do spacing checks for #include or #import statements at
1788     # minimum because it messes up checks for spacing around /
1789     if match(r'\s*#\s*(?:include|import)', line):
1790         return
1791     if search(r'[\w.]=[\w.]', line):
1792         error(line_number, 'whitespace/operators', 4,
1793               'Missing spaces around =')
1794
1795     # FIXME: It's not ok to have spaces around binary operators like .
1796
1797     # You should always have whitespace around binary operators.
1798     # Alas, we can't test < or > because they're legitimately used sans spaces
1799     # (a->b, vector<int> a).  The only time we can tell is a < with no >, and
1800     # only if it's not template params list spilling into the next line.
1801     matched = search(r'[^<>=!\s](==|!=|\+=|-=|\*=|/=|/|\|=|&=|<<=|>>=|<=|>=|\|\||\||&&|>>|<<)[^<>=!\s]', line)
1802     if not matched:
1803         # Note that while it seems that the '<[^<]*' term in the following
1804         # regexp could be simplified to '<.*', which would indeed match
1805         # the same class of strings, the [^<] means that searching for the
1806         # regexp takes linear rather than quadratic time.
1807         if not search(r'<[^<]*,\s*$', line):  # template params spill
1808             matched = search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line)
1809     if matched:
1810         error(line_number, 'whitespace/operators', 3,
1811               'Missing spaces around %s' % matched.group(1))
1812
1813     # There shouldn't be space around unary operators
1814     matched = search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
1815     if matched:
1816         error(line_number, 'whitespace/operators', 4,
1817               'Extra space for operator %s' % matched.group(1))
1818
1819     # A pet peeve of mine: no spaces after an if, while, switch, or for
1820     matched = search(r' (if\(|for\(|foreach\(|while\(|switch\()', line)
1821     if matched:
1822         error(line_number, 'whitespace/parens', 5,
1823               'Missing space before ( in %s' % matched.group(1))
1824
1825     # For if/for/foreach/while/switch, the left and right parens should be
1826     # consistent about how many spaces are inside the parens, and
1827     # there should either be zero or one spaces inside the parens.
1828     # We don't want: "if ( foo)" or "if ( foo   )".
1829     # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
1830     matched = search(r'\b(?P<statement>if|for|foreach|while|switch)\s*\((?P<remainder>.*)$', line)
1831     if matched:
1832         statement = matched.group('statement')
1833         condition, rest = up_to_unmatched_closing_paren(matched.group('remainder'))
1834         if condition is not None:
1835             condition_match = search(r'(?P<leading>[ ]*)(?P<separator>.).*[^ ]+(?P<trailing>[ ]*)', condition)
1836             if condition_match:
1837                 n_leading = len(condition_match.group('leading'))
1838                 n_trailing = len(condition_match.group('trailing'))
1839                 if n_leading != 0:
1840                     for_exception = statement == 'for' and condition.startswith(' ;')
1841                     if not for_exception:
1842                         error(line_number, 'whitespace/parens', 5,
1843                               'Extra space after ( in %s' % statement)
1844                 if n_trailing != 0:
1845                     for_exception = statement == 'for' and condition.endswith('; ')
1846                     if not for_exception:
1847                         error(line_number, 'whitespace/parens', 5,
1848                               'Extra space before ) in %s' % statement)
1849
1850             # Do not check for more than one command in macros
1851             in_preprocessor_directive = match(r'\s*#', line)
1852             if not in_preprocessor_directive and not match(r'((\s*{\s*}?)|(\s*;?))\s*\\?$', rest):
1853                 error(line_number, 'whitespace/parens', 4,
1854                       'More than one command on the same line in %s' % statement)
1855
1856     # You should always have a space after a comma (either as fn arg or operator)
1857     if search(r',[^\s]', line):
1858         error(line_number, 'whitespace/comma', 3,
1859               'Missing space after ,')
1860
1861     matched = search(r'^\s*(?P<token1>[a-zA-Z0-9_\*&]+)\s\s+(?P<token2>[a-zA-Z0-9_\*&]+)', line)
1862     if matched:
1863         error(line_number, 'whitespace/declaration', 3,
1864               'Extra space between %s and %s' % (matched.group('token1'), matched.group('token2')))
1865
1866     if file_extension == 'cpp':
1867         # C++ should have the & or * beside the type not the variable name.
1868         matched = match(r'\s*\w+(?<!\breturn|\bdelete)\s+(?P<pointer_operator>\*|\&)\w+', line)
1869         if matched:
1870             error(line_number, 'whitespace/declaration', 3,
1871                   'Declaration has space between type name and %s in %s' % (matched.group('pointer_operator'), matched.group(0).strip()))
1872
1873     elif file_extension == 'c':
1874         # C Pointer declaration should have the * beside the variable not the type name.
1875         matched = search(r'^\s*\w+\*\s+\w+', line)
1876         if matched:
1877             error(line_number, 'whitespace/declaration', 3,
1878                   'Declaration has space between * and variable name in %s' % matched.group(0).strip())
1879
1880     # Next we will look for issues with function calls.
1881     check_spacing_for_function_call(line, line_number, error)
1882
1883     # Except after an opening paren, you should have spaces before your braces.
1884     # And since you should never have braces at the beginning of a line, this is
1885     # an easy test.
1886     if search(r'[^ ({]{', line):
1887         error(line_number, 'whitespace/braces', 5,
1888               'Missing space before {')
1889
1890     # Make sure '} else {' has spaces.
1891     if search(r'}else', line):
1892         error(line_number, 'whitespace/braces', 5,
1893               'Missing space before else')
1894
1895     # You shouldn't have spaces before your brackets, except maybe after
1896     # 'delete []' or 'new char * []'.
1897     if search(r'\w\s+\[', line) and not search(r'delete\s+\[', line):
1898         error(line_number, 'whitespace/braces', 5,
1899               'Extra space before [')
1900
1901     # There should always be a single space in between braces on the same line.
1902     if search(r'\{\}', line):
1903         error(line_number, 'whitespace/braces', 5, 'Missing space inside { }.')
1904     if search(r'\{\s\s+\}', line):
1905         error(line_number, 'whitespace/braces', 5, 'Too many spaces inside { }.')
1906
1907     # You shouldn't have a space before a semicolon at the end of the line.
1908     # There's a special case for "for" since the style guide allows space before
1909     # the semicolon there.
1910     if search(r':\s*;\s*$', line):
1911         error(line_number, 'whitespace/semicolon', 5,
1912               'Semicolon defining empty statement. Use { } instead.')
1913     elif search(r'^\s*;\s*$', line):
1914         error(line_number, 'whitespace/semicolon', 5,
1915               'Line contains only semicolon. If this should be an empty statement, '
1916               'use { } instead.')
1917     elif (search(r'\s+;\s*$', line) and not search(r'\bfor\b', line)):
1918         error(line_number, 'whitespace/semicolon', 5,
1919               'Extra space before last semicolon. If this should be an empty '
1920               'statement, use { } instead.')
1921     elif (search(r'\b(for|while)\s*\(.*\)\s*;\s*$', line)
1922           and line.count('(') == line.count(')')
1923           # Allow do {} while();
1924           and not search(r'}\s*while', line)):
1925         error(line_number, 'whitespace/semicolon', 5,
1926               'Semicolon defining empty statement for this loop. Use { } instead.')
1927
1928
1929 def get_previous_non_blank_line(clean_lines, line_number):
1930     """Return the most recent non-blank line and its line number.
1931
1932     Args:
1933       clean_lines: A CleansedLines instance containing the file contents.
1934       line_number: The number of the line to check.
1935
1936     Returns:
1937       A tuple with two elements.  The first element is the contents of the last
1938       non-blank line before the current line, or the empty string if this is the
1939       first non-blank line.  The second is the line number of that line, or -1
1940       if this is the first non-blank line.
1941     """
1942
1943     previous_line_number = line_number - 1
1944     while previous_line_number >= 0:
1945         previous_line = clean_lines.elided[previous_line_number]
1946         if not is_blank_line(previous_line):     # if not a blank line...
1947             return (previous_line, previous_line_number)
1948         previous_line_number -= 1
1949     return ('', -1)
1950
1951
1952 def check_namespace_indentation(clean_lines, line_number, file_extension, file_state, error):
1953     """Looks for indentation errors inside of namespaces.
1954
1955     Args:
1956       clean_lines: A CleansedLines instance containing the file.
1957       line_number: The number of the line to check.
1958       file_extension: The extension (dot not included) of the file.
1959       file_state: A _FileState instance which maintains information about
1960                   the state of things in the file.
1961       error: The function to call with any errors found.
1962     """
1963
1964     line = clean_lines.elided[line_number] # Get rid of comments and strings.
1965
1966     namespace_match = match(r'(?P<namespace_indentation>\s*)namespace\s+\S+\s*{\s*$', line)
1967     if not namespace_match:
1968         return
1969
1970     current_indentation_level = len(namespace_match.group('namespace_indentation'))
1971     if current_indentation_level > 0:
1972         # Don't warn about an indented namespace if we already warned about indented code.
1973         if not file_state.did_inside_namespace_indent_warning():
1974             error(line_number, 'whitespace/indent', 4,
1975                   'namespace should never be indented.')
1976         return
1977     looking_for_semicolon = False;
1978     line_offset = 0
1979     in_preprocessor_directive = False;
1980     for current_line in clean_lines.elided[line_number + 1:]:
1981         line_offset += 1
1982         if not current_line.strip():
1983             continue
1984         if not current_indentation_level:
1985             if not (in_preprocessor_directive or looking_for_semicolon):
1986                 if not match(r'\S', current_line) and not file_state.did_inside_namespace_indent_warning():
1987                     file_state.set_did_inside_namespace_indent_warning()
1988                     error(line_number + line_offset, 'whitespace/indent', 4,
1989                           'Code inside a namespace should not be indented.')
1990             if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax.
1991                 in_preprocessor_directive = current_line[-1] == '\\'
1992             else:
1993                 looking_for_semicolon = ((current_line.find(';') == -1) and (current_line.strip()[-1] != '}')) or (current_line[-1] == '\\')
1994         else:
1995             looking_for_semicolon = False; # If we have a brace we may not need a semicolon.
1996         current_indentation_level += current_line.count('{') - current_line.count('}')
1997         if current_indentation_level < 0:
1998             break;
1999
2000
2001 def check_using_std(clean_lines, line_number, file_state, error):
2002     """Looks for 'using std::foo;' statements which should be replaced with 'using namespace std;'.
2003
2004     Args:
2005       clean_lines: A CleansedLines instance containing the file.
2006       line_number: The number of the line to check.
2007       file_state: A _FileState instance which maintains information about
2008                   the state of things in the file.
2009       error: The function to call with any errors found.
2010     """
2011
2012     # This check doesn't apply to C or Objective-C implementation files.
2013     if file_state.is_c_or_objective_c():
2014         return
2015
2016     line = clean_lines.elided[line_number] # Get rid of comments and strings.
2017
2018     using_std_match = match(r'\s*using\s+std::(?P<method_name>\S+)\s*;\s*$', line)
2019     if not using_std_match:
2020         return
2021
2022     method_name = using_std_match.group('method_name')
2023     error(line_number, 'build/using_std', 4,
2024           "Use 'using namespace std;' instead of 'using std::%s;'." % method_name)
2025
2026
2027 def check_max_min_macros(clean_lines, line_number, file_state, error):
2028     """Looks use of MAX() and MIN() macros that should be replaced with std::max() and std::min().
2029
2030     Args:
2031       clean_lines: A CleansedLines instance containing the file.
2032       line_number: The number of the line to check.
2033       file_state: A _FileState instance which maintains information about
2034                   the state of things in the file.
2035       error: The function to call with any errors found.
2036     """
2037
2038     # This check doesn't apply to C or Objective-C implementation files.
2039     if file_state.is_c_or_objective_c():
2040         return
2041
2042     line = clean_lines.elided[line_number] # Get rid of comments and strings.
2043
2044     max_min_macros_search = search(r'\b(?P<max_min_macro>(MAX|MIN))\s*\(', line)
2045     if not max_min_macros_search:
2046         return
2047
2048     max_min_macro = max_min_macros_search.group('max_min_macro')
2049     max_min_macro_lower = max_min_macro.lower()
2050     error(line_number, 'runtime/max_min_macros', 4,
2051           'Use std::%s() or std::%s<type>() instead of the %s() macro.'
2052           % (max_min_macro_lower, max_min_macro_lower, max_min_macro))
2053
2054
2055 def check_switch_indentation(clean_lines, line_number, error):
2056     """Looks for indentation errors inside of switch statements.
2057
2058     Args:
2059       clean_lines: A CleansedLines instance containing the file.
2060       line_number: The number of the line to check.
2061       error: The function to call with any errors found.
2062     """
2063
2064     line = clean_lines.elided[line_number] # Get rid of comments and strings.
2065
2066     switch_match = match(r'(?P<switch_indentation>\s*)switch\s*\(.+\)\s*{\s*$', line)
2067     if not switch_match:
2068         return
2069
2070     switch_indentation = switch_match.group('switch_indentation')
2071     inner_indentation = switch_indentation + ' ' * 4
2072     line_offset = 0
2073     encountered_nested_switch = False
2074
2075     for current_line in clean_lines.elided[line_number + 1:]:
2076         line_offset += 1
2077
2078         # Skip not only empty lines but also those with preprocessor directives.
2079         if current_line.strip() == '' or current_line.startswith('#'):
2080             continue
2081
2082         if match(r'\s*switch\s*\(.+\)\s*{\s*$', current_line):
2083             # Complexity alarm - another switch statement nested inside the one
2084             # that we're currently testing. We'll need to track the extent of
2085             # that inner switch if the upcoming label tests are still supposed
2086             # to work correctly. Let's not do that; instead, we'll finish
2087             # checking this line, and then leave it like that. Assuming the
2088             # indentation is done consistently (even if incorrectly), this will
2089             # still catch all indentation issues in practice.
2090             encountered_nested_switch = True
2091
2092         current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_line>.*)$', current_line);
2093         current_indentation = current_indentation_match.group('indentation')
2094         remaining_line = current_indentation_match.group('remaining_line')
2095
2096         # End the check at the end of the switch statement.
2097         if remaining_line.startswith('}') and current_indentation == switch_indentation:
2098             break
2099         # Case and default branches should not be indented. The regexp also
2100         # catches single-line cases like "default: break;" but does not trigger
2101         # on stuff like "Document::Foo();".
2102         elif match(r'(default|case\s+.*)\s*:([^:].*)?$', remaining_line):
2103             if current_indentation != switch_indentation:
2104                 error(line_number + line_offset, 'whitespace/indent', 4,
2105                       'A case label should not be indented, but line up with its switch statement.')
2106                 # Don't throw an error for multiple badly indented labels,
2107                 # one should be enough to figure out the problem.
2108                 break
2109         # We ignore goto labels at the very beginning of a line.
2110         elif match(r'\w+\s*:\s*$', remaining_line):
2111             continue
2112         # It's not a goto label, so check if it's indented at least as far as
2113         # the switch statement plus one more level of indentation.
2114         elif not current_indentation.startswith(inner_indentation):
2115             error(line_number + line_offset, 'whitespace/indent', 4,
2116                   'Non-label code inside switch statements should be indented.')
2117             # Don't throw an error for multiple badly indented statements,
2118             # one should be enough to figure out the problem.
2119             break
2120
2121         if encountered_nested_switch:
2122             break
2123
2124
2125 def check_braces(clean_lines, line_number, error):
2126     """Looks for misplaced braces (e.g. at the end of line).
2127
2128     Args:
2129       clean_lines: A CleansedLines instance containing the file.
2130       line_number: The number of the line to check.
2131       error: The function to call with any errors found.
2132     """
2133
2134     line = clean_lines.elided[line_number] # Get rid of comments and strings.
2135
2136     if match(r'\s*{\s*$', line):
2137         # We allow an open brace to start a line in the case where someone
2138         # is using braces for function definition or in a block to
2139         # explicitly create a new scope, which is commonly used to control
2140         # the lifetime of stack-allocated variables.  We don't detect this
2141         # perfectly: we just don't complain if the last non-whitespace
2142         # character on the previous non-blank line is ';', ':', '{', '}',
2143         # ')', or ') const' and doesn't begin with 'if|for|while|switch|else'.
2144         # We also allow '#' for #endif and '=' for array initialization.
2145         previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
2146         if ((not search(r'[;:}{)=]\s*$|\)\s*const\s*$', previous_line)
2147              or search(r'\b(if|for|foreach|while|switch|else)\b', previous_line))
2148             and previous_line.find('#') < 0):
2149             error(line_number, 'whitespace/braces', 4,
2150                   'This { should be at the end of the previous line')
2151     elif (search(r'\)\s*(const\s*)?{\s*$', line)
2152           and line.count('(') == line.count(')')
2153           and not search(r'\b(if|for|foreach|while|switch)\b', line)
2154           and not match(r'\s+[A-Z_][A-Z_0-9]+\b', line)):
2155         error(line_number, 'whitespace/braces', 4,
2156               'Place brace on its own line for function definitions.')
2157
2158     if (match(r'\s*}\s*(else\s*({\s*)?)?$', line) and line_number > 1):
2159         # We check if a closed brace has started a line to see if a
2160         # one line control statement was previous.
2161         previous_line = clean_lines.elided[line_number - 2]
2162         last_open_brace = previous_line.rfind('{')
2163         if (last_open_brace != -1 and previous_line.find('}', last_open_brace) == -1
2164             and search(r'\b(if|for|foreach|while|else)\b', previous_line)):
2165             error(line_number, 'whitespace/braces', 4,
2166                   'One line control clauses should not use braces.')
2167
2168     # An else clause should be on the same line as the preceding closing brace.
2169     if match(r'\s*else\s*', line):
2170         previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
2171         if match(r'\s*}\s*$', previous_line):
2172             error(line_number, 'whitespace/newline', 4,
2173                   'An else should appear on the same line as the preceding }')
2174
2175     # Likewise, an else should never have the else clause on the same line
2176     if search(r'\belse [^\s{]', line) and not search(r'\belse if\b', line):
2177         error(line_number, 'whitespace/newline', 4,
2178               'Else clause should never be on same line as else (use 2 lines)')
2179
2180     # In the same way, a do/while should never be on one line
2181     if match(r'\s*do [^\s{]', line):
2182         error(line_number, 'whitespace/newline', 4,
2183               'do/while clauses should not be on a single line')
2184
2185     # Braces shouldn't be followed by a ; unless they're defining a struct
2186     # or initializing an array.
2187     # We can't tell in general, but we can for some common cases.
2188     previous_line_number = line_number
2189     while True:
2190         (previous_line, previous_line_number) = get_previous_non_blank_line(clean_lines, previous_line_number)
2191         if match(r'\s+{.*}\s*;', line) and not previous_line.count(';'):
2192             line = previous_line + line
2193         else:
2194             break
2195     if (search(r'{.*}\s*;', line)
2196         and line.count('{') == line.count('}')
2197         and not search(r'struct|class|enum|\s*=\s*{', line)):
2198         error(line_number, 'readability/braces', 4,
2199               "You don't need a ; after a }")
2200
2201
2202 def check_exit_statement_simplifications(clean_lines, line_number, error):
2203     """Looks for else or else-if statements that should be written as an
2204     if statement when the prior if concludes with a return, break, continue or
2205     goto statement.
2206
2207     Args:
2208       clean_lines: A CleansedLines instance containing the file.
2209       line_number: The number of the line to check.
2210       error: The function to call with any errors found.
2211     """
2212
2213     line = clean_lines.elided[line_number] # Get rid of comments and strings.
2214
2215     else_match = match(r'(?P<else_indentation>\s*)(\}\s*)?else(\s+if\s*\(|(?P<else>\s*(\{\s*)?\Z))', line)
2216     if not else_match:
2217         return
2218
2219     else_indentation = else_match.group('else_indentation')
2220     inner_indentation = else_indentation + ' ' * 4
2221
2222     previous_lines = clean_lines.elided[:line_number]
2223     previous_lines.reverse()
2224     line_offset = 0
2225     encountered_exit_statement = False
2226
2227     for current_line in previous_lines:
2228         line_offset -= 1
2229
2230         # Skip not only empty lines but also those with preprocessor directives
2231         # and goto labels.
2232         if current_line.strip() == '' or current_line.startswith('#') or match(r'\w+\s*:\s*$', current_line):
2233             continue
2234
2235         # Skip lines with closing braces on the original indentation level.
2236         # Even though the styleguide says they should be on the same line as
2237         # the "else if" statement, we also want to check for instances where
2238         # the current code does not comply with the coding style. Thus, ignore
2239         # these lines and proceed to the line before that.
2240         if current_line == else_indentation + '}':
2241             continue
2242
2243         current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_line>.*)$', current_line);
2244         current_indentation = current_indentation_match.group('indentation')
2245         remaining_line = current_indentation_match.group('remaining_line')
2246
2247         # As we're going up the lines, the first real statement to encounter
2248         # has to be an exit statement (return, break, continue or goto) -
2249         # otherwise, this check doesn't apply.
2250         if not encountered_exit_statement:
2251             # We only want to find exit statements if they are on exactly
2252             # the same level of indentation as expected from the code inside
2253             # the block. If the indentation doesn't strictly match then we
2254             # might have a nested if or something, which must be ignored.
2255             if current_indentation != inner_indentation:
2256                 break
2257             if match(r'(return(\W+.*)|(break|continue)\s*;|goto\s*\w+;)$', remaining_line):
2258                 encountered_exit_statement = True
2259                 continue
2260             break
2261
2262         # When code execution reaches this point, we've found an exit statement
2263         # as last statement of the previous block. Now we only need to make
2264         # sure that the block belongs to an "if", then we can throw an error.
2265
2266         # Skip lines with opening braces on the original indentation level,
2267         # similar to the closing braces check above. ("if (condition)\n{")
2268         if current_line == else_indentation + '{':
2269             continue
2270
2271         # Skip everything that's further indented than our "else" or "else if".
2272         if current_indentation.startswith(else_indentation) and current_indentation != else_indentation:
2273             continue
2274
2275         # So we've got a line with same (or less) indentation. Is it an "if"?
2276         # If yes: throw an error. If no: don't throw an error.
2277         # Whatever the outcome, this is the end of our loop.
2278         if match(r'if\s*\(', remaining_line):
2279             if else_match.start('else') != -1:
2280                 error(line_number + line_offset, 'readability/control_flow', 4,
2281                       'An else statement can be removed when the prior "if" '
2282                       'concludes with a return, break, continue or goto statement.')
2283             else:
2284                 error(line_number + line_offset, 'readability/control_flow', 4,
2285                       'An else if statement should be written as an if statement '
2286                       'when the prior "if" concludes with a return, break, '
2287                       'continue or goto statement.')
2288         break
2289
2290
2291 def replaceable_check(operator, macro, line):
2292     """Determine whether a basic CHECK can be replaced with a more specific one.
2293
2294     For example suggest using CHECK_EQ instead of CHECK(a == b) and
2295     similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
2296
2297     Args:
2298       operator: The C++ operator used in the CHECK.
2299       macro: The CHECK or EXPECT macro being called.
2300       line: The current source line.
2301
2302     Returns:
2303       True if the CHECK can be replaced with a more specific one.
2304     """
2305
2306     # This matches decimal and hex integers, strings, and chars (in that order).
2307     match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
2308
2309     # Expression to match two sides of the operator with something that
2310     # looks like a literal, since CHECK(x == iterator) won't compile.
2311     # This means we can't catch all the cases where a more specific
2312     # CHECK is possible, but it's less annoying than dealing with
2313     # extraneous warnings.
2314     match_this = (r'\s*' + macro + r'\((\s*' +
2315                   match_constant + r'\s*' + operator + r'[^<>].*|'
2316                   r'.*[^<>]' + operator + r'\s*' + match_constant +
2317                   r'\s*\))')
2318
2319     # Don't complain about CHECK(x == NULL) or similar because
2320     # CHECK_EQ(x, NULL) won't compile (requires a cast).
2321     # Also, don't complain about more complex boolean expressions
2322     # involving && or || such as CHECK(a == b || c == d).
2323     return match(match_this, line) and not search(r'NULL|&&|\|\|', line)
2324
2325
2326 def check_check(clean_lines, line_number, error):
2327     """Checks the use of CHECK and EXPECT macros.
2328
2329     Args:
2330       clean_lines: A CleansedLines instance containing the file.
2331       line_number: The number of the line to check.
2332       error: The function to call with any errors found.
2333     """
2334
2335     # Decide the set of replacement macros that should be suggested
2336     raw_lines = clean_lines.raw_lines
2337     current_macro = ''
2338     for macro in _CHECK_MACROS:
2339         if raw_lines[line_number].find(macro) >= 0:
2340             current_macro = macro
2341             break
2342     if not current_macro:
2343         # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
2344         return
2345
2346     line = clean_lines.elided[line_number]        # get rid of comments and strings
2347
2348     # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.
2349     for operator in ['==', '!=', '>=', '>', '<=', '<']:
2350         if replaceable_check(operator, current_macro, line):
2351             error(line_number, 'readability/check', 2,
2352                   'Consider using %s instead of %s(a %s b)' % (
2353                       _CHECK_REPLACEMENT[current_macro][operator],
2354                       current_macro, operator))
2355             break
2356
2357
2358 def check_for_comparisons_to_zero(clean_lines, line_number, error):
2359     # Get the line without comments and strings.
2360     line = clean_lines.elided[line_number]
2361
2362     # Include NULL here so that users don't have to convert NULL to 0 first and then get this error.
2363     if search(r'[=!]=\s*(NULL|0|true|false)\W', line) or search(r'\W(NULL|0|true|false)\s*[=!]=', line):
2364         if not search('LIKELY', line) and not search('UNLIKELY', line):
2365             error(line_number, 'readability/comparison_to_zero', 5,
2366                   'Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons.')
2367
2368
2369 def check_for_null(clean_lines, line_number, file_state, error):
2370     # This check doesn't apply to C or Objective-C implementation files.
2371     if file_state.is_c_or_objective_c():
2372         return
2373
2374     line = clean_lines.elided[line_number]
2375
2376     # Don't warn about NULL usage in g_*(). See Bug 32858 and 39372.
2377     if search(r'\bg(_[a-z]+)+\b', line):
2378         return
2379
2380     # Don't warn about NULL usage in gst_*_many(). See Bug 39740
2381     if search(r'\bgst_\w+_many\b', line):
2382         return
2383
2384     # Don't warn about NULL usage in g_str{join,concat}(). See Bug 34834
2385     if search(r'\bg_str(join|concat)\b', line):
2386         return
2387
2388     # Don't warn about NULL usage in gdk_pixbuf_save_to_*{join,concat}(). See Bug 43090.
2389     if search(r'\bgdk_pixbuf_save_to\w+\b', line):
2390         return
2391
2392     # Don't warn about NULL usage in gtk_widget_style_get(). See Bug 51758.
2393     if search(r'\bgtk_widget_style_get\(\w+\b', line):
2394         return
2395
2396     if search(r'\bNULL\b', line):
2397         error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.')
2398         return
2399
2400     line = clean_lines.raw_lines[line_number]
2401     # See if NULL occurs in any comments in the line. If the search for NULL using the raw line
2402     # matches, then do the check with strings collapsed to avoid giving errors for
2403     # NULLs occurring in strings.
2404     if search(r'\bNULL\b', line) and search(r'\bNULL\b', CleansedLines.collapse_strings(line)):
2405         error(line_number, 'readability/null', 4, 'Use 0 or null instead of NULL (even in *comments*).')
2406
2407 def get_line_width(line):
2408     """Determines the width of the line in column positions.
2409
2410     Args:
2411       line: A string, which may be a Unicode string.
2412
2413     Returns:
2414       The width of the line in column positions, accounting for Unicode
2415       combining characters and wide characters.
2416     """
2417     if isinstance(line, unicode):
2418         width = 0
2419         for c in unicodedata.normalize('NFC', line):
2420             if unicodedata.east_asian_width(c) in ('W', 'F'):
2421                 width += 2
2422             elif not unicodedata.combining(c):
2423                 width += 1
2424         return width
2425     return len(line)
2426
2427
2428 def check_style(clean_lines, line_number, file_extension, class_state, file_state, error):
2429     """Checks rules from the 'C++ style rules' section of cppguide.html.
2430
2431     Most of these rules are hard to test (naming, comment style), but we
2432     do what we can.  In particular we check for 4-space indents, line lengths,
2433     tab usage, spaces inside code, etc.
2434
2435     Args:
2436       clean_lines: A CleansedLines instance containing the file.
2437       line_number: The number of the line to check.
2438       file_extension: The extension (without the dot) of the filename.
2439       class_state: A _ClassState instance which maintains information about
2440                    the current stack of nested class declarations being parsed.
2441       file_state: A _FileState instance which maintains information about
2442                   the state of things in the file.
2443       error: The function to call with any errors found.
2444     """
2445
2446     raw_lines = clean_lines.raw_lines
2447     line = raw_lines[line_number]
2448
2449     if line.find('\t') != -1:
2450         error(line_number, 'whitespace/tab', 1,
2451               'Tab found; better to use spaces')
2452
2453     # One or three blank spaces at the beginning of the line is weird; it's
2454     # hard to reconcile that with 4-space indents.
2455     # NOTE: here are the conditions rob pike used for his tests.  Mine aren't
2456     # as sophisticated, but it may be worth becoming so:  RLENGTH==initial_spaces
2457     # if(RLENGTH > 20) complain = 0;
2458     # if(match($0, " +(error|private|public|protected):")) complain = 0;
2459     # if(match(prev, "&& *$")) complain = 0;
2460     # if(match(prev, "\\|\\| *$")) complain = 0;
2461     # if(match(prev, "[\",=><] *$")) complain = 0;
2462     # if(match($0, " <<")) complain = 0;
2463     # if(match(prev, " +for \\(")) complain = 0;
2464     # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
2465     initial_spaces = 0
2466     cleansed_line = clean_lines.elided[line_number]
2467     while initial_spaces < len(line) and line[initial_spaces] == ' ':
2468         initial_spaces += 1
2469     if line and line[-1].isspace():
2470         error(line_number, 'whitespace/end_of_line', 4,
2471               'Line ends in whitespace.  Consider deleting these extra spaces.')
2472     # There are certain situations we allow one space, notably for labels
2473     elif ((initial_spaces >= 1 and initial_spaces <= 3)
2474           and not match(r'\s*\w+\s*:\s*$', cleansed_line)):
2475         error(line_number, 'whitespace/indent', 3,
2476               'Weird number of spaces at line-start.  '
2477               'Are you using a 4-space indent?')
2478     # Labels should always be indented at least one space.
2479     elif not initial_spaces and line[:2] != '//':
2480         label_match = match(r'(?P<label>[^:]+):\s*$', line)
2481
2482         if label_match:
2483             label = label_match.group('label')
2484             # Only throw errors for stuff that is definitely not a goto label,
2485             # because goto labels can in fact occur at the start of the line.
2486             if label in ['public', 'private', 'protected'] or label.find(' ') != -1:
2487                 error(line_number, 'whitespace/labels', 4,
2488                       'Labels should always be indented at least one space.  '
2489                       'If this is a member-initializer list in a constructor, '
2490                       'the colon should be on the line after the definition header.')
2491
2492     if (cleansed_line.count(';') > 1
2493         # for loops are allowed two ;'s (and may run over two lines).
2494         and cleansed_line.find('for') == -1
2495         and (get_previous_non_blank_line(clean_lines, line_number)[0].find('for') == -1
2496              or get_previous_non_blank_line(clean_lines, line_number)[0].find(';') != -1)
2497         # It's ok to have many commands in a switch case that fits in 1 line
2498         and not ((cleansed_line.find('case ') != -1
2499                   or cleansed_line.find('default:') != -1)
2500                  and cleansed_line.find('break;') != -1)
2501         # Also it's ok to have many commands in trivial single-line accessors in class definitions.
2502         and not (match(r'.*\(.*\).*{.*.}', line)
2503                  and class_state.classinfo_stack
2504                  and line.count('{') == line.count('}'))
2505         and not cleansed_line.startswith('#define ')):
2506         error(line_number, 'whitespace/newline', 4,
2507               'More than one command on the same line')
2508
2509     if cleansed_line.strip().endswith('||') or cleansed_line.strip().endswith('&&'):
2510         error(line_number, 'whitespace/operators', 4,
2511               'Boolean expressions that span multiple lines should have their '
2512               'operators on the left side of the line instead of the right side.')
2513
2514     # Some more style checks
2515     check_namespace_indentation(clean_lines, line_number, file_extension, file_state, error)
2516     check_using_std(clean_lines, line_number, file_state, error)
2517     check_max_min_macros(clean_lines, line_number, file_state, error)
2518     check_switch_indentation(clean_lines, line_number, error)
2519     check_braces(clean_lines, line_number, error)
2520     check_exit_statement_simplifications(clean_lines, line_number, error)
2521     check_spacing(file_extension, clean_lines, line_number, error)
2522     check_check(clean_lines, line_number, error)
2523     check_for_comparisons_to_zero(clean_lines, line_number, error)
2524     check_for_null(clean_lines, line_number, file_state, error)
2525
2526
2527 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
2528 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
2529 # Matches the first component of a filename delimited by -s and _s. That is:
2530 #  _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
2531 #  _RE_FIRST_COMPONENT.match('foo.cpp').group(0) == 'foo'
2532 #  _RE_FIRST_COMPONENT.match('foo-bar_baz.cpp').group(0) == 'foo'
2533 #  _RE_FIRST_COMPONENT.match('foo_bar-baz.cpp').group(0) == 'foo'
2534 _RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
2535
2536
2537 def _drop_common_suffixes(filename):
2538     """Drops common suffixes like _test.cpp or -inl.h from filename.
2539
2540     For example:
2541       >>> _drop_common_suffixes('foo/foo-inl.h')
2542       'foo/foo'
2543       >>> _drop_common_suffixes('foo/bar/foo.cpp')
2544       'foo/bar/foo'
2545       >>> _drop_common_suffixes('foo/foo_internal.h')
2546       'foo/foo'
2547       >>> _drop_common_suffixes('foo/foo_unusualinternal.h')
2548       'foo/foo_unusualinternal'
2549
2550     Args:
2551       filename: The input filename.
2552
2553     Returns:
2554       The filename with the common suffix removed.
2555     """
2556     for suffix in ('test.cpp', 'regtest.cpp', 'unittest.cpp',
2557                    'inl.h', 'impl.h', 'internal.h'):
2558         if (filename.endswith(suffix) and len(filename) > len(suffix)
2559             and filename[-len(suffix) - 1] in ('-', '_')):
2560             return filename[:-len(suffix) - 1]
2561     return os.path.splitext(filename)[0]
2562
2563
2564 def _classify_include(filename, include, is_system, include_state):
2565     """Figures out what kind of header 'include' is.
2566
2567     Args:
2568       filename: The current file cpp_style is running over.
2569       include: The path to a #included file.
2570       is_system: True if the #include used <> rather than "".
2571       include_state: An _IncludeState instance in which the headers are inserted.
2572
2573     Returns:
2574       One of the _XXX_HEADER constants.
2575
2576     For example:
2577       >>> _classify_include('foo.cpp', 'config.h', False)
2578       _CONFIG_HEADER
2579       >>> _classify_include('foo.cpp', 'foo.h', False)
2580       _PRIMARY_HEADER
2581       >>> _classify_include('foo.cpp', 'bar.h', False)
2582       _OTHER_HEADER
2583     """
2584
2585     # If it is a system header we know it is classified as _OTHER_HEADER.
2586     if is_system:
2587         return _OTHER_HEADER
2588
2589     # If the include is named config.h then this is WebCore/config.h.
2590     if include == "config.h":
2591         return _CONFIG_HEADER
2592
2593     # There cannot be primary includes in header files themselves. Only an
2594     # include exactly matches the header filename will be is flagged as
2595     # primary, so that it triggers the "don't include yourself" check.
2596     if filename.endswith('.h') and filename != include:
2597         return _OTHER_HEADER;
2598
2599     # Qt's moc files do not follow the naming and ordering rules, so they should be skipped
2600     if include.startswith('moc_') and include.endswith('.cpp'):
2601         return _MOC_HEADER
2602
2603     if include.endswith('.moc'):
2604         return _MOC_HEADER
2605
2606     # If the target file basename starts with the include we're checking
2607     # then we consider it the primary header.
2608     target_base = FileInfo(filename).base_name()
2609     include_base = FileInfo(include).base_name()
2610
2611     # If we haven't encountered a primary header, then be lenient in checking.
2612     if not include_state.visited_primary_section() and target_base.find(include_base) != -1:
2613         return _PRIMARY_HEADER
2614     # If we already encountered a primary header, perform a strict comparison.
2615     # In case the two filename bases are the same then the above lenient check
2616     # probably was a false positive.
2617     elif include_state.visited_primary_section() and target_base == include_base:
2618         if include == "ResourceHandleWin.h":
2619             # FIXME: Thus far, we've only seen one example of these, but if we
2620             # start to see more, please consider generalizing this check
2621             # somehow.
2622             return _OTHER_HEADER
2623         return _PRIMARY_HEADER
2624
2625     return _OTHER_HEADER
2626
2627
2628 def _does_primary_header_exist(filename):
2629     """Return a primary header file name for a file, or empty string
2630     if the file is not source file or primary header does not exist.
2631     """
2632     fileinfo = FileInfo(filename)
2633     if not fileinfo.is_source():
2634         return False
2635     primary_header = fileinfo.no_extension() + ".h"
2636     return os.path.isfile(primary_header)
2637
2638
2639 def check_include_line(filename, file_extension, clean_lines, line_number, include_state, error):
2640     """Check rules that are applicable to #include lines.
2641
2642     Strings on #include lines are NOT removed from elided line, to make
2643     certain tasks easier. However, to prevent false positives, checks
2644     applicable to #include lines in CheckLanguage must be put here.
2645
2646     Args:
2647       filename: The name of the current file.
2648       file_extension: The current file extension, without the leading dot.
2649       clean_lines: A CleansedLines instance containing the file.
2650       line_number: The number of the line to check.
2651       include_state: An _IncludeState instance in which the headers are inserted.
2652       error: The function to call with any errors found.
2653     """
2654     # FIXME: For readability or as a possible optimization, consider
2655     #        exiting early here by checking whether the "build/include"
2656     #        category should be checked for the given filename.  This
2657     #        may involve having the error handler classes expose a
2658     #        should_check() method, in addition to the usual __call__
2659     #        method.
2660     line = clean_lines.lines[line_number]
2661
2662     matched = _RE_PATTERN_INCLUDE.search(line)
2663     if not matched:
2664         return
2665
2666     include = matched.group(2)
2667     is_system = (matched.group(1) == '<')
2668
2669     # Look for any of the stream classes that are part of standard C++.
2670     if match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
2671         error(line_number, 'readability/streams', 3,
2672               'Streams are highly discouraged.')
2673
2674     # Look for specific includes to fix.
2675     if include.startswith('wtf/') and not is_system:
2676         error(line_number, 'build/include', 4,
2677               'wtf includes should be <wtf/file.h> instead of "wtf/file.h".')
2678
2679     duplicate_header = include in include_state
2680     if duplicate_header:
2681         error(line_number, 'build/include', 4,
2682               '"%s" already included at %s:%s' %
2683               (include, filename, include_state[include]))
2684     else:
2685         include_state[include] = line_number
2686
2687     header_type = _classify_include(filename, include, is_system, include_state)
2688     primary_header_exists = _does_primary_header_exist(filename)
2689     include_state.header_types[line_number] = header_type
2690
2691     # Only proceed if this isn't a duplicate header.
2692     if duplicate_header:
2693         return
2694
2695     # We want to ensure that headers appear in the right order:
2696     # 1) for implementation files: config.h, primary header, blank line, alphabetically sorted
2697     # 2) for header files: alphabetically sorted
2698     # The include_state object keeps track of the last type seen
2699     # and complains if the header types are out of order or missing.
2700     error_message = include_state.check_next_include_order(header_type,
2701                                                            file_extension == "h",
2702                                                            primary_header_exists)
2703
2704     # Check to make sure we have a blank line after primary header.
2705     if not error_message and header_type == _PRIMARY_HEADER:
2706          next_line = clean_lines.raw_lines[line_number + 1]
2707          if not is_blank_line(next_line):
2708             error(line_number, 'build/include_order', 4,
2709                   'You should add a blank line after implementation file\'s own header.')
2710
2711     # Check to make sure all headers besides config.h and the primary header are
2712     # alphabetically sorted. Skip Qt's moc files.
2713     if not error_message and header_type == _OTHER_HEADER:
2714          previous_line_number = line_number - 1;
2715          previous_line = clean_lines.lines[previous_line_number]
2716          previous_match = _RE_PATTERN_INCLUDE.search(previous_line)
2717          while (not previous_match and previous_line_number > 0
2718                 and not search(r'\A(#if|#ifdef|#ifndef|#else|#elif|#endif)', previous_line)):
2719             previous_line_number -= 1;
2720             previous_line = clean_lines.lines[previous_line_number]
2721             previous_match = _RE_PATTERN_INCLUDE.search(previous_line)
2722          if previous_match:
2723             previous_header_type = include_state.header_types[previous_line_number]
2724             if previous_header_type == _OTHER_HEADER and previous_line.strip() > line.strip():
2725                 error(line_number, 'build/include_order', 4,
2726                       'Alphabetical sorting problem.')
2727
2728     if error_message:
2729         if file_extension == 'h':
2730             error(line_number, 'build/include_order', 4,
2731                   '%s Should be: alphabetically sorted.' %
2732                   error_message)
2733         else:
2734             error(line_number, 'build/include_order', 4,
2735                   '%s Should be: config.h, primary header, blank line, and then alphabetically sorted.' %
2736                   error_message)
2737
2738
2739 def check_language(filename, clean_lines, line_number, file_extension, include_state,
2740                    file_state, error):
2741     """Checks rules from the 'C++ language rules' section of cppguide.html.
2742
2743     Some of these rules are hard to test (function overloading, using
2744     uint32 inappropriately), but we do the best we can.
2745
2746     Args:
2747       filename: The name of the current file.
2748       clean_lines: A CleansedLines instance containing the file.
2749       line_number: The number of the line to check.
2750       file_extension: The extension (without the dot) of the filename.
2751       include_state: An _IncludeState instance in which the headers are inserted.
2752       file_state: A _FileState instance which maintains information about
2753                   the state of things in the file.
2754       error: The function to call with any errors found.
2755     """
2756     # If the line is empty or consists of entirely a comment, no need to
2757     # check it.
2758     line = clean_lines.elided[line_number]
2759     if not line:
2760         return
2761
2762     matched = _RE_PATTERN_INCLUDE.search(line)
2763     if matched:
2764         check_include_line(filename, file_extension, clean_lines, line_number, include_state, error)
2765         return
2766
2767     # FIXME: figure out if they're using default arguments in fn proto.
2768
2769     # Check to see if they're using an conversion function cast.
2770     # I just try to capture the most common basic types, though there are more.
2771     # Parameterless conversion functions, such as bool(), are allowed as they are
2772     # probably a member operator declaration or default constructor.
2773     matched = search(
2774         r'\b(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
2775     if matched:
2776         # gMock methods are defined using some variant of MOCK_METHODx(name, type)
2777         # where type may be float(), int(string), etc.  Without context they are
2778         # virtually indistinguishable from int(x) casts.
2779         if not match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line):
2780             error(line_number, 'readability/casting', 4,
2781                   'Using deprecated casting style.  '
2782                   'Use static_cast<%s>(...) instead' %
2783                   matched.group(1))
2784
2785     check_c_style_cast(line_number, line, clean_lines.raw_lines[line_number],
2786                        'static_cast',
2787                        r'\((int|float|double|bool|char|u?int(16|32|64))\)',
2788                        error)
2789     # This doesn't catch all cases.  Consider (const char * const)"hello".
2790     check_c_style_cast(line_number, line, clean_lines.raw_lines[line_number],
2791                        'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
2792
2793     # In addition, we look for people taking the address of a cast.  This
2794     # is dangerous -- casts can assign to temporaries, so the pointer doesn't
2795     # point where you think.
2796     if search(
2797         r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
2798         error(line_number, 'runtime/casting', 4,
2799               ('Are you taking an address of a cast?  '
2800                'This is dangerous: could be a temp var.  '
2801                'Take the address before doing the cast, rather than after'))
2802
2803     # Check for people declaring static/global STL strings at the top level.
2804     # This is dangerous because the C++ language does not guarantee that
2805     # globals with constructors are initialized before the first access.
2806     matched = match(
2807         r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
2808         line)
2809     # Make sure it's not a function.
2810     # Function template specialization looks like: "string foo<Type>(...".
2811     # Class template definitions look like: "string Foo<Type>::Method(...".
2812     if matched and not match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)',
2813                              matched.group(3)):
2814         error(line_number, 'runtime/string', 4,
2815               'For a static/global string constant, use a C style string instead: '
2816               '"%schar %s[]".' %
2817               (matched.group(1), matched.group(2)))
2818
2819     # Check that we're not using RTTI outside of testing code.
2820     if search(r'\bdynamic_cast<', line):
2821         error(line_number, 'runtime/rtti', 5,
2822               'Do not use dynamic_cast<>.  If you need to cast within a class '
2823               "hierarchy, use static_cast<> to upcast.  Google doesn't support "
2824               'RTTI.')
2825
2826     if search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
2827         error(line_number, 'runtime/init', 4,
2828               'You seem to be initializing a member variable with itself.')
2829
2830     if file_extension == 'h':
2831         # FIXME: check that 1-arg constructors are explicit.
2832         #        How to tell it's a constructor?
2833         #        (handled in check_for_non_standard_constructs for now)
2834         pass
2835
2836     # Check if people are using the verboten C basic types.  The only exception
2837     # we regularly allow is "unsigned short port" for port.
2838     if search(r'\bshort port\b', line):
2839         if not search(r'\bunsigned short port\b', line):
2840             error(line_number, 'runtime/int', 4,
2841                   'Use "unsigned short" for ports, not "short"')
2842
2843     # When snprintf is used, the second argument shouldn't be a literal.
2844     matched = search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
2845     if matched:
2846         error(line_number, 'runtime/printf', 3,
2847               'If you can, use sizeof(%s) instead of %s as the 2nd arg '
2848               'to snprintf.' % (matched.group(1), matched.group(2)))
2849
2850     # Check if some verboten C functions are being used.
2851     if search(r'\bsprintf\b', line):
2852         error(line_number, 'runtime/printf', 5,
2853               'Never use sprintf.  Use snprintf instead.')
2854     matched = search(r'\b(strcpy|strcat)\b', line)
2855     if matched:
2856         error(line_number, 'runtime/printf', 4,
2857               'Almost always, snprintf is better than %s' % matched.group(1))
2858
2859     if search(r'\bsscanf\b', line):
2860         error(line_number, 'runtime/printf', 1,
2861               'sscanf can be ok, but is slow and can overflow buffers.')
2862
2863     # Check for suspicious usage of "if" like
2864     # } if (a == b) {
2865     if search(r'\}\s*if\s*\(', line):
2866         error(line_number, 'readability/braces', 4,
2867               'Did you mean "else if"? If not, start a new line for "if".')
2868
2869     # Check for potential format string bugs like printf(foo).
2870     # We constrain the pattern not to pick things like DocidForPrintf(foo).
2871     # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
2872     matched = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I)
2873     if matched:
2874         error(line_number, 'runtime/printf', 4,
2875               'Potential format string bug. Do %s("%%s", %s) instead.'
2876               % (matched.group(1), matched.group(2)))
2877
2878     # Check for potential memset bugs like memset(buf, sizeof(buf), 0).
2879     matched = search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
2880     if matched and not match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", matched.group(2)):
2881         error(line_number, 'runtime/memset', 4,
2882               'Did you mean "memset(%s, 0, %s)"?'
2883               % (matched.group(1), matched.group(2)))
2884
2885     # Detect variable-length arrays.
2886     matched = match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
2887     if (matched and matched.group(2) != 'return' and matched.group(2) != 'delete' and
2888         matched.group(3).find(']') == -1):
2889         # Split the size using space and arithmetic operators as delimiters.
2890         # If any of the resulting tokens are not compile time constants then
2891         # report the error.
2892         tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', matched.group(3))
2893         is_const = True
2894         skip_next = False
2895         for tok in tokens:
2896             if skip_next:
2897                 skip_next = False
2898                 continue
2899
2900             if search(r'sizeof\(.+\)', tok):
2901                 continue
2902             if search(r'arraysize\(\w+\)', tok):
2903                 continue
2904
2905             tok = tok.lstrip('(')
2906             tok = tok.rstrip(')')
2907             if not tok:
2908                 continue
2909             if match(r'\d+', tok):
2910                 continue
2911             if match(r'0[xX][0-9a-fA-F]+', tok):
2912                 continue
2913             if match(r'k[A-Z0-9]\w*', tok):
2914                 continue
2915             if match(r'(.+::)?k[A-Z0-9]\w*', tok):
2916                 continue
2917             if match(r'(.+::)?[A-Z][A-Z0-9_]*', tok):
2918                 continue
2919             # A catch all for tricky sizeof cases, including 'sizeof expression',
2920             # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
2921             # requires skipping the next token becasue we split on ' ' and '*'.
2922             if tok.startswith('sizeof'):
2923                 skip_next = True
2924                 continue
2925             is_const = False
2926             break
2927         if not is_const:
2928             error(line_number, 'runtime/arrays', 1,
2929                   'Do not use variable-length arrays.  Use an appropriately named '
2930                   "('k' followed by CamelCase) compile-time constant for the size.")
2931
2932     # Check for use of unnamed namespaces in header files.  Registration
2933     # macros are typically OK, so we allow use of "namespace {" on lines
2934     # that end with backslashes.
2935     if (file_extension == 'h'
2936         and search(r'\bnamespace\s*{', line)
2937         and line[-1] != '\\'):
2938         error(line_number, 'build/namespaces', 4,
2939               'Do not use unnamed namespaces in header files.  See '
2940               'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
2941               ' for more information.')
2942
2943     # Check for plain bitfields declared without either "singed" or "unsigned".
2944     # Most compilers treat such bitfields as signed, but there are still compilers like
2945     # RVCT 4.0 that use unsigned by default.
2946     matched = re.match(r'\s*((const|mutable)\s+)?(char|(short(\s+int)?)|int|long(\s+(long|int))?)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\d+\s*;', line)
2947     if matched:
2948         error(line_number, 'runtime/bitfields', 5,
2949               'Please declare integral type bitfields with either signed or unsigned.')
2950
2951     check_identifier_name_in_declaration(filename, line_number, line, file_state, error)
2952
2953
2954 def check_identifier_name_in_declaration(filename, line_number, line, file_state, error):
2955     """Checks if identifier names contain any underscores.
2956
2957     As identifiers in libraries we are using have a bunch of
2958     underscores, we only warn about the declarations of identifiers
2959     and don't check use of identifiers.
2960
2961     Args:
2962       filename: The name of the current file.
2963       line_number: The number of the line to check.
2964       line: The line of code to check.
2965       file_state: A _FileState instance which maintains information about
2966                   the state of things in the file.
2967       error: The function to call with any errors found.
2968     """
2969     # We don't check a return statement.
2970     if match(r'\s*(return|delete)\b', line):
2971         return
2972
2973     # Basically, a declaration is a type name followed by whitespaces
2974     # followed by an identifier. The type name can be complicated
2975     # due to type adjectives and templates. We remove them first to
2976     # simplify the process to find declarations of identifiers.
2977
2978     # Convert "long long", "long double", and "long long int" to
2979     # simple types, but don't remove simple "long".
2980     line = sub(r'long (long )?(?=long|double|int)', '', line)
2981     # Convert unsigned/signed types to simple types, too.
2982     line = sub(r'(unsigned|signed) (?=char|short|int|long)', '', line)
2983     line = sub(r'\b(inline|using|static|const|volatile|auto|register|extern|typedef|restrict|struct|class|virtual)(?=\W)', '', line)
2984
2985     # Remove "new" and "new (expr)" to simplify, too.
2986     line = sub(r'new\s*(\([^)]*\))?', '', line)
2987
2988     # Remove all template parameters by removing matching < and >.
2989     # Loop until no templates are removed to remove nested templates.
2990     while True:
2991         line, number_of_replacements = subn(r'<([\w\s:]|::)+\s*[*&]*\s*>', '', line)
2992         if not number_of_replacements:
2993             break
2994
2995     # Declarations of local variables can be in condition expressions
2996     # of control flow statements (e.g., "if (RenderObject* p = o->parent())").
2997     # We remove the keywords and the first parenthesis.
2998     #
2999     # Declarations in "while", "if", and "switch" are different from
3000     # other declarations in two aspects:
3001     #
3002     # - There can be only one declaration between the parentheses.
3003     #   (i.e., you cannot write "if (int i = 0, j = 1) {}")
3004     # - The variable must be initialized.
3005     #   (i.e., you cannot write "if (int i) {}")
3006     #
3007     # and we will need different treatments for them.
3008     line = sub(r'^\s*for\s*\(', '', line)
3009     line, control_statement = subn(r'^\s*(while|else if|if|switch)\s*\(', '', line)
3010
3011     # Detect variable and functions.
3012     type_regexp = r'\w([\w]|\s*[*&]\s*|::)+'
3013     identifier_regexp = r'(?P<identifier>[\w:]+)'
3014     maybe_bitfield_regexp = r'(:\s*\d+\s*)?'
3015     character_after_identifier_regexp = r'(?P<character_after_identifier>[[;()=,])(?!=)'
3016     declaration_without_type_regexp = r'\s*' + identifier_regexp + r'\s*' + maybe_bitfield_regexp + character_after_identifier_regexp
3017     declaration_with_type_regexp = r'\s*' + type_regexp + r'\s' + declaration_without_type_regexp
3018     is_function_arguments = False
3019     number_of_identifiers = 0
3020     while True:
3021         # If we are seeing the first identifier or arguments of a
3022         # function, there should be a type name before an identifier.
3023         if not number_of_identifiers or is_function_arguments:
3024             declaration_regexp = declaration_with_type_regexp
3025         else:
3026             declaration_regexp = declaration_without_type_regexp
3027
3028         matched = match(declaration_regexp, line)
3029         if not matched:
3030             return
3031         identifier = matched.group('identifier')
3032         character_after_identifier = matched.group('character_after_identifier')
3033
3034         # If we removed a non-for-control statement, the character after
3035         # the identifier should be '='. With this rule, we can avoid
3036         # warning for cases like "if (val & INT_MAX) {".
3037         if control_statement and character_after_identifier != '=':
3038             return
3039
3040         is_function_arguments = is_function_arguments or character_after_identifier == '('
3041
3042         # Remove "m_" and "s_" to allow them.
3043         modified_identifier = sub(r'(^|(?<=::))[ms]_', '', identifier)
3044         if not file_state.is_objective_c() and modified_identifier.find('_') >= 0:
3045             # Various exceptions to the rule: JavaScript op codes functions, const_iterator.
3046             if (not (filename.find('JavaScriptCore') >= 0 and modified_identifier.find('op_') >= 0)
3047                 and not modified_identifier.startswith('tst_')
3048                 and not modified_identifier.startswith('webkit_dom_object_')
3049                 and not modified_identifier.startswith('NPN_')
3050                 and not modified_identifier.startswith('NPP_')
3051                 and not modified_identifier.startswith('NP_')
3052                 and not modified_identifier.startswith('qt_')
3053                 and not modified_identifier.startswith('cairo_')
3054                 and not modified_identifier.find('::qt_') >= 0
3055                 and not modified_identifier == "const_iterator"
3056                 and not modified_identifier == "vm_throw"):
3057                 error(line_number, 'readability/naming', 4, identifier + " is incorrectly named. Don't use underscores in your identifier names.")
3058
3059         # Check for variables named 'l', these are too easy to confuse with '1' in some fonts
3060         if modified_identifier == 'l':
3061             error(line_number, 'readability/naming', 4, identifier + " is incorrectly named. Don't use the single letter 'l' as an identifier name.")
3062
3063         # There can be only one declaration in non-for-control statements.
3064         if control_statement:
3065             return
3066         # We should continue checking if this is a function
3067         # declaration because we need to check its arguments.
3068         # Also, we need to check multiple declarations.
3069         if character_after_identifier != '(' and character_after_identifier != ',':
3070             return
3071
3072         number_of_identifiers += 1
3073         line = line[matched.end():]
3074
3075 def check_c_style_cast(line_number, line, raw_line, cast_type, pattern,
3076                        error):
3077     """Checks for a C-style cast by looking for the pattern.
3078
3079     This also handles sizeof(type) warnings, due to similarity of content.
3080
3081     Args:
3082       line_number: The number of the line to check.
3083       line: The line of code to check.
3084       raw_line: The raw line of code to check, with comments.
3085       cast_type: The string for the C++ cast to recommend.  This is either
3086                  reinterpret_cast or static_cast, depending.
3087       pattern: The regular expression used to find C-style casts.
3088       error: The function to call with any errors found.
3089     """
3090     matched = search(pattern, line)
3091     if not matched:
3092         return
3093
3094     # e.g., sizeof(int)
3095     sizeof_match = match(r'.*sizeof\s*$', line[0:matched.start(1) - 1])
3096     if sizeof_match:
3097         error(line_number, 'runtime/sizeof', 1,
3098               'Using sizeof(type).  Use sizeof(varname) instead if possible')
3099         return
3100
3101     remainder = line[matched.end(0):]
3102
3103     # The close paren is for function pointers as arguments to a function.
3104     # eg, void foo(void (*bar)(int));
3105     # The semicolon check is a more basic function check; also possibly a
3106     # function pointer typedef.
3107     # eg, void foo(int); or void foo(int) const;
3108     # The equals check is for function pointer assignment.
3109     # eg, void *(*foo)(int) = ...
3110     #
3111     # Right now, this will only catch cases where there's a single argument, and
3112     # it's unnamed.  It should probably be expanded to check for multiple
3113     # arguments with some unnamed.
3114     function_match = match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder)
3115     if function_match:
3116         if (not function_match.group(3)
3117             or function_match.group(3) == ';'
3118             or raw_line.find('/*') < 0):
3119             error(line_number, 'readability/function', 3,
3120                   'All parameters should be named in a function')
3121         return
3122
3123     # At this point, all that should be left is actual casts.
3124     error(line_number, 'readability/casting', 4,
3125           'Using C-style cast.  Use %s<%s>(...) instead' %
3126           (cast_type, matched.group(1)))
3127
3128
3129 _HEADERS_CONTAINING_TEMPLATES = (
3130     ('<deque>', ('deque',)),
3131     ('<functional>', ('unary_function', 'binary_function',
3132                       'plus', 'minus', 'multiplies', 'divides', 'modulus',