| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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) |
| OLD | NEW |