| 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 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 | 682 |
| 683 Returns: | 683 Returns: |
| 684 True, if next character appended to 'line' is inside a | 684 True, if next character appended to 'line' is inside a |
| 685 string constant. | 685 string constant. |
| 686 """ | 686 """ |
| 687 | 687 |
| 688 line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" | 688 line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" |
| 689 return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 | 689 return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 |
| 690 | 690 |
| 691 | 691 |
| 692 def cleanse_raw_strings(raw_lines): |
| 693 """Removes C++11 raw strings from lines. |
| 694 |
| 695 Before: |
| 696 static const char kData[] = R"( |
| 697 multi-line string |
| 698 )"; |
| 699 |
| 700 After: |
| 701 static const char kData[] = "" |
| 702 (replaced by blank line) |
| 703 ""; |
| 704 |
| 705 Args: |
| 706 raw_lines: list of raw lines. |
| 707 |
| 708 Returns: |
| 709 list of lines with C++11 raw strings replaced by empty strings. |
| 710 """ |
| 711 |
| 712 delimiter = None |
| 713 lines_without_raw_strings = [] |
| 714 for line in raw_lines: |
| 715 if delimiter: |
| 716 # Inside a raw string, look for the end |
| 717 end = line.find(delimiter) |
| 718 if end >= 0: |
| 719 # Found the end of the string, match leading space for this |
| 720 # line and resume copying the original lines, and also insert |
| 721 # a "" on the last line. |
| 722 leading_space = match(r'^(\s*)\S', line) |
| 723 line = leading_space.group(1) + '""' + line[end + len(delimiter)
:] |
| 724 delimiter = None |
| 725 else: |
| 726 # Haven't found the end yet, append a blank line. |
| 727 line = '""' |
| 728 |
| 729 # Look for beginning of a raw string, and replace them with |
| 730 # empty strings. This is done in a loop to handle multiple raw |
| 731 # strings on the same line. |
| 732 while delimiter is None: |
| 733 # Look for beginning of a raw string. |
| 734 # See 2.14.15 [lex.string] for syntax. |
| 735 # |
| 736 # Once we have matched a raw string, we check the prefix of the |
| 737 # line to make sure that the line is not part of a single line |
| 738 # comment. It's done this way because we remove raw strings |
| 739 # before removing comments as opposed to removing comments |
| 740 # before removing raw strings. This is because there are some |
| 741 # cpplint checks that requires the comments to be preserved, but |
| 742 # we don't want to check comments that are inside raw strings. |
| 743 matched = match(r'^(.*?)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', l
ine) |
| 744 if matched and not match(r'^([^\'"]|\'(\\.|[^\'])*\'|"(\\.|[^"])*")*
//', matched.group(1)): |
| 745 delimiter = ')' + matched.group(2) + '"' |
| 746 |
| 747 end = matched.group(3).find(delimiter) |
| 748 if end >= 0: |
| 749 # Raw string ended on same line |
| 750 line = (matched.group(1) + '""' + |
| 751 matched.group(3)[end + len(delimiter):]) |
| 752 delimiter = None |
| 753 else: |
| 754 # Start of a multi-line raw string |
| 755 line = matched.group(1) + '""' |
| 756 else: |
| 757 break |
| 758 |
| 759 lines_without_raw_strings.append(line) |
| 760 |
| 761 # TODO(unknown): if delimiter is not None here, we might want to |
| 762 # emit a warning for unterminated string. |
| 763 return lines_without_raw_strings |
| 764 |
| 765 |
| 692 def find_next_multi_line_comment_start(lines, line_index): | 766 def find_next_multi_line_comment_start(lines, line_index): |
| 693 """Find the beginning marker for a multiline comment.""" | 767 """Find the beginning marker for a multiline comment.""" |
| 694 while line_index < len(lines): | 768 while line_index < len(lines): |
| 695 if lines[line_index].strip().startswith('/*'): | 769 if lines[line_index].strip().startswith('/*'): |
| 696 # Only return this marker if the comment goes beyond this line | 770 # Only return this marker if the comment goes beyond this line |
| 697 if lines[line_index].strip().find('*/', 2) < 0: | 771 if lines[line_index].strip().find('*/', 2) < 0: |
| 698 return line_index | 772 return line_index |
| 699 line_index += 1 | 773 line_index += 1 |
| 700 return len(lines) | 774 return len(lines) |
| 701 | 775 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 The line with single-line comments removed. | 817 The line with single-line comments removed. |
| 744 """ | 818 """ |
| 745 comment_position = line.find('//') | 819 comment_position = line.find('//') |
| 746 if comment_position != -1 and not is_cpp_string(line[:comment_position]): | 820 if comment_position != -1 and not is_cpp_string(line[:comment_position]): |
| 747 line = line[:comment_position] | 821 line = line[:comment_position] |
| 748 # get rid of /* ... */ | 822 # get rid of /* ... */ |
| 749 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) | 823 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) |
| 750 | 824 |
| 751 | 825 |
| 752 class CleansedLines(object): | 826 class CleansedLines(object): |
| 753 """Holds 3 copies of all lines with different preprocessing applied to them. | 827 """Holds 4 copies of all lines with different preprocessing applied to them. |
| 754 | 828 |
| 755 1) elided member contains lines without strings and comments, | 829 1) elided member contains lines without strings and comments. |
| 756 2) lines member contains lines without comments, and | 830 2) lines member contains lines without comments. |
| 757 3) raw member contains all the lines without processing. | 831 3) raw_lines member contains all the lines without processing. |
| 758 All these three members are of <type 'list'>, and of the same length. | 832 4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw |
| 833 strings removed. |
| 834 All these members are of <type 'list'>, and of the same length. |
| 759 """ | 835 """ |
| 760 | 836 |
| 761 def __init__(self, lines): | 837 def __init__(self, lines): |
| 762 self.elided = [] | 838 self.elided = [] |
| 763 self.lines = [] | 839 self.lines = [] |
| 764 self.raw_lines = lines | 840 self.raw_lines = lines |
| 765 self._num_lines = len(lines) | 841 self._num_lines = len(lines) |
| 766 for line_number in range(len(lines)): | 842 self.lines_without_raw_strings = cleanse_raw_strings(lines) |
| 767 self.lines.append(cleanse_comments(lines[line_number])) | 843 for line_number in range(len(self.lines_without_raw_strings)): |
| 768 elided = self.collapse_strings(lines[line_number]) | 844 self.lines.append(cleanse_comments(self.lines_without_raw_strings[li
ne_number])) |
| 845 elided = self.collapse_strings(self.lines_without_raw_strings[line_n
umber]) |
| 769 self.elided.append(cleanse_comments(elided)) | 846 self.elided.append(cleanse_comments(elided)) |
| 770 | 847 |
| 771 def num_lines(self): | 848 def num_lines(self): |
| 772 """Returns the number of lines represented.""" | 849 """Returns the number of lines represented.""" |
| 773 return self._num_lines | 850 return self._num_lines |
| 774 | 851 |
| 775 @staticmethod | 852 @staticmethod |
| 776 def collapse_strings(elided): | 853 def collapse_strings(elided): |
| 777 """Collapses strings and chars on a line to simple "" or '' blocks. | 854 """Collapses strings and chars on a line to simple "" or '' blocks. |
| 778 | 855 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 | 986 |
| 910 # If it's a full path and starts with Source/, replace Source with blink | 987 # If it's a full path and starts with Source/, replace Source with blink |
| 911 # since that will be the new style directory. | 988 # since that will be the new style directory. |
| 912 filename = sub(r'^Source\/', 'blink/', filename) | 989 filename = sub(r'^Source\/', 'blink/', filename) |
| 913 | 990 |
| 914 standard_name = sub(r'[-.\s\/]', '_', filename).upper() + '_' | 991 standard_name = sub(r'[-.\s\/]', '_', filename).upper() + '_' |
| 915 | 992 |
| 916 return standard_name | 993 return standard_name |
| 917 | 994 |
| 918 | 995 |
| 919 def check_for_header_guard(filename, lines, error): | 996 def check_for_header_guard(filename, clean_lines, error): |
| 920 """Checks that the file contains a header guard. | 997 """Checks that the file contains a header guard. |
| 921 | 998 |
| 922 Logs an error if no #ifndef header guard is present. For other | 999 Logs an error if no #ifndef header guard is present. For other |
| 923 headers, checks that the full pathname is used. | 1000 headers, checks that the full pathname is used. |
| 924 | 1001 |
| 925 Args: | 1002 Args: |
| 926 filename: The name of the C++ header file. | 1003 filename: The name of the C++ header file. |
| 927 lines: An array of strings, each representing a line of the file. | 1004 lines: An array of strings, each representing a line of the file. |
| 928 error: The function to call with any errors found. | 1005 error: The function to call with any errors found. |
| 929 """ | 1006 """ |
| 1007 raw_lines = clean_lines.lines_without_raw_strings |
| 930 | 1008 |
| 931 legacy_cpp_var = get_legacy_header_guard_cpp_variable(filename) | 1009 legacy_cpp_var = get_legacy_header_guard_cpp_variable(filename) |
| 932 cpp_var = get_header_guard_cpp_variable(filename) | 1010 cpp_var = get_header_guard_cpp_variable(filename) |
| 933 | 1011 |
| 934 ifndef = None | 1012 ifndef = None |
| 935 ifndef_line_number = 0 | 1013 ifndef_line_number = 0 |
| 936 define = None | 1014 define = None |
| 937 for line_number, line in enumerate(lines): | 1015 for line_number, line in enumerate(raw_lines): |
| 938 line_split = line.split() | 1016 line_split = line.split() |
| 939 if len(line_split) >= 2: | 1017 if len(line_split) >= 2: |
| 940 # find the first occurrence of #ifndef and #define, save arg | 1018 # find the first occurrence of #ifndef and #define, save arg |
| 941 if not ifndef and line_split[0] == '#ifndef': | 1019 if not ifndef and line_split[0] == '#ifndef': |
| 942 # set ifndef to the header guard presented on the #ifndef line. | 1020 # set ifndef to the header guard presented on the #ifndef line. |
| 943 ifndef = line_split[1] | 1021 ifndef = line_split[1] |
| 944 ifndef_line_number = line_number | 1022 ifndef_line_number = line_number |
| 945 if not define and line_split[0] == '#define': | 1023 if not define and line_split[0] == '#define': |
| 946 define = line_split[1] | 1024 define = line_split[1] |
| 947 if define and ifndef: | 1025 if define and ifndef: |
| (...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1697 line, don't end a function with a blank line, don't have too many | 1775 line, don't end a function with a blank line, don't have too many |
| 1698 blank lines in a row. | 1776 blank lines in a row. |
| 1699 | 1777 |
| 1700 Args: | 1778 Args: |
| 1701 file_extension: The current file extension, without the leading dot. | 1779 file_extension: The current file extension, without the leading dot. |
| 1702 clean_lines: A CleansedLines instance containing the file. | 1780 clean_lines: A CleansedLines instance containing the file. |
| 1703 line_number: The number of the line to check. | 1781 line_number: The number of the line to check. |
| 1704 error: The function to call with any errors found. | 1782 error: The function to call with any errors found. |
| 1705 """ | 1783 """ |
| 1706 | 1784 |
| 1707 line = clean_lines.elided[line_number] # get rid of comments and strings | 1785 # Don't use "elided" lines here, otherwise we can't check commented lines. |
| 1786 # Don't want to use "raw" either, because we don't want to check inside C++1
1 |
| 1787 # raw strings, |
| 1788 raw = clean_lines.lines_without_raw_strings |
| 1789 line = raw[line_number] |
| 1708 | 1790 |
| 1709 # You shouldn't have a space before a semicolon at the end of the line. | 1791 # You shouldn't have a space before a semicolon at the end of the line. |
| 1710 # There's a special case for "for" since the style guide allows space before | 1792 # There's a special case for "for" since the style guide allows space before |
| 1711 # the semicolon there. | 1793 # the semicolon there. |
| 1712 if search(r':\s*;\s*$', line): | 1794 if search(r':\s*;\s*$', line): |
| 1713 error(line_number, 'whitespace/semicolon', 5, | 1795 error(line_number, 'whitespace/semicolon', 5, |
| 1714 'Semicolon defining empty statement. Use { } instead.') | 1796 'Semicolon defining empty statement. Use { } instead.') |
| 1715 elif search(r'^\s*;\s*$', line): | 1797 elif search(r'^\s*;\s*$', line): |
| 1716 error(line_number, 'whitespace/semicolon', 5, | 1798 error(line_number, 'whitespace/semicolon', 5, |
| 1717 'Line contains only semicolon. If this should be an empty statemen
t, ' | 1799 'Line contains only semicolon. If this should be an empty statemen
t, ' |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2344 line_number: The number of the line to check. | 2426 line_number: The number of the line to check. |
| 2345 file_extension: The extension (without the dot) of the filename. | 2427 file_extension: The extension (without the dot) of the filename. |
| 2346 class_state: A _ClassState instance which maintains information about | 2428 class_state: A _ClassState instance which maintains information about |
| 2347 the current stack of nested class declarations being parsed. | 2429 the current stack of nested class declarations being parsed. |
| 2348 file_state: A _FileState instance which maintains information about | 2430 file_state: A _FileState instance which maintains information about |
| 2349 the state of things in the file. | 2431 the state of things in the file. |
| 2350 enum_state: A _EnumState instance which maintains the current enum state. | 2432 enum_state: A _EnumState instance which maintains the current enum state. |
| 2351 error: The function to call with any errors found. | 2433 error: The function to call with any errors found. |
| 2352 """ | 2434 """ |
| 2353 | 2435 |
| 2354 raw_lines = clean_lines.raw_lines | 2436 # Don't use "elided" lines here, otherwise we can't check commented lines. |
| 2437 # Don't want to use "raw" either, because we don't want to check inside C++1
1 |
| 2438 # raw strings, |
| 2439 raw_lines = clean_lines.lines_without_raw_strings |
| 2355 line = raw_lines[line_number] | 2440 line = raw_lines[line_number] |
| 2356 | 2441 |
| 2357 # Some more style checks | 2442 # Some more style checks |
| 2358 check_using_std(clean_lines, line_number, file_state, error) | 2443 check_using_std(clean_lines, line_number, file_state, error) |
| 2359 check_max_min_macros(clean_lines, line_number, file_state, error) | 2444 check_max_min_macros(clean_lines, line_number, file_state, error) |
| 2360 check_ctype_functions(clean_lines, line_number, file_state, error) | 2445 check_ctype_functions(clean_lines, line_number, file_state, error) |
| 2361 check_braces(clean_lines, line_number, error) | 2446 check_braces(clean_lines, line_number, error) |
| 2362 check_exit_statement_simplifications(clean_lines, line_number, error) | 2447 check_exit_statement_simplifications(clean_lines, line_number, error) |
| 2363 check_spacing(file_extension, clean_lines, line_number, error) | 2448 check_spacing(file_extension, clean_lines, line_number, error) |
| 2364 check_check(clean_lines, line_number, error) | 2449 check_check(clean_lines, line_number, error) |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3271 error: A callable to which errors are reported, which takes 4 arguments: | 3356 error: A callable to which errors are reported, which takes 4 arguments: |
| 3272 """ | 3357 """ |
| 3273 lines = (['// marker so line numbers and indices both start at 1'] + lines + | 3358 lines = (['// marker so line numbers and indices both start at 1'] + lines + |
| 3274 ['// marker so line numbers end in a known way']) | 3359 ['// marker so line numbers end in a known way']) |
| 3275 | 3360 |
| 3276 include_state = _IncludeState() | 3361 include_state = _IncludeState() |
| 3277 function_state = _FunctionState(min_confidence) | 3362 function_state = _FunctionState(min_confidence) |
| 3278 class_state = _ClassState() | 3363 class_state = _ClassState() |
| 3279 | 3364 |
| 3280 check_for_copyright(lines, error) | 3365 check_for_copyright(lines, error) |
| 3366 remove_multi_line_comments(lines, error) |
| 3367 clean_lines = CleansedLines(lines) |
| 3281 | 3368 |
| 3282 if file_extension == 'h': | 3369 if file_extension == 'h': |
| 3283 check_for_header_guard(filename, lines, error) | 3370 check_for_header_guard(filename, clean_lines, error) |
| 3284 | 3371 |
| 3285 remove_multi_line_comments(lines, error) | |
| 3286 clean_lines = CleansedLines(lines) | |
| 3287 file_state = _FileState(clean_lines, file_extension) | 3372 file_state = _FileState(clean_lines, file_extension) |
| 3288 enum_state = _EnumState() | 3373 enum_state = _EnumState() |
| 3289 for line in xrange(clean_lines.num_lines()): | 3374 for line in xrange(clean_lines.num_lines()): |
| 3290 process_line(filename, file_extension, clean_lines, line, | 3375 process_line(filename, file_extension, clean_lines, line, |
| 3291 include_state, function_state, class_state, file_state, | 3376 include_state, function_state, class_state, file_state, |
| 3292 enum_state, error) | 3377 enum_state, error) |
| 3293 class_state.check_finished(error) | 3378 class_state.check_finished(error) |
| 3294 | 3379 |
| 3295 check_for_include_what_you_use(filename, clean_lines, include_state, error) | 3380 check_for_include_what_you_use(filename, clean_lines, include_state, error) |
| 3296 | 3381 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3410 | 3495 |
| 3411 def check(self, lines): | 3496 def check(self, lines): |
| 3412 _process_lines(self.file_path, self.file_extension, lines, | 3497 _process_lines(self.file_path, self.file_extension, lines, |
| 3413 self.handle_style_error, self.min_confidence) | 3498 self.handle_style_error, self.min_confidence) |
| 3414 | 3499 |
| 3415 | 3500 |
| 3416 # FIXME: Remove this function (requires refactoring unit tests). | 3501 # FIXME: Remove this function (requires refactoring unit tests). |
| 3417 def process_file_data(filename, file_extension, lines, error, min_confidence, fs
=None): | 3502 def process_file_data(filename, file_extension, lines, error, min_confidence, fs
=None): |
| 3418 checker = CppChecker(filename, file_extension, error, min_confidence, fs) | 3503 checker = CppChecker(filename, file_extension, error, min_confidence, fs) |
| 3419 checker.check(lines) | 3504 checker.check(lines) |
| OLD | NEW |