| 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 if c == '(': | 285 if c == '(': |
| 286 i += 1 | 286 i += 1 |
| 287 elif c == ')': | 287 elif c == ')': |
| 288 i -= 1 | 288 i -= 1 |
| 289 if i == 0: | 289 if i == 0: |
| 290 return s[:pos], s[pos + 1:] | 290 return s[:pos], s[pos + 1:] |
| 291 return None, None | 291 return None, None |
| 292 | 292 |
| 293 | 293 |
| 294 class _IncludeState(dict): | 294 class _IncludeState(dict): |
| 295 |
| 295 """Tracks line numbers for includes, and the order in which includes appear. | 296 """Tracks line numbers for includes, and the order in which includes appear. |
| 296 | 297 |
| 297 As a dict, an _IncludeState object serves as a mapping between include | 298 As a dict, an _IncludeState object serves as a mapping between include |
| 298 filename and line number on which that file was included. | 299 filename and line number on which that file was included. |
| 299 | 300 |
| 300 Call check_next_include_order() once for each header in the file, passing | 301 Call check_next_include_order() once for each header in the file, passing |
| 301 in the type constants defined above. Calls in an illegal order will | 302 in the type constants defined above. Calls in an illegal order will |
| 302 raise an _IncludeError with an appropriate error message. | 303 raise an _IncludeError with an appropriate error message. |
| 303 | 304 |
| 304 """ | 305 """ |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 assert header_type == _OTHER_HEADER | 367 assert header_type == _OTHER_HEADER |
| 367 if not file_is_header and self._section < self._PRIMARY_SECTION: | 368 if not file_is_header and self._section < self._PRIMARY_SECTION: |
| 368 if primary_header_exists: | 369 if primary_header_exists: |
| 369 error_message = before_error_message | 370 error_message = before_error_message |
| 370 self._section = self._OTHER_SECTION | 371 self._section = self._OTHER_SECTION |
| 371 | 372 |
| 372 return error_message | 373 return error_message |
| 373 | 374 |
| 374 | 375 |
| 375 class Position(object): | 376 class Position(object): |
| 377 |
| 376 """Holds the position of something.""" | 378 """Holds the position of something.""" |
| 377 | 379 |
| 378 def __init__(self, row, column): | 380 def __init__(self, row, column): |
| 379 self.row = row | 381 self.row = row |
| 380 self.column = column | 382 self.column = column |
| 381 | 383 |
| 382 def __str__(self): | 384 def __str__(self): |
| 383 return '(%s, %s)' % (self.row, self.column) | 385 return '(%s, %s)' % (self.row, self.column) |
| 384 | 386 |
| 385 def __cmp__(self, other): | 387 def __cmp__(self, other): |
| 386 return self.row.__cmp__(other.row) or self.column.__cmp__(other.column) | 388 return self.row.__cmp__(other.row) or self.column.__cmp__(other.column) |
| 387 | 389 |
| 388 | 390 |
| 389 class Parameter(object): | 391 class Parameter(object): |
| 392 |
| 390 """Information about one function parameter.""" | 393 """Information about one function parameter.""" |
| 391 | 394 |
| 392 def __init__(self, parameter, parameter_name_index, row): | 395 def __init__(self, parameter, parameter_name_index, row): |
| 393 self.type = parameter[:parameter_name_index].strip() | 396 self.type = parameter[:parameter_name_index].strip() |
| 394 # Remove any initializers from the parameter name (e.g. int i = 5). | 397 # Remove any initializers from the parameter name (e.g. int i = 5). |
| 395 self.name = sub(r'=.*', '', parameter[parameter_name_index:]).strip() | 398 self.name = sub(r'=.*', '', parameter[parameter_name_index:]).strip() |
| 396 self.row = row | 399 self.row = row |
| 397 | 400 |
| 398 @memoized | 401 @memoized |
| 399 def lower_with_underscores_name(self): | 402 def lower_with_underscores_name(self): |
| 400 """Returns the parameter name in the lower with underscores format.""" | 403 """Returns the parameter name in the lower with underscores format.""" |
| 401 return _convert_to_lower_with_underscores(self.name) | 404 return _convert_to_lower_with_underscores(self.name) |
| 402 | 405 |
| 403 | 406 |
| 404 class SingleLineView(object): | 407 class SingleLineView(object): |
| 408 |
| 405 """Converts multiple lines into a single line (with line breaks replaced by
a | 409 """Converts multiple lines into a single line (with line breaks replaced by
a |
| 406 space) to allow for easier searching.""" | 410 space) to allow for easier searching.""" |
| 407 | 411 |
| 408 def __init__(self, lines, start_position, end_position): | 412 def __init__(self, lines, start_position, end_position): |
| 409 """Create a SingleLineView instance. | 413 """Create a SingleLineView instance. |
| 410 | 414 |
| 411 Args: | 415 Args: |
| 412 lines: a list of multiple lines to combine into a single line. | 416 lines: a list of multiple lines to combine into a single line. |
| 413 start_position: offset within lines of where to start the single line. | 417 start_position: offset within lines of where to start the single line. |
| 414 end_position: just after where to end (like a slice operation). | 418 end_position: just after where to end (like a slice operation). |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 row = single_line_view.convert_column_to_row(end_index) | 512 row = single_line_view.convert_column_to_row(end_index) |
| 509 | 513 |
| 510 # Parse the parameter into a type and parameter name. | 514 # Parse the parameter into a type and parameter name. |
| 511 skeleton_parameter = skeleton_parameters[start_index:end_index] | 515 skeleton_parameter = skeleton_parameters[start_index:end_index] |
| 512 name_offset = find_parameter_name_index(skeleton_parameter) | 516 name_offset = find_parameter_name_index(skeleton_parameter) |
| 513 parameter = single_line_view.single_line[start_index:end_index] | 517 parameter = single_line_view.single_line[start_index:end_index] |
| 514 yield Parameter(parameter, name_offset, row) | 518 yield Parameter(parameter, name_offset, row) |
| 515 | 519 |
| 516 | 520 |
| 517 class _FunctionState(object): | 521 class _FunctionState(object): |
| 522 |
| 518 """Tracks current function name and the number of lines in its body. | 523 """Tracks current function name and the number of lines in its body. |
| 519 | 524 |
| 520 Attributes: | 525 Attributes: |
| 521 min_confidence: The minimum confidence level to use while checking style. | 526 min_confidence: The minimum confidence level to use while checking style. |
| 522 | 527 |
| 523 """ | 528 """ |
| 524 | 529 |
| 525 _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. | 530 _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. |
| 526 _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. | 531 _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. |
| 527 | 532 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 if self.is_declaration: | 566 if self.is_declaration: |
| 562 characters_after_parameters = SingleLineView( | 567 characters_after_parameters = SingleLineView( |
| 563 clean_lines.elided, parameter_end_position, body_start_position)
.single_line | 568 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)) | 569 self.is_pure = bool(match(r'\s*=\s*0\s*', characters_after_parameter
s)) |
| 565 self._clean_lines = clean_lines | 570 self._clean_lines = clean_lines |
| 566 self._parameter_list = None | 571 self._parameter_list = None |
| 567 | 572 |
| 568 def modifiers_and_return_type(self): | 573 def modifiers_and_return_type(self): |
| 569 """Returns the modifiers and the return type.""" | 574 """Returns the modifiers and the return type.""" |
| 570 # Go backwards from where the function name is until we encounter one of
several things: | 575 # 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
) | 576 # ';' or '{' or '}' or 'private:', etc. or '#' or return Position(0, 0) |
| 572 elided = self._clean_lines.elided | 577 elided = self._clean_lines.elided |
| 573 start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected):
)|(#.*)', | 578 start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected):
)|(#.*)', |
| 574 elided, self.parameter_start_position,
Position(0, 0)) | 579 elided, self.parameter_start_position,
Position(0, 0)) |
| 575 return SingleLineView(elided, start_modifiers, self.function_name_start_
position).single_line.strip() | 580 return SingleLineView(elided, start_modifiers, self.function_name_start_
position).single_line.strip() |
| 576 | 581 |
| 577 def parameter_list(self): | 582 def parameter_list(self): |
| 578 if not self._parameter_list: | 583 if not self._parameter_list: |
| 579 # Store the final result as a tuple since that is immutable. | 584 # Store the final result as a tuple since that is immutable. |
| 580 self._parameter_list = tuple(parameter_list(self._clean_lines.elided
, | 585 self._parameter_list = tuple(parameter_list(self._clean_lines.elided
, |
| 581 self.parameter_start_pos
ition, self.parameter_end_position)) | 586 self.parameter_start_pos
ition, self.parameter_end_position)) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 610 ' %s has %d non-comment lines' | 615 ' %s has %d non-comment lines' |
| 611 ' (error triggered by exceeding %d lines).' % ( | 616 ' (error triggered by exceeding %d lines).' % ( |
| 612 self.current_function, self.lines_in_function, trigger)) | 617 self.current_function, self.lines_in_function, trigger)) |
| 613 | 618 |
| 614 def end(self): | 619 def end(self): |
| 615 """Stop analyzing function body.""" | 620 """Stop analyzing function body.""" |
| 616 self.in_a_function = False | 621 self.in_a_function = False |
| 617 | 622 |
| 618 | 623 |
| 619 class _IncludeError(Exception): | 624 class _IncludeError(Exception): |
| 625 |
| 620 """Indicates a problem with the include order in a file.""" | 626 """Indicates a problem with the include order in a file.""" |
| 621 pass | 627 pass |
| 622 | 628 |
| 623 | 629 |
| 624 class FileInfo: | 630 class FileInfo: |
| 631 |
| 625 """Provides utility functions for filenames. | 632 """Provides utility functions for filenames. |
| 626 | 633 |
| 627 FileInfo provides easy access to the components of a file's path | 634 FileInfo provides easy access to the components of a file's path |
| 628 relative to the project root. | 635 relative to the project root. |
| 629 """ | 636 """ |
| 630 | 637 |
| 631 def __init__(self, filename): | 638 def __init__(self, filename): |
| 632 self._filename = filename | 639 self._filename = filename |
| 633 | 640 |
| 634 def full_name(self): | 641 def full_name(self): |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 The line with single-line comments removed. | 810 The line with single-line comments removed. |
| 804 """ | 811 """ |
| 805 comment_position = line.find('//') | 812 comment_position = line.find('//') |
| 806 if comment_position != -1 and not is_cpp_string(line[:comment_position]): | 813 if comment_position != -1 and not is_cpp_string(line[:comment_position]): |
| 807 line = line[:comment_position] | 814 line = line[:comment_position] |
| 808 # get rid of /* ... */ | 815 # get rid of /* ... */ |
| 809 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) | 816 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) |
| 810 | 817 |
| 811 | 818 |
| 812 class CleansedLines(object): | 819 class CleansedLines(object): |
| 820 |
| 813 """Holds 3 copies of all lines with different preprocessing applied to them. | 821 """Holds 3 copies of all lines with different preprocessing applied to them. |
| 814 | 822 |
| 815 1) elided member contains lines without strings and comments, | 823 1) elided member contains lines without strings and comments, |
| 816 2) lines member contains lines without comments, and | 824 2) lines member contains lines without comments, and |
| 817 3) raw member contains all the lines without processing. | 825 3) raw member contains all the lines without processing. |
| 818 All these three members are of <type 'list'>, and of the same length. | 826 All these three members are of <type 'list'>, and of the same length. |
| 819 """ | 827 """ |
| 820 | 828 |
| 821 def __init__(self, lines): | 829 def __init__(self, lines): |
| 822 self.elided = [] | 830 self.elided = [] |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1157 line_number: The number of the line to check. | 1165 line_number: The number of the line to check. |
| 1158 error: The function to call with any errors found. | 1166 error: The function to call with any errors found. |
| 1159 """ | 1167 """ |
| 1160 line = clean_lines.elided[line_number] | 1168 line = clean_lines.elided[line_number] |
| 1161 if _RE_PATTERN_INVALID_INCREMENT.match(line): | 1169 if _RE_PATTERN_INVALID_INCREMENT.match(line): |
| 1162 error(line_number, 'runtime/invalid_increment', 5, | 1170 error(line_number, 'runtime/invalid_increment', 5, |
| 1163 'Changing pointer instead of value (or unused value of operator*).
') | 1171 'Changing pointer instead of value (or unused value of operator*).
') |
| 1164 | 1172 |
| 1165 | 1173 |
| 1166 class _ClassInfo(object): | 1174 class _ClassInfo(object): |
| 1175 |
| 1167 """Stores information about a class.""" | 1176 """Stores information about a class.""" |
| 1168 | 1177 |
| 1169 def __init__(self, name, line_number): | 1178 def __init__(self, name, line_number): |
| 1170 self.name = name | 1179 self.name = name |
| 1171 self.line_number = line_number | 1180 self.line_number = line_number |
| 1172 self.seen_open_brace = False | 1181 self.seen_open_brace = False |
| 1173 self.is_derived = False | 1182 self.is_derived = False |
| 1174 self.virtual_method_line_number = None | 1183 self.virtual_method_line_number = None |
| 1175 self.has_virtual_destructor = False | 1184 self.has_virtual_destructor = False |
| 1176 self.brace_depth = 0 | 1185 self.brace_depth = 0 |
| 1177 self.unsigned_bitfields = [] | 1186 self.unsigned_bitfields = [] |
| 1178 self.bool_bitfields = [] | 1187 self.bool_bitfields = [] |
| 1179 | 1188 |
| 1180 | 1189 |
| 1181 class _ClassState(object): | 1190 class _ClassState(object): |
| 1191 |
| 1182 """Holds the current state of the parse relating to class declarations. | 1192 """Holds the current state of the parse relating to class declarations. |
| 1183 | 1193 |
| 1184 It maintains a stack of _ClassInfos representing the parser's guess | 1194 It maintains a stack of _ClassInfos representing the parser's guess |
| 1185 as to the current nesting of class declarations. The innermost class | 1195 as to the current nesting of class declarations. The innermost class |
| 1186 is at the top (back) of the stack. Typically, the stack will either | 1196 is at the top (back) of the stack. Typically, the stack will either |
| 1187 be empty or have exactly one entry. | 1197 be empty or have exactly one entry. |
| 1188 """ | 1198 """ |
| 1189 | 1199 |
| 1190 def __init__(self): | 1200 def __init__(self): |
| 1191 self.classinfo_stack = [] | 1201 self.classinfo_stack = [] |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 else: | 1266 else: |
| 1257 self._is_c = False | 1267 self._is_c = False |
| 1258 return self._is_c | 1268 return self._is_c |
| 1259 | 1269 |
| 1260 def is_c_or_objective_c(self): | 1270 def is_c_or_objective_c(self): |
| 1261 """Return whether the file extension corresponds to C or Objective-C.""" | 1271 """Return whether the file extension corresponds to C or Objective-C.""" |
| 1262 return self.is_c() or self.is_objective_c() | 1272 return self.is_c() or self.is_objective_c() |
| 1263 | 1273 |
| 1264 | 1274 |
| 1265 class _EnumState(object): | 1275 class _EnumState(object): |
| 1276 |
| 1266 """Maintains whether currently in an enum declaration, and checks whether | 1277 """Maintains whether currently in an enum declaration, and checks whether |
| 1267 enum declarations follow the style guide. | 1278 enum declarations follow the style guide. |
| 1268 """ | 1279 """ |
| 1269 | 1280 |
| 1270 def __init__(self): | 1281 def __init__(self): |
| 1271 self.in_enum_decl = False | 1282 self.in_enum_decl = False |
| 1272 self.is_webidl_enum = False | 1283 self.is_webidl_enum = False |
| 1273 | 1284 |
| 1274 def process_clean_line(self, line): | 1285 def process_clean_line(self, line): |
| 1275 # FIXME: The regular expressions for expr_all_uppercase and expr_enum_en
d only accept integers | 1286 # FIXME: The regular expressions for expr_all_uppercase and expr_enum_en
d only accept integers |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 brace_depth = classinfo.brace_depth | 1460 brace_depth = classinfo.brace_depth |
| 1450 brace_depth = brace_depth + line.count('{') - line.count('}') | 1461 brace_depth = brace_depth + line.count('{') - line.count('}') |
| 1451 if brace_depth <= 0: | 1462 if brace_depth <= 0: |
| 1452 classinfo = classinfo_stack.pop() | 1463 classinfo = classinfo_stack.pop() |
| 1453 # Try to detect missing virtual destructor declarations. | 1464 # Try to detect missing virtual destructor declarations. |
| 1454 # For now, only warn if a non-derived class with virtual methods lacks | 1465 # 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 | 1466 # a virtual destructor. This is to make it less likely that people will |
| 1456 # declare derived virtual destructors without declaring the base | 1467 # declare derived virtual destructors without declaring the base |
| 1457 # destructor virtual. | 1468 # destructor virtual. |
| 1458 if ((classinfo.virtual_method_line_number is not None) | 1469 if ((classinfo.virtual_method_line_number is not None) |
| 1459 and (not classinfo.has_virtual_destructor) | 1470 and (not classinfo.has_virtual_destructor) |
| 1460 and (not classinfo.is_derived)): # Only warn for base classes | 1471 and (not classinfo.is_derived)): # Only warn for base classes |
| 1461 error(classinfo.line_number, 'runtime/virtual', 4, | 1472 error(classinfo.line_number, 'runtime/virtual', 4, |
| 1462 'The class %s probably needs a virtual destructor due to ' | 1473 'The class %s probably needs a virtual destructor due to ' |
| 1463 'having virtual method(s), one declared at line %d.' | 1474 'having virtual method(s), one declared at line %d.' |
| 1464 % (classinfo.name, classinfo.virtual_method_line_number)) | 1475 % (classinfo.name, classinfo.virtual_method_line_number)) |
| 1465 # Look for mixed bool and unsigned bitfields. | 1476 # Look for mixed bool and unsigned bitfields. |
| 1466 if (classinfo.bool_bitfields and classinfo.unsigned_bitfields): | 1477 if (classinfo.bool_bitfields and classinfo.unsigned_bitfields): |
| 1467 bool_list = ', '.join(classinfo.bool_bitfields) | 1478 bool_list = ', '.join(classinfo.bool_bitfields) |
| 1468 unsigned_list = ', '.join(classinfo.unsigned_bitfields) | 1479 unsigned_list = ', '.join(classinfo.unsigned_bitfields) |
| 1469 error(classinfo.line_number, 'runtime/bitfields', 5, | 1480 error(classinfo.line_number, 'runtime/bitfields', 5, |
| 1470 'The class %s contains mixed unsigned and bool bitfields, ' | 1481 '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 | 1542 # 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 | 1543 # 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: | 1544 # pointers and references to arrays and functions coz they're too tricky: |
| 1534 # we use a very simple way to recognize these: | 1545 # we use a very simple way to recognize these: |
| 1535 # " (something)(maybe-something)" or | 1546 # " (something)(maybe-something)" or |
| 1536 # " (something)(maybe-something," or | 1547 # " (something)(maybe-something," or |
| 1537 # " (something)[something]" | 1548 # " (something)[something]" |
| 1538 # Note that we assume the contents of [] to be short enough that | 1549 # Note that we assume the contents of [] to be short enough that |
| 1539 # they'll never need to wrap. | 1550 # they'll never need to wrap. |
| 1540 if ( # Ignore control structures. | 1551 if ( # Ignore control structures. |
| 1541 not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', funct
ion_call) | 1552 not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', f
unction_call) |
| 1542 # Ignore pointers/references to functions. | 1553 # Ignore pointers/references to functions. |
| 1543 and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call) | 1554 and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call) |
| 1544 # Ignore pointers/references to arrays. | 1555 # Ignore pointers/references to arrays. |
| 1545 and not search(r' \([^)]+\)\[[^\]]+\]', function_call)): | 1556 and not search(r' \([^)]+\)\[[^\]]+\]', function_call)): |
| 1546 if search(r'\w\s*\([ \t](?!\s*\\$)', function_call): # a ( used for
a fn call | 1557 if search(r'\w\s*\([ \t](?!\s*\\$)', function_call): # a ( used for
a fn call |
| 1547 error(line_number, 'whitespace/parens', 4, | 1558 error(line_number, 'whitespace/parens', 4, |
| 1548 'Extra space after ( in function call') | 1559 'Extra space after ( in function call') |
| 1549 elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call): | 1560 elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call): |
| 1550 error(line_number, 'whitespace/parens', 2, | 1561 error(line_number, 'whitespace/parens', 2, |
| 1551 'Extra space after (') | 1562 'Extra space after (') |
| 1552 if (search(r'\w\s+\(', function_call) | 1563 if (search(r'\w\s+\(', function_call) |
| 1553 and not match(r'\s*(#|typedef)', function_call)): | 1564 and not match(r'\s*(#|typedef)', function_call)): |
| 1554 error(line_number, 'whitespace/parens', 4, | 1565 error(line_number, 'whitespace/parens', 4, |
| 1555 'Extra space before ( in function call') | 1566 'Extra space before ( in function call') |
| 1556 # If the ) is followed only by a newline or a { + newline, assume it's | 1567 # 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 | 1568 # part of a control statement (if/while/etc), and don't complain |
| 1558 if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call): | 1569 if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call): |
| 1559 error(line_number, 'whitespace/parens', 2, | 1570 error(line_number, 'whitespace/parens', 2, |
| 1560 'Extra space before )') | 1571 'Extra space before )') |
| 1561 | 1572 |
| 1562 | 1573 |
| 1563 def is_blank_line(line): | 1574 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. | 1765 clean_lines: A CleansedLines instance containing the file. |
| 1755 line_number: The number of the line to check. | 1766 line_number: The number of the line to check. |
| 1756 function_state: Current function name and lines in body so far. | 1767 function_state: Current function name and lines in body so far. |
| 1757 error: The function to call with any errors found. | 1768 error: The function to call with any errors found. |
| 1758 """ | 1769 """ |
| 1759 if line_number != function_state.body_start_position.row: | 1770 if line_number != function_state.body_start_position.row: |
| 1760 return | 1771 return |
| 1761 | 1772 |
| 1762 modifiers_and_return_type = function_state.modifiers_and_return_type() | 1773 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): | 1774 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: | 1775 if filename.find('/chromium/public/') == -1 and filename.find('/chromium
/tests/') == - \ |
| 1776 1 and filename.find('chromium/platform') == -1: |
| 1765 error(function_state.function_name_start_position.row, 'readability/
webkit_export', 5, | 1777 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.') | 1778 'WEBKIT_EXPORT should only appear in the chromium public (or t
ests) directory.') |
| 1767 elif not file_extension == "h": | 1779 elif not file_extension == "h": |
| 1768 error(function_state.function_name_start_position.row, 'readability/
webkit_export', 5, | 1780 error(function_state.function_name_start_position.row, 'readability/
webkit_export', 5, |
| 1769 'WEBKIT_EXPORT should only be used in header files.') | 1781 '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): | 1782 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, | 1783 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.') | 1784 'WEBKIT_EXPORT should not be used on a function with a body.') |
| 1773 elif function_state.is_pure: | 1785 elif function_state.is_pure: |
| 1774 error(function_state.function_name_start_position.row, 'readability/
webkit_export', 5, | 1786 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 '}'). | 1883 # blank lines at the end of a function (ie, right before a line like '}'). |
| 1872 if is_blank_line(line): | 1884 if is_blank_line(line): |
| 1873 elided = clean_lines.elided | 1885 elided = clean_lines.elided |
| 1874 previous_line = elided[line_number - 1] | 1886 previous_line = elided[line_number - 1] |
| 1875 previous_brace = previous_line.rfind('{') | 1887 previous_brace = previous_line.rfind('{') |
| 1876 # FIXME: Don't complain if line before blank line, and line after, | 1888 # FIXME: Don't complain if line before blank line, and line after, |
| 1877 # both start with alnums and are indented the same amount. | 1889 # both start with alnums and are indented the same amount. |
| 1878 # This ignores whitespace at the start of a namespace block | 1890 # This ignores whitespace at the start of a namespace block |
| 1879 # because those are not usually indented. | 1891 # because those are not usually indented. |
| 1880 if (previous_brace != -1 and previous_line[previous_brace:].find('}') ==
-1 | 1892 if (previous_brace != -1 and previous_line[previous_brace:].find('}') ==
-1 |
| 1881 and previous_line[:previous_brace].find('namespace') == -1): | 1893 and previous_line[:previous_brace].find('namespace') == -1): |
| 1882 # OK, we have a blank line at the start of a code block. Before we | 1894 # 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 | 1895 # 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 | 1896 # 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 | 1897 # 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 | 1898 # 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 | 1899 # 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. | 1900 # initializers of a constructor do not fit into a 80 column line. |
| 1889 exception = False | 1901 exception = False |
| 1890 if match(r' {6}\w', previous_line): # Initializer list? | 1902 if match(r' {6}\w', previous_line): # Initializer list? |
| 1891 # We are looking for the opening column of initializer list, whi
ch | 1903 # 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: | 2180 if not current_indentation_level: |
| 2169 if not (in_preprocessor_directive or looking_for_semicolon): | 2181 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(): | 2182 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() | 2183 file_state.set_did_inside_namespace_indent_warning() |
| 2172 error(line_number + line_offset, 'whitespace/indent', 4, | 2184 error(line_number + line_offset, 'whitespace/indent', 4, |
| 2173 'Code inside a namespace should not be indented.') | 2185 '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. | 2186 if in_preprocessor_directive or (current_line.strip()[0] == '#'): #
This takes care of preprocessor directive syntax. |
| 2175 in_preprocessor_directive = current_line[-1] == '\\' | 2187 in_preprocessor_directive = current_line[-1] == '\\' |
| 2176 else: | 2188 else: |
| 2177 looking_for_semicolon = ((';' not in current_line) and (current_
line.strip() | 2189 looking_for_semicolon = ((';' not in current_line) and (current_
line.strip() |
| 2178 [-1
] != '}')) or (current_line[-1] == '\\') | 2190 [-1] !=
'}')) or (current_line[-1] == '\\') |
| 2179 else: | 2191 else: |
| 2180 looking_for_semicolon = False # If we have a brace we may not need
a semicolon. | 2192 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('}') | 2193 current_indentation_level += current_line.count('{') - current_line.coun
t('}') |
| 2182 if current_indentation_level < 0: | 2194 if current_indentation_level < 0: |
| 2183 break | 2195 break |
| 2184 | 2196 |
| 2185 | 2197 |
| 2186 def check_enum_casing(clean_lines, line_number, enum_state, error): | 2198 def check_enum_casing(clean_lines, line_number, enum_state, error): |
| 2187 """Looks for incorrectly named enum values. | 2199 """Looks for incorrectly named enum values. |
| 2188 | 2200 |
| (...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 | 2427 # explicitly create a new scope, which is commonly used to control |
| 2416 # the lifetime of stack-allocated variables. We don't detect this | 2428 # the lifetime of stack-allocated variables. We don't detect this |
| 2417 # perfectly: we just don't complain if the last non-whitespace | 2429 # perfectly: we just don't complain if the last non-whitespace |
| 2418 # character on the previous non-blank line is ';', ':', '{', '}', | 2430 # character on the previous non-blank line is ';', ':', '{', '}', |
| 2419 # ')' or is like a function declaration, and doesn't begin with | 2431 # ')' or is like a function declaration, and doesn't begin with |
| 2420 # 'if|for|while|switch|else' without a beginning '{'. | 2432 # 'if|for|while|switch|else' without a beginning '{'. |
| 2421 # We also allow '#' for #endif and '=' for array initialization. | 2433 # We also allow '#' for #endif and '=' for array initialization. |
| 2422 previous_line = get_previous_non_blank_line(clean_lines, line_number)[0] | 2434 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) | 2435 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)) | 2436 or search(r'^\s*\b(if|for|foreach|while|switch|else)\b.*[^{]\s*$',
previous_line)) |
| 2425 and previous_line.find('#') < 0): | 2437 and previous_line.find('#') < 0): |
| 2426 error(line_number, 'whitespace/braces', 4, | 2438 error(line_number, 'whitespace/braces', 4, |
| 2427 'This { should be at the end of the previous line') | 2439 'This { should be at the end of the previous line') |
| 2428 elif (search(r'\)\s*(((const|override|final)\s*)*\s*)?{\s*$', line) | 2440 elif (search(r'\)\s*(((const|override|final)\s*)*\s*)?{\s*$', line) |
| 2429 and line.count('(') == line.count(')') | 2441 and line.count('(') == line.count(')') |
| 2430 and not search(r'\b(if|for|foreach|while|switch)\b', line) | 2442 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)): | 2443 and not match(r'\s+[A-Z_][A-Z_0-9]+\b', line)): |
| 2432 error(line_number, 'whitespace/braces', 4, | 2444 error(line_number, 'whitespace/braces', 4, |
| 2433 'Place brace on its own line for function definitions.') | 2445 'Place brace on its own line for function definitions.') |
| 2434 | 2446 |
| 2435 # An else clause should be on the same line as the preceding closing brace. | 2447 # 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. | 2465 # or initializing an array. |
| 2454 # We can't tell in general, but we can for some common cases. | 2466 # We can't tell in general, but we can for some common cases. |
| 2455 previous_line_number = line_number | 2467 previous_line_number = line_number |
| 2456 while True: | 2468 while True: |
| 2457 (previous_line, previous_line_number) = get_previous_non_blank_line(clea
n_lines, previous_line_number) | 2469 (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(';'): | 2470 if match(r'\s+{.*}\s*;', line) and not previous_line.count(';'): |
| 2459 line = previous_line + line | 2471 line = previous_line + line |
| 2460 else: | 2472 else: |
| 2461 break | 2473 break |
| 2462 if (search(r'{.*}\s*;', line) | 2474 if (search(r'{.*}\s*;', line) |
| 2463 and line.count('{') == line.count('}') | 2475 and line.count('{') == line.count('}') |
| 2464 and not search(r'struct|class|enum|\s*=\s*{', line)): | 2476 and not search(r'struct|class|enum|\s*=\s*{', line)): |
| 2465 error(line_number, 'readability/braces', 4, | 2477 error(line_number, 'readability/braces', 4, |
| 2466 "You don't need a ; after a }") | 2478 "You don't need a ; after a }") |
| 2467 | 2479 |
| 2468 | 2480 |
| 2469 def check_exit_statement_simplifications(clean_lines, line_number, error): | 2481 def check_exit_statement_simplifications(clean_lines, line_number, error): |
| 2470 """Looks for else or else-if statements that should be written as an | 2482 """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 | 2483 if statement when the prior if concludes with a return, break, continue or |
| 2472 goto statement. | 2484 goto statement. |
| 2473 | 2485 |
| 2474 Args: | 2486 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. | 2676 # Don't warn about NULL usage in gst_*(). See Bug 70498. |
| 2665 if search(r'\bgst(_[a-z]+)+\b', line): | 2677 if search(r'\bgst(_[a-z]+)+\b', line): |
| 2666 return | 2678 return |
| 2667 | 2679 |
| 2668 # Don't warn about NULL usage in gdk_pixbuf_save_to_*{join,concat}(). See Bu
g 43090. | 2680 # 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): | 2681 if search(r'\bgdk_pixbuf_save_to\w+\b', line): |
| 2670 return | 2682 return |
| 2671 | 2683 |
| 2672 # Don't warn about NULL usage in gtk_widget_style_get(), | 2684 # 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 | 2685 # 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
): | 2686 if search(r'\bgtk_widget_style_get\(\w+\b', line) or search(r'\bgtk_style_co
ntext_get_style\(\w+\b', |
| 2687 line) or search(
r'\bgtk_style_context_get\(\w+\b', line): |
| 2675 return | 2688 return |
| 2676 | 2689 |
| 2677 # Don't warn about NULL usage in soup_server_new(). See Bug 77890. | 2690 # Don't warn about NULL usage in soup_server_new(). See Bug 77890. |
| 2678 if search(r'\bsoup_server_new\(\w+\b', line): | 2691 if search(r'\bsoup_server_new\(\w+\b', line): |
| 2679 return | 2692 return |
| 2680 | 2693 |
| 2681 if search(r'\bNULL\b', line): | 2694 if search(r'\bNULL\b', line): |
| 2682 error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.') | 2695 error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.') |
| 2683 return | 2696 return |
| 2684 | 2697 |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3026 | 3039 |
| 3027 Args: | 3040 Args: |
| 3028 filename: The input filename. | 3041 filename: The input filename. |
| 3029 | 3042 |
| 3030 Returns: | 3043 Returns: |
| 3031 The filename with the common suffix removed. | 3044 The filename with the common suffix removed. |
| 3032 """ | 3045 """ |
| 3033 for suffix in ('test.cpp', 'regtest.cpp', 'unittest.cpp', | 3046 for suffix in ('test.cpp', 'regtest.cpp', 'unittest.cpp', |
| 3034 'inl.h', 'impl.h', 'internal.h'): | 3047 'inl.h', 'impl.h', 'internal.h'): |
| 3035 if (filename.endswith(suffix) and len(filename) > len(suffix) | 3048 if (filename.endswith(suffix) and len(filename) > len(suffix) |
| 3036 and filename[-len(suffix) - 1] in ('-', '_')): | 3049 and filename[-len(suffix) - 1] in ('-', '_')): |
| 3037 return filename[:-len(suffix) - 1] | 3050 return filename[:-len(suffix) - 1] |
| 3038 return os.path.splitext(filename)[0] | 3051 return os.path.splitext(filename)[0] |
| 3039 | 3052 |
| 3040 | 3053 |
| 3041 def _classify_include(filename, include, is_system, include_state): | 3054 def _classify_include(filename, include, is_system, include_state): |
| 3042 """Figures out what kind of header 'include' is. | 3055 """Figures out what kind of header 'include' is. |
| 3043 | 3056 |
| 3044 Args: | 3057 Args: |
| 3045 filename: The current file cpp_style is running over. | 3058 filename: The current file cpp_style is running over. |
| 3046 include: The path to a #included file. | 3059 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))\)', | 3283 r'\((int|float|double|bool|char|u?int(16|32|64))\)', |
| 3271 error) | 3284 error) |
| 3272 # This doesn't catch all cases. Consider (const char * const)"hello". | 3285 # 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], | 3286 check_c_style_cast(line_number, line, clean_lines.raw_lines[line_number], |
| 3274 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) | 3287 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) |
| 3275 | 3288 |
| 3276 # In addition, we look for people taking the address of a cast. This | 3289 # 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 | 3290 # is dangerous -- casts can assign to temporaries, so the pointer doesn't |
| 3278 # point where you think. | 3291 # point where you think. |
| 3279 if search( | 3292 if search( |
| 3280 r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line): | 3293 r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line): |
| 3281 error(line_number, 'runtime/casting', 4, | 3294 error(line_number, 'runtime/casting', 4, |
| 3282 ('Are you taking an address of a cast? ' | 3295 ('Are you taking an address of a cast? ' |
| 3283 'This is dangerous: could be a temp var. ' | 3296 'This is dangerous: could be a temp var. ' |
| 3284 'Take the address before doing the cast, rather than after')) | 3297 'Take the address before doing the cast, rather than after')) |
| 3285 | 3298 |
| 3286 # Check for people declaring static/global STL strings at the top level. | 3299 # Check for people declaring static/global STL strings at the top level. |
| 3287 # This is dangerous because the C++ language does not guarantee that | 3300 # This is dangerous because the C++ language does not guarantee that |
| 3288 # globals with constructors are initialized before the first access. | 3301 # globals with constructors are initialized before the first access. |
| 3289 matched = match( | 3302 matched = match( |
| 3290 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', | 3303 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). | 3374 # Check for potential memset bugs like memset(buf, sizeof(buf), 0). |
| 3362 matched = search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) | 3375 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)): | 3376 if matched and not match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", matched.group(2)): |
| 3364 error(line_number, 'runtime/memset', 4, | 3377 error(line_number, 'runtime/memset', 4, |
| 3365 'Did you mean "memset(%s, 0, %s)"?' | 3378 'Did you mean "memset(%s, 0, %s)"?' |
| 3366 % (matched.group(1), matched.group(2))) | 3379 % (matched.group(1), matched.group(2))) |
| 3367 | 3380 |
| 3368 # Detect variable-length arrays. | 3381 # Detect variable-length arrays. |
| 3369 matched = match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) | 3382 matched = match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) |
| 3370 if (matched and matched.group(2) != 'return' and matched.group(2) != 'delete
' and | 3383 if (matched and matched.group(2) != 'return' and matched.group(2) != 'delete
' and |
| 3371 matched.group(3).find(']') == -1): | 3384 matched.group(3).find(']') == -1): |
| 3372 # Split the size using space and arithmetic operators as delimiters. | 3385 # Split the size using space and arithmetic operators as delimiters. |
| 3373 # If any of the resulting tokens are not compile time constants then | 3386 # If any of the resulting tokens are not compile time constants then |
| 3374 # report the error. | 3387 # report the error. |
| 3375 tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', matched.group(3)) | 3388 tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', matched.group(3)) |
| 3376 is_const = True | 3389 is_const = True |
| 3377 skip_next = False | 3390 skip_next = False |
| 3378 for tok in tokens: | 3391 for tok in tokens: |
| 3379 if skip_next: | 3392 if skip_next: |
| 3380 skip_next = False | 3393 skip_next = False |
| 3381 continue | 3394 continue |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3409 break | 3422 break |
| 3410 if not is_const: | 3423 if not is_const: |
| 3411 error(line_number, 'runtime/arrays', 1, | 3424 error(line_number, 'runtime/arrays', 1, |
| 3412 'Do not use variable-length arrays. Use an appropriately name
d ' | 3425 'Do not use variable-length arrays. Use an appropriately name
d ' |
| 3413 "('k' followed by CamelCase) compile-time constant for the siz
e.") | 3426 "('k' followed by CamelCase) compile-time constant for the siz
e.") |
| 3414 | 3427 |
| 3415 # Check for use of unnamed namespaces in header files. Registration | 3428 # Check for use of unnamed namespaces in header files. Registration |
| 3416 # macros are typically OK, so we allow use of "namespace {" on lines | 3429 # macros are typically OK, so we allow use of "namespace {" on lines |
| 3417 # that end with backslashes. | 3430 # that end with backslashes. |
| 3418 if (file_extension == 'h' | 3431 if (file_extension == 'h' |
| 3419 and search(r'\bnamespace\s*{', line) | 3432 and search(r'\bnamespace\s*{', line) |
| 3420 and line[-1] != '\\'): | 3433 and line[-1] != '\\'): |
| 3421 error(line_number, 'build/namespaces', 4, | 3434 error(line_number, 'build/namespaces', 4, |
| 3422 'Do not use unnamed namespaces in header files. See ' | 3435 'Do not use unnamed namespaces in header files. See ' |
| 3423 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Na
mespaces' | 3436 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Na
mespaces' |
| 3424 ' for more information.') | 3437 ' for more information.') |
| 3425 | 3438 |
| 3426 # Check for plain bitfields declared without either "singed" or "unsigned". | 3439 # 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 | 3440 # Most compilers treat such bitfields as signed, but there are still compile
rs like |
| 3428 # RVCT 4.0 that use unsigned by default. | 3441 # RVCT 4.0 that use unsigned by default. |
| 3429 matched = re.match( | 3442 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) | 3443 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 # | 3511 # |
| 3499 # and we will need different treatments for them. | 3512 # and we will need different treatments for them. |
| 3500 line = sub(r'^\s*for\s*\(', '', line) | 3513 line = sub(r'^\s*for\s*\(', '', line) |
| 3501 line, control_statement = subn(r'^\s*(while|else if|if|switch)\s*\(', '', li
ne) | 3514 line, control_statement = subn(r'^\s*(while|else if|if|switch)\s*\(', '', li
ne) |
| 3502 | 3515 |
| 3503 # Detect variable and functions. | 3516 # Detect variable and functions. |
| 3504 type_regexp = r'\w([\w]|\s*[*&]\s*|::)+' | 3517 type_regexp = r'\w([\w]|\s*[*&]\s*|::)+' |
| 3505 identifier_regexp = r'(?P<identifier>[\w:]+)' | 3518 identifier_regexp = r'(?P<identifier>[\w:]+)' |
| 3506 maybe_bitfield_regexp = r'(:\s*\d+\s*)?' | 3519 maybe_bitfield_regexp = r'(:\s*\d+\s*)?' |
| 3507 character_after_identifier_regexp = r'(?P<character_after_identifier>[[;()=,
])(?!=)' | 3520 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 | 3521 declaration_without_type_regexp = r'\s*' + identifier_regexp + \ |
| 3522 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 | 3523 declaration_with_type_regexp = r'\s*' + type_regexp + r'\s' + declaration_wi
thout_type_regexp |
| 3510 is_function_arguments = False | 3524 is_function_arguments = False |
| 3511 number_of_identifiers = 0 | 3525 number_of_identifiers = 0 |
| 3512 while True: | 3526 while True: |
| 3513 # If we are seeing the first identifier or arguments of a | 3527 # If we are seeing the first identifier or arguments of a |
| 3514 # function, there should be a type name before an identifier. | 3528 # function, there should be a type name before an identifier. |
| 3515 if not number_of_identifiers or is_function_arguments: | 3529 if not number_of_identifiers or is_function_arguments: |
| 3516 declaration_regexp = declaration_with_type_regexp | 3530 declaration_regexp = declaration_with_type_regexp |
| 3517 else: | 3531 else: |
| 3518 declaration_regexp = declaration_without_type_regexp | 3532 declaration_regexp = declaration_without_type_regexp |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3529 if control_statement and character_after_identifier != '=': | 3543 if control_statement and character_after_identifier != '=': |
| 3530 return | 3544 return |
| 3531 | 3545 |
| 3532 is_function_arguments = is_function_arguments or character_after_identif
ier == '(' | 3546 is_function_arguments = is_function_arguments or character_after_identif
ier == '(' |
| 3533 | 3547 |
| 3534 # Remove "m_" and "s_" to allow them. | 3548 # Remove "m_" and "s_" to allow them. |
| 3535 modified_identifier = sub(r'(^|(?<=::))[ms]_', '', identifier) | 3549 modified_identifier = sub(r'(^|(?<=::))[ms]_', '', identifier) |
| 3536 if not file_state.is_objective_c() and modified_identifier.find('_') >=
0: | 3550 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. | 3551 # 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) | 3552 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) | 3553 and not (filename.find('gtk') >= 0 and modified_identifier.s
tartswith('webkit_') >= 0) |
| 3540 and not modified_identifier.startswith('tst_') | 3554 and not modified_identifier.startswith('tst_') |
| 3541 and not modified_identifier.startswith('webkit_dom_object_') | 3555 and not modified_identifier.startswith('webkit_dom_object_') |
| 3542 and not modified_identifier.startswith('webkit_soup') | 3556 and not modified_identifier.startswith('webkit_soup') |
| 3543 and not modified_identifier.startswith('NPN_') | 3557 and not modified_identifier.startswith('NPN_') |
| 3544 and not modified_identifier.startswith('NPP_') | 3558 and not modified_identifier.startswith('NPP_') |
| 3545 and not modified_identifier.startswith('NP_') | 3559 and not modified_identifier.startswith('NP_') |
| 3546 and not modified_identifier.startswith('qt_') | 3560 and not modified_identifier.startswith('qt_') |
| 3547 and not modified_identifier.startswith('_q_') | 3561 and not modified_identifier.startswith('_q_') |
| 3548 and not modified_identifier.startswith('cairo_') | 3562 and not modified_identifier.startswith('cairo_') |
| 3549 and not modified_identifier.startswith('Ecore_') | 3563 and not modified_identifier.startswith('Ecore_') |
| 3550 and not modified_identifier.startswith('Eina_') | 3564 and not modified_identifier.startswith('Eina_') |
| 3551 and not modified_identifier.startswith('Evas_') | 3565 and not modified_identifier.startswith('Evas_') |
| 3552 and not modified_identifier.startswith('Ewk_') | 3566 and not modified_identifier.startswith('Ewk_') |
| 3553 and not modified_identifier.startswith('cti_') | 3567 and not modified_identifier.startswith('cti_') |
| 3554 and not modified_identifier.find('::qt_') >= 0 | 3568 and not modified_identifier.find('::qt_') >= 0 |
| 3555 and not modified_identifier.find('::_q_') >= 0 | 3569 and not modified_identifier.find('::_q_') >= 0 |
| 3556 and not modified_identifier == "const_iterator" | 3570 and not modified_identifier == "const_iterator" |
| 3557 and not modified_identifier == "vm_throw" | 3571 and not modified_identifier == "vm_throw" |
| 3558 and not modified_identifier == "DFG_OPERATION"): | 3572 and not modified_identifier == "DFG_OPERATION"): |
| 3559 error(line_number, 'readability/naming/underscores', 4, identifi
er + | 3573 error(line_number, 'readability/naming/underscores', 4, identifi
er + |
| 3560 " is incorrectly named. Don't use underscores in your iden
tifier names.") | 3574 " is incorrectly named. Don't use underscores in your iden
tifier names.") |
| 3561 | 3575 |
| 3562 # Check for variables named 'l', these are too easy to confuse with '1'
in some fonts | 3576 # Check for variables named 'l', these are too easy to confuse with '1'
in some fonts |
| 3563 if modified_identifier == 'l': | 3577 if modified_identifier == 'l': |
| 3564 error(line_number, 'readability/naming', 4, identifier + | 3578 error(line_number, 'readability/naming', 4, identifier + |
| 3565 " is incorrectly named. Don't use the single letter 'l' as an
identifier name.") | 3579 " is incorrectly named. Don't use the single letter 'l' as an
identifier name.") |
| 3566 | 3580 |
| 3567 # There can be only one declaration in non-for-control statements. | 3581 # There can be only one declaration in non-for-control statements. |
| 3568 if control_statement: | 3582 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; | 3763 # eg, void foo(int); or void foo(int) const; |
| 3750 # The equals check is for function pointer assignment. | 3764 # The equals check is for function pointer assignment. |
| 3751 # eg, void *(*foo)(int) = ... | 3765 # eg, void *(*foo)(int) = ... |
| 3752 # | 3766 # |
| 3753 # Right now, this will only catch cases where there's a single argument, and | 3767 # 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 | 3768 # it's unnamed. It should probably be expanded to check for multiple |
| 3755 # arguments with some unnamed. | 3769 # arguments with some unnamed. |
| 3756 function_match = match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder) | 3770 function_match = match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder) |
| 3757 if function_match: | 3771 if function_match: |
| 3758 if (not function_match.group(3) | 3772 if (not function_match.group(3) |
| 3759 or function_match.group(3) == ';' | 3773 or function_match.group(3) == ';' |
| 3760 or raw_line.find('/*') < 0): | 3774 or raw_line.find('/*') < 0): |
| 3761 error(line_number, 'readability/function', 3, | 3775 error(line_number, 'readability/function', 3, |
| 3762 'All parameters should be named in a function') | 3776 'All parameters should be named in a function') |
| 3763 return | 3777 return |
| 3764 | 3778 |
| 3765 # At this point, all that should be left is actual casts. | 3779 # At this point, all that should be left is actual casts. |
| 3766 error(line_number, 'readability/casting', 4, | 3780 error(line_number, 'readability/casting', 4, |
| 3767 'Using C-style cast. Use %s<%s>(...) instead' % | 3781 'Using C-style cast. Use %s<%s>(...) instead' % |
| 3768 (cast_type, matched.group(1))) | 3782 (cast_type, matched.group(1))) |
| 3769 | 3783 |
| 3770 | 3784 |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4210 | 4224 |
| 4211 def check(self, lines): | 4225 def check(self, lines): |
| 4212 _process_lines(self.file_path, self.file_extension, lines, | 4226 _process_lines(self.file_path, self.file_extension, lines, |
| 4213 self.handle_style_error, self.min_confidence) | 4227 self.handle_style_error, self.min_confidence) |
| 4214 | 4228 |
| 4215 | 4229 |
| 4216 # FIXME: Remove this function (requires refactoring unit tests). | 4230 # FIXME: Remove this function (requires refactoring unit tests). |
| 4217 def process_file_data(filename, file_extension, lines, error, min_confidence, fs
=None): | 4231 def process_file_data(filename, file_extension, lines, error, min_confidence, fs
=None): |
| 4218 checker = CppChecker(filename, file_extension, error, min_confidence, fs) | 4232 checker = CppChecker(filename, file_extension, error, min_confidence, fs) |
| 4219 checker.check(lines) | 4233 checker.check(lines) |
| OLD | NEW |