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