@@ 5426-5476 (lines=51) @@ | ||
5423 | 'Take the address before doing the cast, rather than after')) |
|
5424 | ||
5425 | ||
5426 | def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): |
|
5427 | """Checks for a C-style cast by looking for the pattern. |
|
5428 | ||
5429 | Args: |
|
5430 | filename: The name of the current file. |
|
5431 | clean_lines: A CleansedLines instance containing the file. |
|
5432 | linenum: The number of the line to check. |
|
5433 | cast_type: The string for the C++ cast to recommend. This is either |
|
5434 | reinterpret_cast, static_cast, or const_cast, depending. |
|
5435 | pattern: The regular expression used to find C-style casts. |
|
5436 | error: The function to call with any errors found. |
|
5437 | ||
5438 | Returns: |
|
5439 | True if an error was emitted. |
|
5440 | False otherwise. |
|
5441 | """ |
|
5442 | line = clean_lines.elided[linenum] |
|
5443 | match = Search(pattern, line) |
|
5444 | if not match: |
|
5445 | return False |
|
5446 | ||
5447 | # Exclude lines with keywords that tend to look like casts |
|
5448 | context = line[0:match.start(1) - 1] |
|
5449 | if Match(r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$', context): |
|
5450 | return False |
|
5451 | ||
5452 | # Try expanding current context to see if we one level of |
|
5453 | # parentheses inside a macro. |
|
5454 | if linenum > 0: |
|
5455 | for i in xrange(linenum - 1, max(0, linenum - 5), -1): |
|
5456 | context = clean_lines.elided[i] + context |
|
5457 | if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): |
|
5458 | return False |
|
5459 | ||
5460 | # operator++(int) and operator--(int) |
|
5461 | if context.endswith(' operator++') or context.endswith(' operator--'): |
|
5462 | return False |
|
5463 | ||
5464 | # A single unnamed argument for a function tends to look like old style cast. |
|
5465 | # If we see those, don't issue warnings for deprecated casts. |
|
5466 | remainder = line[match.end(0):] |
|
5467 | if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', |
|
5468 | remainder): |
|
5469 | return False |
|
5470 | ||
5471 | # At this point, all that should be left is actual casts. |
|
5472 | error(filename, linenum, 'readability/casting', 4, |
|
5473 | 'Using C-style cast. Use %s<%s>(...) instead' % |
|
5474 | (cast_type, match.group(1))) |
|
5475 | ||
5476 | return True |
|
5477 | ||
5478 | ||
5479 | def ExpectingFunctionArgs(clean_lines, linenum): |
@@ 5426-5476 (lines=51) @@ | ||
5423 | 'Take the address before doing the cast, rather than after')) |
|
5424 | ||
5425 | ||
5426 | def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): |
|
5427 | """Checks for a C-style cast by looking for the pattern. |
|
5428 | ||
5429 | Args: |
|
5430 | filename: The name of the current file. |
|
5431 | clean_lines: A CleansedLines instance containing the file. |
|
5432 | linenum: The number of the line to check. |
|
5433 | cast_type: The string for the C++ cast to recommend. This is either |
|
5434 | reinterpret_cast, static_cast, or const_cast, depending. |
|
5435 | pattern: The regular expression used to find C-style casts. |
|
5436 | error: The function to call with any errors found. |
|
5437 | ||
5438 | Returns: |
|
5439 | True if an error was emitted. |
|
5440 | False otherwise. |
|
5441 | """ |
|
5442 | line = clean_lines.elided[linenum] |
|
5443 | match = Search(pattern, line) |
|
5444 | if not match: |
|
5445 | return False |
|
5446 | ||
5447 | # Exclude lines with keywords that tend to look like casts |
|
5448 | context = line[0:match.start(1) - 1] |
|
5449 | if Match(r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$', context): |
|
5450 | return False |
|
5451 | ||
5452 | # Try expanding current context to see if we one level of |
|
5453 | # parentheses inside a macro. |
|
5454 | if linenum > 0: |
|
5455 | for i in xrange(linenum - 1, max(0, linenum - 5), -1): |
|
5456 | context = clean_lines.elided[i] + context |
|
5457 | if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): |
|
5458 | return False |
|
5459 | ||
5460 | # operator++(int) and operator--(int) |
|
5461 | if context.endswith(' operator++') or context.endswith(' operator--'): |
|
5462 | return False |
|
5463 | ||
5464 | # A single unnamed argument for a function tends to look like old style cast. |
|
5465 | # If we see those, don't issue warnings for deprecated casts. |
|
5466 | remainder = line[match.end(0):] |
|
5467 | if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', |
|
5468 | remainder): |
|
5469 | return False |
|
5470 | ||
5471 | # At this point, all that should be left is actual casts. |
|
5472 | error(filename, linenum, 'readability/casting', 4, |
|
5473 | 'Using C-style cast. Use %s<%s>(...) instead' % |
|
5474 | (cast_type, match.group(1))) |
|
5475 | ||
5476 | return True |
|
5477 | ||
5478 | ||
5479 | def ExpectingFunctionArgs(clean_lines, linenum): |