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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py

Issue 2014063002: Run format-webkit on webkitpy code (without string conversion). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 # 2 #
3 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved. 3 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved.
4 # Copyright (C) 2009 Torch Mobile Inc. 4 # Copyright (C) 2009 Torch Mobile Inc.
5 # Copyright (C) 2009 Apple Inc. All rights reserved. 5 # Copyright (C) 2009 Apple Inc. All rights reserved.
6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) 6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
7 # 7 #
8 # Redistribution and use in source and binary forms, with or without 8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are 9 # modification, are permitted provided that the following conditions are
10 # met: 10 # met:
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 if self.is_declaration: 561 if self.is_declaration:
562 characters_after_parameters = SingleLineView( 562 characters_after_parameters = SingleLineView(
563 clean_lines.elided, parameter_end_position, body_start_position) .single_line 563 clean_lines.elided, parameter_end_position, body_start_position) .single_line
564 self.is_pure = bool(match(r'\s*=\s*0\s*', characters_after_parameter s)) 564 self.is_pure = bool(match(r'\s*=\s*0\s*', characters_after_parameter s))
565 self._clean_lines = clean_lines 565 self._clean_lines = clean_lines
566 self._parameter_list = None 566 self._parameter_list = None
567 567
568 def modifiers_and_return_type(self): 568 def modifiers_and_return_type(self):
569 """Returns the modifiers and the return type.""" 569 """Returns the modifiers and the return type."""
570 # Go backwards from where the function name is until we encounter one of several things: 570 # Go backwards from where the function name is until we encounter one of several things:
571 # ';' or '{' or '}' or 'private:', etc. or '#' or return Position(0, 0 ) 571 # ';' or '{' or '}' or 'private:', etc. or '#' or return Position(0, 0)
572 elided = self._clean_lines.elided 572 elided = self._clean_lines.elided
573 start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected): )|(#.*)', 573 start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected): )|(#.*)',
574 elided, self.parameter_start_position, Position(0, 0)) 574 elided, self.parameter_start_position, Position(0, 0))
575 return SingleLineView(elided, start_modifiers, self.function_name_start_ position).single_line.strip() 575 return SingleLineView(elided, start_modifiers, self.function_name_start_ position).single_line.strip()
576 576
577 def parameter_list(self): 577 def parameter_list(self):
578 if not self._parameter_list: 578 if not self._parameter_list:
579 # Store the final result as a tuple since that is immutable. 579 # Store the final result as a tuple since that is immutable.
580 self._parameter_list = tuple(parameter_list(self._clean_lines.elided , 580 self._parameter_list = tuple(parameter_list(self._clean_lines.elided ,
581 self.parameter_start_pos ition, self.parameter_end_position)) 581 self.parameter_start_pos ition, self.parameter_end_position))
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 brace_depth = classinfo.brace_depth 1449 brace_depth = classinfo.brace_depth
1450 brace_depth = brace_depth + line.count('{') - line.count('}') 1450 brace_depth = brace_depth + line.count('{') - line.count('}')
1451 if brace_depth <= 0: 1451 if brace_depth <= 0:
1452 classinfo = classinfo_stack.pop() 1452 classinfo = classinfo_stack.pop()
1453 # Try to detect missing virtual destructor declarations. 1453 # Try to detect missing virtual destructor declarations.
1454 # For now, only warn if a non-derived class with virtual methods lacks 1454 # For now, only warn if a non-derived class with virtual methods lacks
1455 # a virtual destructor. This is to make it less likely that people will 1455 # a virtual destructor. This is to make it less likely that people will
1456 # declare derived virtual destructors without declaring the base 1456 # declare derived virtual destructors without declaring the base
1457 # destructor virtual. 1457 # destructor virtual.
1458 if ((classinfo.virtual_method_line_number is not None) 1458 if ((classinfo.virtual_method_line_number is not None)
1459 and (not classinfo.has_virtual_destructor) 1459 and (not classinfo.has_virtual_destructor)
1460 and (not classinfo.is_derived)): # Only warn for base classes 1460 and (not classinfo.is_derived)): # Only warn for base classes
1461 error(classinfo.line_number, 'runtime/virtual', 4, 1461 error(classinfo.line_number, 'runtime/virtual', 4,
1462 'The class %s probably needs a virtual destructor due to ' 1462 'The class %s probably needs a virtual destructor due to '
1463 'having virtual method(s), one declared at line %d.' 1463 'having virtual method(s), one declared at line %d.'
1464 % (classinfo.name, classinfo.virtual_method_line_number)) 1464 % (classinfo.name, classinfo.virtual_method_line_number))
1465 # Look for mixed bool and unsigned bitfields. 1465 # Look for mixed bool and unsigned bitfields.
1466 if (classinfo.bool_bitfields and classinfo.unsigned_bitfields): 1466 if (classinfo.bool_bitfields and classinfo.unsigned_bitfields):
1467 bool_list = ', '.join(classinfo.bool_bitfields) 1467 bool_list = ', '.join(classinfo.bool_bitfields)
1468 unsigned_list = ', '.join(classinfo.unsigned_bitfields) 1468 unsigned_list = ', '.join(classinfo.unsigned_bitfields)
1469 error(classinfo.line_number, 'runtime/bitfields', 5, 1469 error(classinfo.line_number, 'runtime/bitfields', 5,
1470 'The class %s contains mixed unsigned and bool bitfields, ' 1470 'The class %s contains mixed unsigned and bool bitfields, '
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 # function argument when the char before the whitespace is legal in 1531 # function argument when the char before the whitespace is legal in
1532 # a function name (alnum + _) and we're not starting a macro. Also ignore 1532 # a function name (alnum + _) and we're not starting a macro. Also ignore
1533 # pointers and references to arrays and functions coz they're too tricky: 1533 # pointers and references to arrays and functions coz they're too tricky:
1534 # we use a very simple way to recognize these: 1534 # we use a very simple way to recognize these:
1535 # " (something)(maybe-something)" or 1535 # " (something)(maybe-something)" or
1536 # " (something)(maybe-something," or 1536 # " (something)(maybe-something," or
1537 # " (something)[something]" 1537 # " (something)[something]"
1538 # Note that we assume the contents of [] to be short enough that 1538 # Note that we assume the contents of [] to be short enough that
1539 # they'll never need to wrap. 1539 # they'll never need to wrap.
1540 if ( # Ignore control structures. 1540 if ( # Ignore control structures.
1541 not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', funct ion_call) 1541 not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', f unction_call)
1542 # Ignore pointers/references to functions. 1542 # Ignore pointers/references to functions.
1543 and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call) 1543 and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call)
1544 # Ignore pointers/references to arrays. 1544 # Ignore pointers/references to arrays.
1545 and not search(r' \([^)]+\)\[[^\]]+\]', function_call)): 1545 and not search(r' \([^)]+\)\[[^\]]+\]', function_call)):
1546 if search(r'\w\s*\([ \t](?!\s*\\$)', function_call): # a ( used for a fn call 1546 if search(r'\w\s*\([ \t](?!\s*\\$)', function_call): # a ( used for a fn call
1547 error(line_number, 'whitespace/parens', 4, 1547 error(line_number, 'whitespace/parens', 4,
1548 'Extra space after ( in function call') 1548 'Extra space after ( in function call')
1549 elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call): 1549 elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call):
1550 error(line_number, 'whitespace/parens', 2, 1550 error(line_number, 'whitespace/parens', 2,
1551 'Extra space after (') 1551 'Extra space after (')
1552 if (search(r'\w\s+\(', function_call) 1552 if (search(r'\w\s+\(', function_call)
1553 and not match(r'\s*(#|typedef)', function_call)): 1553 and not match(r'\s*(#|typedef)', function_call)):
1554 error(line_number, 'whitespace/parens', 4, 1554 error(line_number, 'whitespace/parens', 4,
1555 'Extra space before ( in function call') 1555 'Extra space before ( in function call')
1556 # If the ) is followed only by a newline or a { + newline, assume it's 1556 # If the ) is followed only by a newline or a { + newline, assume it's
1557 # part of a control statement (if/while/etc), and don't complain 1557 # part of a control statement (if/while/etc), and don't complain
1558 if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call): 1558 if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call):
1559 error(line_number, 'whitespace/parens', 2, 1559 error(line_number, 'whitespace/parens', 2,
1560 'Extra space before )') 1560 'Extra space before )')
1561 1561
1562 1562
1563 def is_blank_line(line): 1563 def is_blank_line(line):
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 clean_lines: A CleansedLines instance containing the file. 1754 clean_lines: A CleansedLines instance containing the file.
1755 line_number: The number of the line to check. 1755 line_number: The number of the line to check.
1756 function_state: Current function name and lines in body so far. 1756 function_state: Current function name and lines in body so far.
1757 error: The function to call with any errors found. 1757 error: The function to call with any errors found.
1758 """ 1758 """
1759 if line_number != function_state.body_start_position.row: 1759 if line_number != function_state.body_start_position.row:
1760 return 1760 return
1761 1761
1762 modifiers_and_return_type = function_state.modifiers_and_return_type() 1762 modifiers_and_return_type = function_state.modifiers_and_return_type()
1763 if filename.find('/chromium/') != -1 and search(r'\bWEBKIT_EXPORT\b', modifi ers_and_return_type): 1763 if filename.find('/chromium/') != -1 and search(r'\bWEBKIT_EXPORT\b', modifi ers_and_return_type):
1764 if filename.find('/chromium/public/') == -1 and filename.find('/chromium /tests/') == -1 and filename.find('chromium/platform') == -1: 1764 if filename.find('/chromium/public/') == -1 and filename.find('/chromium /tests/') == - \
1765 1 and filename.find('chromium/platform') == -1:
1765 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1766 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
1766 'WEBKIT_EXPORT should only appear in the chromium public (or t ests) directory.') 1767 'WEBKIT_EXPORT should only appear in the chromium public (or t ests) directory.')
1767 elif not file_extension == "h": 1768 elif not file_extension == "h":
1768 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1769 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
1769 'WEBKIT_EXPORT should only be used in header files.') 1770 'WEBKIT_EXPORT should only be used in header files.')
1770 elif not function_state.is_declaration or search(r'\binline\b', modifier s_and_return_type): 1771 elif not function_state.is_declaration or search(r'\binline\b', modifier s_and_return_type):
1771 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1772 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
1772 'WEBKIT_EXPORT should not be used on a function with a body.') 1773 'WEBKIT_EXPORT should not be used on a function with a body.')
1773 elif function_state.is_pure: 1774 elif function_state.is_pure:
1774 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1775 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 # blank lines at the end of a function (ie, right before a line like '}'). 1872 # blank lines at the end of a function (ie, right before a line like '}').
1872 if is_blank_line(line): 1873 if is_blank_line(line):
1873 elided = clean_lines.elided 1874 elided = clean_lines.elided
1874 previous_line = elided[line_number - 1] 1875 previous_line = elided[line_number - 1]
1875 previous_brace = previous_line.rfind('{') 1876 previous_brace = previous_line.rfind('{')
1876 # FIXME: Don't complain if line before blank line, and line after, 1877 # FIXME: Don't complain if line before blank line, and line after,
1877 # both start with alnums and are indented the same amount. 1878 # both start with alnums and are indented the same amount.
1878 # This ignores whitespace at the start of a namespace block 1879 # This ignores whitespace at the start of a namespace block
1879 # because those are not usually indented. 1880 # because those are not usually indented.
1880 if (previous_brace != -1 and previous_line[previous_brace:].find('}') == -1 1881 if (previous_brace != -1 and previous_line[previous_brace:].find('}') == -1
1881 and previous_line[:previous_brace].find('namespace') == -1): 1882 and previous_line[:previous_brace].find('namespace') == -1):
1882 # OK, we have a blank line at the start of a code block. Before we 1883 # OK, we have a blank line at the start of a code block. Before we
1883 # complain, we check if it is an exception to the rule: The previous 1884 # complain, we check if it is an exception to the rule: The previous
1884 # non-empty line has the parameters of a function header that are in dented 1885 # non-empty line has the parameters of a function header that are in dented
1885 # 4 spaces (because they did not fit in a 80 column line when placed on 1886 # 4 spaces (because they did not fit in a 80 column line when placed on
1886 # the same line as the function name). We also check for the case w here 1887 # the same line as the function name). We also check for the case w here
1887 # the previous line is indented 6 spaces, which may happen when the 1888 # the previous line is indented 6 spaces, which may happen when the
1888 # initializers of a constructor do not fit into a 80 column line. 1889 # initializers of a constructor do not fit into a 80 column line.
1889 exception = False 1890 exception = False
1890 if match(r' {6}\w', previous_line): # Initializer list? 1891 if match(r' {6}\w', previous_line): # Initializer list?
1891 # We are looking for the opening column of initializer list, whi ch 1892 # We are looking for the opening column of initializer list, whi ch
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 if not current_indentation_level: 2169 if not current_indentation_level:
2169 if not (in_preprocessor_directive or looking_for_semicolon): 2170 if not (in_preprocessor_directive or looking_for_semicolon):
2170 if not match(r'\S', current_line) and not file_state.did_inside_ namespace_indent_warning(): 2171 if not match(r'\S', current_line) and not file_state.did_inside_ namespace_indent_warning():
2171 file_state.set_did_inside_namespace_indent_warning() 2172 file_state.set_did_inside_namespace_indent_warning()
2172 error(line_number + line_offset, 'whitespace/indent', 4, 2173 error(line_number + line_offset, 'whitespace/indent', 4,
2173 'Code inside a namespace should not be indented.') 2174 'Code inside a namespace should not be indented.')
2174 if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax. 2175 if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax.
2175 in_preprocessor_directive = current_line[-1] == '\\' 2176 in_preprocessor_directive = current_line[-1] == '\\'
2176 else: 2177 else:
2177 looking_for_semicolon = ((';' not in current_line) and (current_ line.strip() 2178 looking_for_semicolon = ((';' not in current_line) and (current_ line.strip()
2178 [-1 ] != '}')) or (current_line[-1] == '\\') 2179 [-1] != '}')) or (current_line[-1] == '\\')
2179 else: 2180 else:
2180 looking_for_semicolon = False # If we have a brace we may not need a semicolon. 2181 looking_for_semicolon = False # If we have a brace we may not need a semicolon.
2181 current_indentation_level += current_line.count('{') - current_line.coun t('}') 2182 current_indentation_level += current_line.count('{') - current_line.coun t('}')
2182 if current_indentation_level < 0: 2183 if current_indentation_level < 0:
2183 break 2184 break
2184 2185
2185 2186
2186 def check_enum_casing(clean_lines, line_number, enum_state, error): 2187 def check_enum_casing(clean_lines, line_number, enum_state, error):
2187 """Looks for incorrectly named enum values. 2188 """Looks for incorrectly named enum values.
2188 2189
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2415 # explicitly create a new scope, which is commonly used to control 2416 # explicitly create a new scope, which is commonly used to control
2416 # the lifetime of stack-allocated variables. We don't detect this 2417 # the lifetime of stack-allocated variables. We don't detect this
2417 # perfectly: we just don't complain if the last non-whitespace 2418 # perfectly: we just don't complain if the last non-whitespace
2418 # character on the previous non-blank line is ';', ':', '{', '}', 2419 # character on the previous non-blank line is ';', ':', '{', '}',
2419 # ')' or is like a function declaration, and doesn't begin with 2420 # ')' or is like a function declaration, and doesn't begin with
2420 # 'if|for|while|switch|else' without a beginning '{'. 2421 # 'if|for|while|switch|else' without a beginning '{'.
2421 # We also allow '#' for #endif and '=' for array initialization. 2422 # We also allow '#' for #endif and '=' for array initialization.
2422 previous_line = get_previous_non_blank_line(clean_lines, line_number)[0] 2423 previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
2423 if ((not search(r'[;:}{)=]\s*$|\)\s*((const|override|final)\s*)*\s*(->\s *.+)?$', previous_line) 2424 if ((not search(r'[;:}{)=]\s*$|\)\s*((const|override|final)\s*)*\s*(->\s *.+)?$', previous_line)
2424 or search(r'^\s*\b(if|for|foreach|while|switch|else)\b.*[^{]\s*$', previous_line)) 2425 or search(r'^\s*\b(if|for|foreach|while|switch|else)\b.*[^{]\s*$', previous_line))
2425 and previous_line.find('#') < 0): 2426 and previous_line.find('#') < 0):
2426 error(line_number, 'whitespace/braces', 4, 2427 error(line_number, 'whitespace/braces', 4,
2427 'This { should be at the end of the previous line') 2428 'This { should be at the end of the previous line')
2428 elif (search(r'\)\s*(((const|override|final)\s*)*\s*)?{\s*$', line) 2429 elif (search(r'\)\s*(((const|override|final)\s*)*\s*)?{\s*$', line)
2429 and line.count('(') == line.count(')') 2430 and line.count('(') == line.count(')')
2430 and not search(r'\b(if|for|foreach|while|switch)\b', line) 2431 and not search(r'\b(if|for|foreach|while|switch)\b', line)
2431 and not match(r'\s+[A-Z_][A-Z_0-9]+\b', line)): 2432 and not match(r'\s+[A-Z_][A-Z_0-9]+\b', line)):
2432 error(line_number, 'whitespace/braces', 4, 2433 error(line_number, 'whitespace/braces', 4,
2433 'Place brace on its own line for function definitions.') 2434 'Place brace on its own line for function definitions.')
2434 2435
2435 # An else clause should be on the same line as the preceding closing brace. 2436 # An else clause should be on the same line as the preceding closing brace.
(...skipping 17 matching lines...) Expand all
2453 # or initializing an array. 2454 # or initializing an array.
2454 # We can't tell in general, but we can for some common cases. 2455 # We can't tell in general, but we can for some common cases.
2455 previous_line_number = line_number 2456 previous_line_number = line_number
2456 while True: 2457 while True:
2457 (previous_line, previous_line_number) = get_previous_non_blank_line(clea n_lines, previous_line_number) 2458 (previous_line, previous_line_number) = get_previous_non_blank_line(clea n_lines, previous_line_number)
2458 if match(r'\s+{.*}\s*;', line) and not previous_line.count(';'): 2459 if match(r'\s+{.*}\s*;', line) and not previous_line.count(';'):
2459 line = previous_line + line 2460 line = previous_line + line
2460 else: 2461 else:
2461 break 2462 break
2462 if (search(r'{.*}\s*;', line) 2463 if (search(r'{.*}\s*;', line)
2463 and line.count('{') == line.count('}') 2464 and line.count('{') == line.count('}')
2464 and not search(r'struct|class|enum|\s*=\s*{', line)): 2465 and not search(r'struct|class|enum|\s*=\s*{', line)):
2465 error(line_number, 'readability/braces', 4, 2466 error(line_number, 'readability/braces', 4,
2466 "You don't need a ; after a }") 2467 "You don't need a ; after a }")
2467 2468
2468 2469
2469 def check_exit_statement_simplifications(clean_lines, line_number, error): 2470 def check_exit_statement_simplifications(clean_lines, line_number, error):
2470 """Looks for else or else-if statements that should be written as an 2471 """Looks for else or else-if statements that should be written as an
2471 if statement when the prior if concludes with a return, break, continue or 2472 if statement when the prior if concludes with a return, break, continue or
2472 goto statement. 2473 goto statement.
2473 2474
2474 Args: 2475 Args:
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2664 # Don't warn about NULL usage in gst_*(). See Bug 70498. 2665 # Don't warn about NULL usage in gst_*(). See Bug 70498.
2665 if search(r'\bgst(_[a-z]+)+\b', line): 2666 if search(r'\bgst(_[a-z]+)+\b', line):
2666 return 2667 return
2667 2668
2668 # Don't warn about NULL usage in gdk_pixbuf_save_to_*{join,concat}(). See Bu g 43090. 2669 # Don't warn about NULL usage in gdk_pixbuf_save_to_*{join,concat}(). See Bu g 43090.
2669 if search(r'\bgdk_pixbuf_save_to\w+\b', line): 2670 if search(r'\bgdk_pixbuf_save_to\w+\b', line):
2670 return 2671 return
2671 2672
2672 # Don't warn about NULL usage in gtk_widget_style_get(), 2673 # Don't warn about NULL usage in gtk_widget_style_get(),
2673 # gtk_style_context_get_style(), or gtk_style_context_get(). See Bug 51758 2674 # gtk_style_context_get_style(), or gtk_style_context_get(). See Bug 51758
2674 if search(r'\bgtk_widget_style_get\(\w+\b', line) or search(r'\bgtk_style_co ntext_get_style\(\w+\b', line) or search(r'\bgtk_style_context_get\(\w+\b', line ): 2675 if search(r'\bgtk_widget_style_get\(\w+\b', line) or search(r'\bgtk_style_co ntext_get_style\(\w+\b',
2676 line) or search( r'\bgtk_style_context_get\(\w+\b', line):
2675 return 2677 return
2676 2678
2677 # Don't warn about NULL usage in soup_server_new(). See Bug 77890. 2679 # Don't warn about NULL usage in soup_server_new(). See Bug 77890.
2678 if search(r'\bsoup_server_new\(\w+\b', line): 2680 if search(r'\bsoup_server_new\(\w+\b', line):
2679 return 2681 return
2680 2682
2681 if search(r'\bNULL\b', line): 2683 if search(r'\bNULL\b', line):
2682 error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.') 2684 error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.')
2683 return 2685 return
2684 2686
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
3026 3028
3027 Args: 3029 Args:
3028 filename: The input filename. 3030 filename: The input filename.
3029 3031
3030 Returns: 3032 Returns:
3031 The filename with the common suffix removed. 3033 The filename with the common suffix removed.
3032 """ 3034 """
3033 for suffix in ('test.cpp', 'regtest.cpp', 'unittest.cpp', 3035 for suffix in ('test.cpp', 'regtest.cpp', 'unittest.cpp',
3034 'inl.h', 'impl.h', 'internal.h'): 3036 'inl.h', 'impl.h', 'internal.h'):
3035 if (filename.endswith(suffix) and len(filename) > len(suffix) 3037 if (filename.endswith(suffix) and len(filename) > len(suffix)
3036 and filename[-len(suffix) - 1] in ('-', '_')): 3038 and filename[-len(suffix) - 1] in ('-', '_')):
3037 return filename[:-len(suffix) - 1] 3039 return filename[:-len(suffix) - 1]
3038 return os.path.splitext(filename)[0] 3040 return os.path.splitext(filename)[0]
3039 3041
3040 3042
3041 def _classify_include(filename, include, is_system, include_state): 3043 def _classify_include(filename, include, is_system, include_state):
3042 """Figures out what kind of header 'include' is. 3044 """Figures out what kind of header 'include' is.
3043 3045
3044 Args: 3046 Args:
3045 filename: The current file cpp_style is running over. 3047 filename: The current file cpp_style is running over.
3046 include: The path to a #included file. 3048 include: The path to a #included file.
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
3270 r'\((int|float|double|bool|char|u?int(16|32|64))\)', 3272 r'\((int|float|double|bool|char|u?int(16|32|64))\)',
3271 error) 3273 error)
3272 # This doesn't catch all cases. Consider (const char * const)"hello". 3274 # This doesn't catch all cases. Consider (const char * const)"hello".
3273 check_c_style_cast(line_number, line, clean_lines.raw_lines[line_number], 3275 check_c_style_cast(line_number, line, clean_lines.raw_lines[line_number],
3274 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) 3276 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
3275 3277
3276 # In addition, we look for people taking the address of a cast. This 3278 # In addition, we look for people taking the address of a cast. This
3277 # is dangerous -- casts can assign to temporaries, so the pointer doesn't 3279 # is dangerous -- casts can assign to temporaries, so the pointer doesn't
3278 # point where you think. 3280 # point where you think.
3279 if search( 3281 if search(
3280 r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line): 3282 r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
3281 error(line_number, 'runtime/casting', 4, 3283 error(line_number, 'runtime/casting', 4,
3282 ('Are you taking an address of a cast? ' 3284 ('Are you taking an address of a cast? '
3283 'This is dangerous: could be a temp var. ' 3285 'This is dangerous: could be a temp var. '
3284 'Take the address before doing the cast, rather than after')) 3286 'Take the address before doing the cast, rather than after'))
3285 3287
3286 # Check for people declaring static/global STL strings at the top level. 3288 # Check for people declaring static/global STL strings at the top level.
3287 # This is dangerous because the C++ language does not guarantee that 3289 # This is dangerous because the C++ language does not guarantee that
3288 # globals with constructors are initialized before the first access. 3290 # globals with constructors are initialized before the first access.
3289 matched = match( 3291 matched = match(
3290 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', 3292 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3361 # Check for potential memset bugs like memset(buf, sizeof(buf), 0). 3363 # Check for potential memset bugs like memset(buf, sizeof(buf), 0).
3362 matched = search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) 3364 matched = search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
3363 if matched and not match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", matched.group(2)): 3365 if matched and not match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", matched.group(2)):
3364 error(line_number, 'runtime/memset', 4, 3366 error(line_number, 'runtime/memset', 4,
3365 'Did you mean "memset(%s, 0, %s)"?' 3367 'Did you mean "memset(%s, 0, %s)"?'
3366 % (matched.group(1), matched.group(2))) 3368 % (matched.group(1), matched.group(2)))
3367 3369
3368 # Detect variable-length arrays. 3370 # Detect variable-length arrays.
3369 matched = match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) 3371 matched = match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
3370 if (matched and matched.group(2) != 'return' and matched.group(2) != 'delete ' and 3372 if (matched and matched.group(2) != 'return' and matched.group(2) != 'delete ' and
3371 matched.group(3).find(']') == -1): 3373 matched.group(3).find(']') == -1):
3372 # Split the size using space and arithmetic operators as delimiters. 3374 # Split the size using space and arithmetic operators as delimiters.
3373 # If any of the resulting tokens are not compile time constants then 3375 # If any of the resulting tokens are not compile time constants then
3374 # report the error. 3376 # report the error.
3375 tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', matched.group(3)) 3377 tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', matched.group(3))
3376 is_const = True 3378 is_const = True
3377 skip_next = False 3379 skip_next = False
3378 for tok in tokens: 3380 for tok in tokens:
3379 if skip_next: 3381 if skip_next:
3380 skip_next = False 3382 skip_next = False
3381 continue 3383 continue
(...skipping 27 matching lines...) Expand all
3409 break 3411 break
3410 if not is_const: 3412 if not is_const:
3411 error(line_number, 'runtime/arrays', 1, 3413 error(line_number, 'runtime/arrays', 1,
3412 'Do not use variable-length arrays. Use an appropriately name d ' 3414 'Do not use variable-length arrays. Use an appropriately name d '
3413 "('k' followed by CamelCase) compile-time constant for the siz e.") 3415 "('k' followed by CamelCase) compile-time constant for the siz e.")
3414 3416
3415 # Check for use of unnamed namespaces in header files. Registration 3417 # Check for use of unnamed namespaces in header files. Registration
3416 # macros are typically OK, so we allow use of "namespace {" on lines 3418 # macros are typically OK, so we allow use of "namespace {" on lines
3417 # that end with backslashes. 3419 # that end with backslashes.
3418 if (file_extension == 'h' 3420 if (file_extension == 'h'
3419 and search(r'\bnamespace\s*{', line) 3421 and search(r'\bnamespace\s*{', line)
3420 and line[-1] != '\\'): 3422 and line[-1] != '\\'):
3421 error(line_number, 'build/namespaces', 4, 3423 error(line_number, 'build/namespaces', 4,
3422 'Do not use unnamed namespaces in header files. See ' 3424 'Do not use unnamed namespaces in header files. See '
3423 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Na mespaces' 3425 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Na mespaces'
3424 ' for more information.') 3426 ' for more information.')
3425 3427
3426 # Check for plain bitfields declared without either "singed" or "unsigned". 3428 # Check for plain bitfields declared without either "singed" or "unsigned".
3427 # Most compilers treat such bitfields as signed, but there are still compile rs like 3429 # Most compilers treat such bitfields as signed, but there are still compile rs like
3428 # RVCT 4.0 that use unsigned by default. 3430 # RVCT 4.0 that use unsigned by default.
3429 matched = re.match( 3431 matched = re.match(
3430 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) 3432 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)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3498 # 3500 #
3499 # and we will need different treatments for them. 3501 # and we will need different treatments for them.
3500 line = sub(r'^\s*for\s*\(', '', line) 3502 line = sub(r'^\s*for\s*\(', '', line)
3501 line, control_statement = subn(r'^\s*(while|else if|if|switch)\s*\(', '', li ne) 3503 line, control_statement = subn(r'^\s*(while|else if|if|switch)\s*\(', '', li ne)
3502 3504
3503 # Detect variable and functions. 3505 # Detect variable and functions.
3504 type_regexp = r'\w([\w]|\s*[*&]\s*|::)+' 3506 type_regexp = r'\w([\w]|\s*[*&]\s*|::)+'
3505 identifier_regexp = r'(?P<identifier>[\w:]+)' 3507 identifier_regexp = r'(?P<identifier>[\w:]+)'
3506 maybe_bitfield_regexp = r'(:\s*\d+\s*)?' 3508 maybe_bitfield_regexp = r'(:\s*\d+\s*)?'
3507 character_after_identifier_regexp = r'(?P<character_after_identifier>[[;()=, ])(?!=)' 3509 character_after_identifier_regexp = r'(?P<character_after_identifier>[[;()=, ])(?!=)'
3508 declaration_without_type_regexp = r'\s*' + identifier_regexp + r'\s*' + mayb e_bitfield_regexp + character_after_identifier_regexp 3510 declaration_without_type_regexp = r'\s*' + identifier_regexp + \
3511 r'\s*' + maybe_bitfield_regexp + character_after_identifier_regexp
3509 declaration_with_type_regexp = r'\s*' + type_regexp + r'\s' + declaration_wi thout_type_regexp 3512 declaration_with_type_regexp = r'\s*' + type_regexp + r'\s' + declaration_wi thout_type_regexp
3510 is_function_arguments = False 3513 is_function_arguments = False
3511 number_of_identifiers = 0 3514 number_of_identifiers = 0
3512 while True: 3515 while True:
3513 # If we are seeing the first identifier or arguments of a 3516 # If we are seeing the first identifier or arguments of a
3514 # function, there should be a type name before an identifier. 3517 # function, there should be a type name before an identifier.
3515 if not number_of_identifiers or is_function_arguments: 3518 if not number_of_identifiers or is_function_arguments:
3516 declaration_regexp = declaration_with_type_regexp 3519 declaration_regexp = declaration_with_type_regexp
3517 else: 3520 else:
3518 declaration_regexp = declaration_without_type_regexp 3521 declaration_regexp = declaration_without_type_regexp
(...skipping 10 matching lines...) Expand all
3529 if control_statement and character_after_identifier != '=': 3532 if control_statement and character_after_identifier != '=':
3530 return 3533 return
3531 3534
3532 is_function_arguments = is_function_arguments or character_after_identif ier == '(' 3535 is_function_arguments = is_function_arguments or character_after_identif ier == '('
3533 3536
3534 # Remove "m_" and "s_" to allow them. 3537 # Remove "m_" and "s_" to allow them.
3535 modified_identifier = sub(r'(^|(?<=::))[ms]_', '', identifier) 3538 modified_identifier = sub(r'(^|(?<=::))[ms]_', '', identifier)
3536 if not file_state.is_objective_c() and modified_identifier.find('_') >= 0: 3539 if not file_state.is_objective_c() and modified_identifier.find('_') >= 0:
3537 # Various exceptions to the rule: JavaScript op codes functions, con st_iterator. 3540 # Various exceptions to the rule: JavaScript op codes functions, con st_iterator.
3538 if (not (filename.find('JavaScriptCore') >= 0 and modified_identifie r.find('op_') >= 0) 3541 if (not (filename.find('JavaScriptCore') >= 0 and modified_identifie r.find('op_') >= 0)
3539 and not (filename.find('gtk') >= 0 and modified_identifier.start swith('webkit_') >= 0) 3542 and not (filename.find('gtk') >= 0 and modified_identifier.s tartswith('webkit_') >= 0)
3540 and not modified_identifier.startswith('tst_') 3543 and not modified_identifier.startswith('tst_')
3541 and not modified_identifier.startswith('webkit_dom_object_') 3544 and not modified_identifier.startswith('webkit_dom_object_')
3542 and not modified_identifier.startswith('webkit_soup') 3545 and not modified_identifier.startswith('webkit_soup')
3543 and not modified_identifier.startswith('NPN_') 3546 and not modified_identifier.startswith('NPN_')
3544 and not modified_identifier.startswith('NPP_') 3547 and not modified_identifier.startswith('NPP_')
3545 and not modified_identifier.startswith('NP_') 3548 and not modified_identifier.startswith('NP_')
3546 and not modified_identifier.startswith('qt_') 3549 and not modified_identifier.startswith('qt_')
3547 and not modified_identifier.startswith('_q_') 3550 and not modified_identifier.startswith('_q_')
3548 and not modified_identifier.startswith('cairo_') 3551 and not modified_identifier.startswith('cairo_')
3549 and not modified_identifier.startswith('Ecore_') 3552 and not modified_identifier.startswith('Ecore_')
3550 and not modified_identifier.startswith('Eina_') 3553 and not modified_identifier.startswith('Eina_')
3551 and not modified_identifier.startswith('Evas_') 3554 and not modified_identifier.startswith('Evas_')
3552 and not modified_identifier.startswith('Ewk_') 3555 and not modified_identifier.startswith('Ewk_')
3553 and not modified_identifier.startswith('cti_') 3556 and not modified_identifier.startswith('cti_')
3554 and not modified_identifier.find('::qt_') >= 0 3557 and not modified_identifier.find('::qt_') >= 0
3555 and not modified_identifier.find('::_q_') >= 0 3558 and not modified_identifier.find('::_q_') >= 0
3556 and not modified_identifier == "const_iterator" 3559 and not modified_identifier == "const_iterator"
3557 and not modified_identifier == "vm_throw" 3560 and not modified_identifier == "vm_throw"
3558 and not modified_identifier == "DFG_OPERATION"): 3561 and not modified_identifier == "DFG_OPERATION"):
3559 error(line_number, 'readability/naming/underscores', 4, identifi er + 3562 error(line_number, 'readability/naming/underscores', 4, identifi er +
3560 " is incorrectly named. Don't use underscores in your iden tifier names.") 3563 " is incorrectly named. Don't use underscores in your iden tifier names.")
3561 3564
3562 # Check for variables named 'l', these are too easy to confuse with '1' in some fonts 3565 # Check for variables named 'l', these are too easy to confuse with '1' in some fonts
3563 if modified_identifier == 'l': 3566 if modified_identifier == 'l':
3564 error(line_number, 'readability/naming', 4, identifier + 3567 error(line_number, 'readability/naming', 4, identifier +
3565 " is incorrectly named. Don't use the single letter 'l' as an identifier name.") 3568 " is incorrectly named. Don't use the single letter 'l' as an identifier name.")
3566 3569
3567 # There can be only one declaration in non-for-control statements. 3570 # There can be only one declaration in non-for-control statements.
3568 if control_statement: 3571 if control_statement:
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
3749 # eg, void foo(int); or void foo(int) const; 3752 # eg, void foo(int); or void foo(int) const;
3750 # The equals check is for function pointer assignment. 3753 # The equals check is for function pointer assignment.
3751 # eg, void *(*foo)(int) = ... 3754 # eg, void *(*foo)(int) = ...
3752 # 3755 #
3753 # Right now, this will only catch cases where there's a single argument, and 3756 # Right now, this will only catch cases where there's a single argument, and
3754 # it's unnamed. It should probably be expanded to check for multiple 3757 # it's unnamed. It should probably be expanded to check for multiple
3755 # arguments with some unnamed. 3758 # arguments with some unnamed.
3756 function_match = match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder) 3759 function_match = match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder)
3757 if function_match: 3760 if function_match:
3758 if (not function_match.group(3) 3761 if (not function_match.group(3)
3759 or function_match.group(3) == ';' 3762 or function_match.group(3) == ';'
3760 or raw_line.find('/*') < 0): 3763 or raw_line.find('/*') < 0):
3761 error(line_number, 'readability/function', 3, 3764 error(line_number, 'readability/function', 3,
3762 'All parameters should be named in a function') 3765 'All parameters should be named in a function')
3763 return 3766 return
3764 3767
3765 # At this point, all that should be left is actual casts. 3768 # At this point, all that should be left is actual casts.
3766 error(line_number, 'readability/casting', 4, 3769 error(line_number, 'readability/casting', 4,
3767 'Using C-style cast. Use %s<%s>(...) instead' % 3770 'Using C-style cast. Use %s<%s>(...) instead' %
3768 (cast_type, matched.group(1))) 3771 (cast_type, matched.group(1)))
3769 3772
3770 3773
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 4213
4211 def check(self, lines): 4214 def check(self, lines):
4212 _process_lines(self.file_path, self.file_extension, lines, 4215 _process_lines(self.file_path, self.file_extension, lines,
4213 self.handle_style_error, self.min_confidence) 4216 self.handle_style_error, self.min_confidence)
4214 4217
4215 4218
4216 # FIXME: Remove this function (requires refactoring unit tests). 4219 # FIXME: Remove this function (requires refactoring unit tests).
4217 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None): 4220 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None):
4218 checker = CppChecker(filename, file_extension, error, min_confidence, fs) 4221 checker = CppChecker(filename, file_extension, error, min_confidence, fs)
4219 checker.check(lines) 4222 checker.check(lines)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698