Checks for a C-style cast by looking for the pattern. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. cast_type: The string for the C++ cast to recommend. This is either
(filename, clean_lines, linenum, cast_type, pattern, error)
| 6608 | |
| 6609 | |
| 6610 | def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): |
| 6611 | """Checks for a C-style cast by looking for the pattern. |
| 6612 | |
| 6613 | Args: |
| 6614 | filename: The name of the current file. |
| 6615 | clean_lines: A CleansedLines instance containing the file. |
| 6616 | linenum: The number of the line to check. |
| 6617 | cast_type: The string for the C++ cast to recommend. This is either |
| 6618 | reinterpret_cast, static_cast, or const_cast, depending. |
| 6619 | pattern: The regular expression used to find C-style casts. |
| 6620 | error: The function to call with any errors found. |
| 6621 | |
| 6622 | Returns: |
| 6623 | True if an error was emitted. |
| 6624 | False otherwise. |
| 6625 | """ |
| 6626 | line = clean_lines.elided[linenum] |
| 6627 | match = re.search(pattern, line) |
| 6628 | if not match: |
| 6629 | return False |
| 6630 | |
| 6631 | # Exclude lines with keywords that tend to look like casts |
| 6632 | context = line[0 : match.start(1) - 1] |
| 6633 | if re.match(r".*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$", context): |
| 6634 | return False |
| 6635 | |
| 6636 | # Try expanding current context to see if we one level of |
| 6637 | # parentheses inside a macro. |
| 6638 | if linenum > 0: |
| 6639 | for i in range(linenum - 1, max(0, linenum - 5), -1): |
| 6640 | context = clean_lines.elided[i] + context |
| 6641 | if re.match(r".*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$", context): |
| 6642 | return False |
| 6643 | |
| 6644 | # operator++(int) and operator--(int) |
| 6645 | if context.endswith((" operator++", " operator--", "::operator++", "::operator--")): |
| 6646 | return False |
| 6647 | |
| 6648 | # A single unnamed argument for a function tends to look like old style cast. |
| 6649 | # If we see those, don't issue warnings for deprecated casts. |
| 6650 | remainder = line[match.end(0) :] |
| 6651 | if re.match(r"^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)", remainder): |
| 6652 | return False |
| 6653 | |
| 6654 | # At this point, all that should be left is actual casts. |
| 6655 | error( |
| 6656 | filename, |
| 6657 | linenum, |
| 6658 | "readability/casting", |
| 6659 | 4, |
| 6660 | f"Using C-style cast. Use {cast_type}<{match.group(1)}>(...) instead", |
| 6661 | ) |
| 6662 | |
| 6663 | return True |
| 6664 | |
| 6665 | |
| 6666 | def ExpectingFunctionArgs(clean_lines, linenum): |