| OLD | NEW |
| 1 #!/usr/bin/python2.4 | 1 #!/usr/bin/python2.4 |
| 2 # | 2 # |
| 3 # Copyright (c) 2009 Google Inc. All rights reserved. | 3 # Copyright (c) 2009 Google Inc. All rights reserved. |
| 4 # | 4 # |
| 5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
| 6 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
| 7 # met: | 7 # met: |
| 8 # | 8 # |
| 9 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
| 10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 [--counting=total|toplevel|detailed] | 95 [--counting=total|toplevel|detailed] |
| 96 <file> [file] ... | 96 <file> [file] ... |
| 97 | 97 |
| 98 The style guidelines this tries to follow are those in | 98 The style guidelines this tries to follow are those in |
| 99 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml | 99 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml |
| 100 | 100 |
| 101 Every problem is given a confidence score from 1-5, with 5 meaning we are | 101 Every problem is given a confidence score from 1-5, with 5 meaning we are |
| 102 certain of the problem, and 1 meaning it could be a legitimate construct. | 102 certain of the problem, and 1 meaning it could be a legitimate construct. |
| 103 This will miss some errors, and is not a substitute for a code review. | 103 This will miss some errors, and is not a substitute for a code review. |
| 104 | 104 |
| 105 To prevent specific lines from being linted, add a '// NOLINT' comment to the | 105 To suppress false-positive errors of a certain category, add a |
| 106 end of the line. | 106 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) |
| 107 suppresses errors of all categories on that line. |
| 107 | 108 |
| 108 The files passed in will be linted; at least one file must be provided. | 109 The files passed in will be linted; at least one file must be provided. |
| 109 Linted extensions are .cc, .cpp, and .h. Other file types will be ignored. | 110 Linted extensions are .cc, .cpp, and .h. Other file types will be ignored. |
| 110 | 111 |
| 111 Flags: | 112 Flags: |
| 112 | 113 |
| 113 output=vs7 | 114 output=vs7 |
| 114 By default, the output is formatted to ease emacs parsing. Visual Studio | 115 By default, the output is formatted to ease emacs parsing. Visual Studio |
| 115 compatible output (vs7) may also be used. Other formats are unsupported. | 116 compatible output (vs7) may also be used. Other formats are unsupported. |
| 116 | 117 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 138 the top-level categories like 'build' and 'whitespace' will | 139 the top-level categories like 'build' and 'whitespace' will |
| 139 also be printed. If 'detailed' is provided, then a count | 140 also be printed. If 'detailed' is provided, then a count |
| 140 is provided for each category like 'build/class'. | 141 is provided for each category like 'build/class'. |
| 141 """ | 142 """ |
| 142 | 143 |
| 143 # We categorize each error message we print. Here are the categories. | 144 # We categorize each error message we print. Here are the categories. |
| 144 # We want an explicit list so we can list them all in cpplint --filter=. | 145 # We want an explicit list so we can list them all in cpplint --filter=. |
| 145 # If you add a new error message with a new category, add it to the list | 146 # If you add a new error message with a new category, add it to the list |
| 146 # here! cpplint_unittest.py should tell you if you forget to do this. | 147 # here! cpplint_unittest.py should tell you if you forget to do this. |
| 147 # \ used for clearer layout -- pylint: disable-msg=C6013 | 148 # \ used for clearer layout -- pylint: disable-msg=C6013 |
| 148 _ERROR_CATEGORIES = '''\ | 149 _ERROR_CATEGORIES = [ |
| 149 build/class | 150 'build/class', |
| 150 build/deprecated | 151 'build/deprecated', |
| 151 build/endif_comment | 152 'build/endif_comment', |
| 152 build/forward_decl | 153 'build/forward_decl', |
| 153 build/header_guard | 154 'build/header_guard', |
| 154 build/include | 155 'build/include', |
| 155 build/include_alpha | 156 'build/include_alpha', |
| 156 build/include_order | 157 'build/include_order', |
| 157 build/include_what_you_use | 158 'build/include_what_you_use', |
| 158 build/namespaces | 159 'build/namespaces', |
| 159 build/printf_format | 160 'build/printf_format', |
| 160 build/storage_class | 161 'build/storage_class', |
| 161 legal/copyright | 162 'legal/copyright', |
| 162 readability/braces | 163 'readability/braces', |
| 163 readability/casting | 164 'readability/casting', |
| 164 readability/check | 165 'readability/check', |
| 165 readability/constructors | 166 'readability/constructors', |
| 166 readability/fn_size | 167 'readability/fn_size', |
| 167 readability/function | 168 'readability/function', |
| 168 readability/multiline_comment | 169 'readability/multiline_comment', |
| 169 readability/multiline_string | 170 'readability/multiline_string', |
| 170 readability/streams | 171 'readability/nolint', |
| 171 readability/todo | 172 'readability/streams', |
| 172 readability/utf8 | 173 'readability/todo', |
| 173 runtime/arrays | 174 'readability/utf8', |
| 174 runtime/casting | 175 'runtime/arrays', |
| 175 runtime/explicit | 176 'runtime/casting', |
| 176 runtime/int | 177 'runtime/explicit', |
| 177 runtime/init | 178 'runtime/int', |
| 178 runtime/invalid_increment | 179 'runtime/init', |
| 179 runtime/member_string_references | 180 'runtime/invalid_increment', |
| 180 runtime/memset | 181 'runtime/member_string_references', |
| 181 runtime/operator | 182 'runtime/memset', |
| 182 runtime/printf | 183 'runtime/operator', |
| 183 runtime/printf_format | 184 'runtime/printf', |
| 184 runtime/references | 185 'runtime/printf_format', |
| 185 runtime/rtti | 186 'runtime/references', |
| 186 runtime/sizeof | 187 'runtime/rtti', |
| 187 runtime/string | 188 'runtime/sizeof', |
| 188 runtime/threadsafe_fn | 189 'runtime/string', |
| 189 runtime/virtual | 190 'runtime/threadsafe_fn', |
| 190 whitespace/blank_line | 191 'runtime/virtual', |
| 191 whitespace/braces | 192 'whitespace/blank_line', |
| 192 whitespace/comma | 193 'whitespace/braces', |
| 193 whitespace/comments | 194 'whitespace/comma', |
| 194 whitespace/end_of_line | 195 'whitespace/comments', |
| 195 whitespace/ending_newline | 196 'whitespace/end_of_line', |
| 196 whitespace/indent | 197 'whitespace/ending_newline', |
| 197 whitespace/labels | 198 'whitespace/indent', |
| 198 whitespace/line_length | 199 'whitespace/labels', |
| 199 whitespace/newline | 200 'whitespace/line_length', |
| 200 whitespace/operators | 201 'whitespace/newline', |
| 201 whitespace/parens | 202 'whitespace/operators', |
| 202 whitespace/semicolon | 203 'whitespace/parens', |
| 203 whitespace/tab | 204 'whitespace/semicolon', |
| 204 whitespace/todo | 205 'whitespace/tab', |
| 205 ''' | 206 'whitespace/todo' |
| 207 ] |
| 206 | 208 |
| 207 # The default state of the category filter. This is overrided by the --filter= | 209 # The default state of the category filter. This is overrided by the --filter= |
| 208 # flag. By default all errors are on, so only add here categories that should be | 210 # flag. By default all errors are on, so only add here categories that should be |
| 209 # off by default (i.e., categories that must be enabled by the --filter= flags). | 211 # off by default (i.e., categories that must be enabled by the --filter= flags). |
| 210 # All entries here should start with a '-' or '+', as in the --filter= flag. | 212 # All entries here should start with a '-' or '+', as in the --filter= flag. |
| 211 _DEFAULT_FILTERS = [ '-build/include_alpha' ] | 213 _DEFAULT_FILTERS = [ '-build/include_alpha' ] |
| 212 | 214 |
| 213 # We used to check for high-bit characters, but after much discussion we | 215 # We used to check for high-bit characters, but after much discussion we |
| 214 # decided those were OK, as long as they were in UTF-8 and didn't represent | 216 # decided those were OK, as long as they were in UTF-8 and didn't represent |
| 215 # hard-coded international strings, which belong in a seperate i18n file. | 217 # hard-coded international strings, which belong in a seperate i18n file. |
| 216 | 218 |
| 217 # Headers that we consider STL headers. | 219 # Headers that we consider STL headers. |
| 218 _STL_HEADERS = frozenset([ | 220 _STL_HEADERS = frozenset([ |
| 219 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', | 221 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', |
| 220 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', | 222 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', |
| 221 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h', | 223 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'new', |
| 222 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack', | 224 'pair.h', 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack', |
| 223 'stl_alloc.h', 'stl_relops.h', 'type_traits.h', | 225 'stl_alloc.h', 'stl_relops.h', 'type_traits.h', |
| 224 'utility', 'vector', 'vector.h', | 226 'utility', 'vector', 'vector.h', |
| 225 ]) | 227 ]) |
| 226 | 228 |
| 227 | 229 |
| 228 # Non-STL C++ system headers. | 230 # Non-STL C++ system headers. |
| 229 _CPP_HEADERS = frozenset([ | 231 _CPP_HEADERS = frozenset([ |
| 230 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype', | 232 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype', |
| 231 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath', | 233 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath', |
| 232 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef', | 234 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef', |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 # _IncludeState.CheckNextIncludeOrder(). | 282 # _IncludeState.CheckNextIncludeOrder(). |
| 281 _C_SYS_HEADER = 1 | 283 _C_SYS_HEADER = 1 |
| 282 _CPP_SYS_HEADER = 2 | 284 _CPP_SYS_HEADER = 2 |
| 283 _LIKELY_MY_HEADER = 3 | 285 _LIKELY_MY_HEADER = 3 |
| 284 _POSSIBLE_MY_HEADER = 4 | 286 _POSSIBLE_MY_HEADER = 4 |
| 285 _OTHER_HEADER = 5 | 287 _OTHER_HEADER = 5 |
| 286 | 288 |
| 287 | 289 |
| 288 _regexp_compile_cache = {} | 290 _regexp_compile_cache = {} |
| 289 | 291 |
| 292 # Finds occurrences of NOLINT or NOLINT(...). |
| 293 _RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?') |
| 294 |
| 295 # {str, set(int)}: a map from error categories to sets of linenumbers |
| 296 # on which those errors are expected and should be suppressed. |
| 297 _error_suppressions = {} |
| 298 |
| 299 def ParseNolintSuppressions(filename, raw_line, linenum, error): |
| 300 """Updates the global list of error-suppressions. |
| 301 |
| 302 Parses any NOLINT comments on the current line, updating the global |
| 303 error_suppressions store. Reports an error if the NOLINT comment |
| 304 was malformed. |
| 305 |
| 306 Args: |
| 307 filename: str, the name of the input file. |
| 308 raw_line: str, the line of input text, with comments. |
| 309 linenum: int, the number of the current line. |
| 310 error: function, an error handler. |
| 311 """ |
| 312 # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*). |
| 313 m = _RE_SUPPRESSION.search(raw_line) |
| 314 if m: |
| 315 category = m.group(1) |
| 316 if category in (None, '(*)'): # => "suppress all" |
| 317 _error_suppressions.setdefault(None, set()).add(linenum) |
| 318 else: |
| 319 if category.startswith('(') and category.endswith(')'): |
| 320 category = category[1:-1] |
| 321 if category in _ERROR_CATEGORIES: |
| 322 _error_suppressions.setdefault(category, set()).add(linenum) |
| 323 else: |
| 324 error(filename, linenum, 'readability/nolint', 5, |
| 325 'Unknown NOLINT error category: %s' % category) |
| 326 |
| 327 |
| 328 def ResetNolintSuppressions(): |
| 329 "Resets the set of NOLINT suppressions to empty." |
| 330 _error_suppressions.clear() |
| 331 |
| 332 |
| 333 def IsErrorSuppressedByNolint(category, linenum): |
| 334 """Returns true if the specified error category is suppressed on this line. |
| 335 |
| 336 Consults the global error_suppressions map populated by |
| 337 ParseNolintSuppressions/ResetNolintSuppressions. |
| 338 |
| 339 Args: |
| 340 category: str, the category of the error. |
| 341 linenum: int, the current line number. |
| 342 Returns: |
| 343 bool, True iff the error should be suppressed due to a NOLINT comment. |
| 344 """ |
| 345 return (linenum in _error_suppressions.get(category, set()) or |
| 346 linenum in _error_suppressions.get(None, set())) |
| 290 | 347 |
| 291 def Match(pattern, s): | 348 def Match(pattern, s): |
| 292 """Matches the string with the pattern, caching the compiled regexp.""" | 349 """Matches the string with the pattern, caching the compiled regexp.""" |
| 293 # The regexp compilation caching is inlined in both Match and Search for | 350 # The regexp compilation caching is inlined in both Match and Search for |
| 294 # performance reasons; factoring it out into a separate function turns out | 351 # performance reasons; factoring it out into a separate function turns out |
| 295 # to be noticeably expensive. | 352 # to be noticeably expensive. |
| 296 if not pattern in _regexp_compile_cache: | 353 if not pattern in _regexp_compile_cache: |
| 297 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) | 354 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) |
| 298 return _regexp_compile_cache[pattern].match(s) | 355 return _regexp_compile_cache[pattern].match(s) |
| 299 | 356 |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 | 751 |
| 695 def NoExtension(self): | 752 def NoExtension(self): |
| 696 """File has no source file extension.""" | 753 """File has no source file extension.""" |
| 697 return '/'.join(self.Split()[0:2]) | 754 return '/'.join(self.Split()[0:2]) |
| 698 | 755 |
| 699 def IsSource(self): | 756 def IsSource(self): |
| 700 """File has a source file extension.""" | 757 """File has a source file extension.""" |
| 701 return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') | 758 return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') |
| 702 | 759 |
| 703 | 760 |
| 704 def _ShouldPrintError(category, confidence): | 761 def _ShouldPrintError(category, confidence, linenum): |
| 705 """Returns true iff confidence >= verbose, and category passes filter.""" | 762 """Returns true iff confidence >= verbose, category passes |
| 706 # There are two ways we might decide not to print an error message: | 763 filter and is not NOLINT-suppressed.""" |
| 764 |
| 765 # There are three ways we might decide not to print an error message: |
| 766 # a "NOLINT(category)" comment appears in the source, |
| 707 # the verbosity level isn't high enough, or the filters filter it out. | 767 # the verbosity level isn't high enough, or the filters filter it out. |
| 768 if IsErrorSuppressedByNolint(category, linenum): |
| 769 return False |
| 708 if confidence < _cpplint_state.verbose_level: | 770 if confidence < _cpplint_state.verbose_level: |
| 709 return False | 771 return False |
| 710 | 772 |
| 711 is_filtered = False | 773 is_filtered = False |
| 712 for one_filter in _Filters(): | 774 for one_filter in _Filters(): |
| 713 if one_filter.startswith('-'): | 775 if one_filter.startswith('-'): |
| 714 if category.startswith(one_filter[1:]): | 776 if category.startswith(one_filter[1:]): |
| 715 is_filtered = True | 777 is_filtered = True |
| 716 elif one_filter.startswith('+'): | 778 elif one_filter.startswith('+'): |
| 717 if category.startswith(one_filter[1:]): | 779 if category.startswith(one_filter[1:]): |
| 718 is_filtered = False | 780 is_filtered = False |
| 719 else: | 781 else: |
| 720 assert False # should have been checked for in SetFilter. | 782 assert False # should have been checked for in SetFilter. |
| 721 if is_filtered: | 783 if is_filtered: |
| 722 return False | 784 return False |
| 723 | 785 |
| 724 return True | 786 return True |
| 725 | 787 |
| 726 | 788 |
| 727 def Error(filename, linenum, category, confidence, message): | 789 def Error(filename, linenum, category, confidence, message): |
| 728 """Logs the fact we've found a lint error. | 790 """Logs the fact we've found a lint error. |
| 729 | 791 |
| 730 We log where the error was found, and also our confidence in the error, | 792 We log where the error was found, and also our confidence in the error, |
| 731 that is, how certain we are this is a legitimate style regression, and | 793 that is, how certain we are this is a legitimate style regression, and |
| 732 not a misidentification or a use that's sometimes justified. | 794 not a misidentification or a use that's sometimes justified. |
| 733 | 795 |
| 796 False positives can be suppressed by the use of |
| 797 "cpplint(category)" comments on the offending line. These are |
| 798 parsed into _error_suppressions. |
| 799 |
| 734 Args: | 800 Args: |
| 735 filename: The name of the file containing the error. | 801 filename: The name of the file containing the error. |
| 736 linenum: The number of the line containing the error. | 802 linenum: The number of the line containing the error. |
| 737 category: A string used to describe the "category" this bug | 803 category: A string used to describe the "category" this bug |
| 738 falls under: "whitespace", say, or "runtime". Categories | 804 falls under: "whitespace", say, or "runtime". Categories |
| 739 may have a hierarchy separated by slashes: "whitespace/indent". | 805 may have a hierarchy separated by slashes: "whitespace/indent". |
| 740 confidence: A number from 1-5 representing a confidence score for | 806 confidence: A number from 1-5 representing a confidence score for |
| 741 the error, with 5 meaning that we are certain of the problem, | 807 the error, with 5 meaning that we are certain of the problem, |
| 742 and 1 meaning that it could be a legitimate construct. | 808 and 1 meaning that it could be a legitimate construct. |
| 743 message: The error message. | 809 message: The error message. |
| 744 """ | 810 """ |
| 745 # There are two ways we might decide not to print an error message: | 811 if _ShouldPrintError(category, confidence, linenum): |
| 746 # the verbosity level isn't high enough, or the filters filter it out. | |
| 747 if _ShouldPrintError(category, confidence): | |
| 748 _cpplint_state.IncrementErrorCount(category) | 812 _cpplint_state.IncrementErrorCount(category) |
| 749 if _cpplint_state.output_format == 'vs7': | 813 if _cpplint_state.output_format == 'vs7': |
| 750 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( | 814 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( |
| 751 filename, linenum, message, category, confidence)) | 815 filename, linenum, message, category, confidence)) |
| 752 else: | 816 else: |
| 753 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( | 817 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( |
| 754 filename, linenum, message, category, confidence)) | 818 filename, linenum, message, category, confidence)) |
| 755 | 819 |
| 756 | 820 |
| 757 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. | 821 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 | 1019 |
| 956 Args: | 1020 Args: |
| 957 filename: The name of a C++ header file. | 1021 filename: The name of a C++ header file. |
| 958 | 1022 |
| 959 Returns: | 1023 Returns: |
| 960 The CPP variable that should be used as a header guard in the | 1024 The CPP variable that should be used as a header guard in the |
| 961 named file. | 1025 named file. |
| 962 | 1026 |
| 963 """ | 1027 """ |
| 964 | 1028 |
| 1029 # Restores original filename in case that cpplint is invoked from Emacs's |
| 1030 # flymake. |
| 1031 filename = re.sub(r'_flymake\.h$', '.h', filename) |
| 1032 |
| 965 fileinfo = FileInfo(filename) | 1033 fileinfo = FileInfo(filename) |
| 966 return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' | 1034 return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' |
| 967 | 1035 |
| 968 | 1036 |
| 969 def CheckForHeaderGuard(filename, lines, error): | 1037 def CheckForHeaderGuard(filename, lines, error): |
| 970 """Checks that the file contains a header guard. | 1038 """Checks that the file contains a header guard. |
| 971 | 1039 |
| 972 Logs an error if no #ifndef header guard is present. For other | 1040 Logs an error if no #ifndef header guard is present. For other |
| 973 headers, checks that the full pathname is used. | 1041 headers, checks that the full pathname is used. |
| 974 | 1042 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1001 endif_linenum = linenum | 1069 endif_linenum = linenum |
| 1002 | 1070 |
| 1003 if not ifndef or not define or ifndef != define: | 1071 if not ifndef or not define or ifndef != define: |
| 1004 error(filename, 0, 'build/header_guard', 5, | 1072 error(filename, 0, 'build/header_guard', 5, |
| 1005 'No #ifndef header guard found, suggested CPP variable is: %s' % | 1073 'No #ifndef header guard found, suggested CPP variable is: %s' % |
| 1006 cppvar) | 1074 cppvar) |
| 1007 return | 1075 return |
| 1008 | 1076 |
| 1009 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ | 1077 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ |
| 1010 # for backward compatibility. | 1078 # for backward compatibility. |
| 1011 if ifndef != cppvar and not Search(r'\bNOLINT\b', lines[ifndef_linenum]): | 1079 if ifndef != cppvar: |
| 1012 error_level = 0 | 1080 error_level = 0 |
| 1013 if ifndef != cppvar + '_': | 1081 if ifndef != cppvar + '_': |
| 1014 error_level = 5 | 1082 error_level = 5 |
| 1015 | 1083 |
| 1084 ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum, |
| 1085 error) |
| 1016 error(filename, ifndef_linenum, 'build/header_guard', error_level, | 1086 error(filename, ifndef_linenum, 'build/header_guard', error_level, |
| 1017 '#ifndef header guard has wrong style, please use: %s' % cppvar) | 1087 '#ifndef header guard has wrong style, please use: %s' % cppvar) |
| 1018 | 1088 |
| 1019 if (endif != ('#endif // %s' % cppvar) and | 1089 if endif != ('#endif // %s' % cppvar): |
| 1020 not Search(r'\bNOLINT\b', lines[endif_linenum])): | |
| 1021 error_level = 0 | 1090 error_level = 0 |
| 1022 if endif != ('#endif // %s' % (cppvar + '_')): | 1091 if endif != ('#endif // %s' % (cppvar + '_')): |
| 1023 error_level = 5 | 1092 error_level = 5 |
| 1024 | 1093 |
| 1094 ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, |
| 1095 error) |
| 1025 error(filename, endif_linenum, 'build/header_guard', error_level, | 1096 error(filename, endif_linenum, 'build/header_guard', error_level, |
| 1026 '#endif line should be "#endif // %s"' % cppvar) | 1097 '#endif line should be "#endif // %s"' % cppvar) |
| 1027 | 1098 |
| 1028 | 1099 |
| 1029 def CheckForUnicodeReplacementCharacters(filename, lines, error): | 1100 def CheckForUnicodeReplacementCharacters(filename, lines, error): |
| 1030 """Logs an error for each line containing Unicode replacement characters. | 1101 """Logs an error for each line containing Unicode replacement characters. |
| 1031 | 1102 |
| 1032 These indicate that either the file contained invalid UTF-8 (likely) | 1103 These indicate that either the file contained invalid UTF-8 (likely) |
| 1033 or Unicode replacement characters (which it shouldn't). Note that | 1104 or Unicode replacement characters (which it shouldn't). Note that |
| 1034 it's possible for this to throw off line numbering if the invalid | 1105 it's possible for this to throw off line numbering if the invalid |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 function += parameter_regexp.group(1) | 1583 function += parameter_regexp.group(1) |
| 1513 else: | 1584 else: |
| 1514 function += '()' | 1585 function += '()' |
| 1515 function_state.Begin(function) | 1586 function_state.Begin(function) |
| 1516 break | 1587 break |
| 1517 if not body_found: | 1588 if not body_found: |
| 1518 # No body for the function (or evidence of a non-function) was found. | 1589 # No body for the function (or evidence of a non-function) was found. |
| 1519 error(filename, linenum, 'readability/fn_size', 5, | 1590 error(filename, linenum, 'readability/fn_size', 5, |
| 1520 'Lint failed to find start of function body.') | 1591 'Lint failed to find start of function body.') |
| 1521 elif Match(r'^\}\s*$', line): # function end | 1592 elif Match(r'^\}\s*$', line): # function end |
| 1522 if not Search(r'\bNOLINT\b', raw_line): | 1593 function_state.Check(error, filename, linenum) |
| 1523 function_state.Check(error, filename, linenum) | |
| 1524 function_state.End() | 1594 function_state.End() |
| 1525 elif not Match(r'^\s*$', line): | 1595 elif not Match(r'^\s*$', line): |
| 1526 function_state.Count() # Count non-blank/non-comment lines. | 1596 function_state.Count() # Count non-blank/non-comment lines. |
| 1527 | 1597 |
| 1528 | 1598 |
| 1529 _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') | 1599 _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') |
| 1530 | 1600 |
| 1531 | 1601 |
| 1532 def CheckComment(comment, filename, linenum, error): | 1602 def CheckComment(comment, filename, linenum, error): |
| 1533 """Checks for common mistakes in TODO comments. | 1603 """Checks for common mistakes in TODO comments. |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 elif ((initial_spaces == 1 or initial_spaces == 3) and | 2090 elif ((initial_spaces == 1 or initial_spaces == 3) and |
| 2021 not Match(r'\s*\w+\s*:\s*$', cleansed_line)): | 2091 not Match(r'\s*\w+\s*:\s*$', cleansed_line)): |
| 2022 error(filename, linenum, 'whitespace/indent', 3, | 2092 error(filename, linenum, 'whitespace/indent', 3, |
| 2023 'Weird number of spaces at line-start. ' | 2093 'Weird number of spaces at line-start. ' |
| 2024 'Are you using a 2-space indent?') | 2094 'Are you using a 2-space indent?') |
| 2025 # Labels should always be indented at least one space. | 2095 # Labels should always be indented at least one space. |
| 2026 elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$', | 2096 elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$', |
| 2027 line): | 2097 line): |
| 2028 error(filename, linenum, 'whitespace/labels', 4, | 2098 error(filename, linenum, 'whitespace/labels', 4, |
| 2029 'Labels should always be indented at least one space. ' | 2099 'Labels should always be indented at least one space. ' |
| 2030 'If this is a member-initializer list in a constructor, ' | 2100 'If this is a member-initializer list in a constructor or ' |
| 2031 'the colon should be on the line after the definition header.') | 2101 'the base class list in a class definition, the colon should ' |
| 2102 'be on the following line.') |
| 2103 |
| 2032 | 2104 |
| 2033 # Check if the line is a header guard. | 2105 # Check if the line is a header guard. |
| 2034 is_header_guard = False | 2106 is_header_guard = False |
| 2035 if file_extension == 'h': | 2107 if file_extension == 'h': |
| 2036 cppvar = GetHeaderGuardCPPVariable(filename) | 2108 cppvar = GetHeaderGuardCPPVariable(filename) |
| 2037 if (line.startswith('#ifndef %s' % cppvar) or | 2109 if (line.startswith('#ifndef %s' % cppvar) or |
| 2038 line.startswith('#define %s' % cppvar) or | 2110 line.startswith('#define %s' % cppvar) or |
| 2039 line.startswith('#endif // %s' % cppvar)): | 2111 line.startswith('#endif // %s' % cppvar)): |
| 2040 is_header_guard = True | 2112 is_header_guard = True |
| 2041 # #include lines and header guards can be long, since there's no clean way to | 2113 # #include lines and header guards can be long, since there's no clean way to |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 error(filename, linenum, 'runtime/int', 4, | 2466 error(filename, linenum, 'runtime/int', 4, |
| 2395 'Use "unsigned short" for ports, not "short"') | 2467 'Use "unsigned short" for ports, not "short"') |
| 2396 else: | 2468 else: |
| 2397 match = Search(r'\b(short|long(?! +double)|long long)\b', line) | 2469 match = Search(r'\b(short|long(?! +double)|long long)\b', line) |
| 2398 if match: | 2470 if match: |
| 2399 error(filename, linenum, 'runtime/int', 4, | 2471 error(filename, linenum, 'runtime/int', 4, |
| 2400 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) | 2472 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) |
| 2401 | 2473 |
| 2402 # When snprintf is used, the second argument shouldn't be a literal. | 2474 # When snprintf is used, the second argument shouldn't be a literal. |
| 2403 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) | 2475 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) |
| 2404 if match: | 2476 if match and match.group(2) != '0': |
| 2477 # If 2nd arg is zero, snprintf is used to calculate size. |
| 2405 error(filename, linenum, 'runtime/printf', 3, | 2478 error(filename, linenum, 'runtime/printf', 3, |
| 2406 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' | 2479 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' |
| 2407 'to snprintf.' % (match.group(1), match.group(2))) | 2480 'to snprintf.' % (match.group(1), match.group(2))) |
| 2408 | 2481 |
| 2409 # Check if some verboten C functions are being used. | 2482 # Check if some verboten C functions are being used. |
| 2410 if Search(r'\bsprintf\b', line): | 2483 if Search(r'\bsprintf\b', line): |
| 2411 error(filename, linenum, 'runtime/printf', 5, | 2484 error(filename, linenum, 'runtime/printf', 5, |
| 2412 'Never use sprintf. Use snprintf instead.') | 2485 'Never use sprintf. Use snprintf instead.') |
| 2413 match = Search(r'\b(strcpy|strcat)\b', line) | 2486 match = Search(r'\b(strcpy|strcat)\b', line) |
| 2414 if match: | 2487 if match: |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2743 """ | 2816 """ |
| 2744 required = {} # A map of header name to linenumber and the template entity. | 2817 required = {} # A map of header name to linenumber and the template entity. |
| 2745 # Example of required: { '<functional>': (1219, 'less<>') } | 2818 # Example of required: { '<functional>': (1219, 'less<>') } |
| 2746 | 2819 |
| 2747 for linenum in xrange(clean_lines.NumLines()): | 2820 for linenum in xrange(clean_lines.NumLines()): |
| 2748 line = clean_lines.elided[linenum] | 2821 line = clean_lines.elided[linenum] |
| 2749 if not line or line[0] == '#': | 2822 if not line or line[0] == '#': |
| 2750 continue | 2823 continue |
| 2751 | 2824 |
| 2752 # String is special -- it is a non-templatized type in STL. | 2825 # String is special -- it is a non-templatized type in STL. |
| 2753 if _RE_PATTERN_STRING.search(line): | 2826 m = _RE_PATTERN_STRING.search(line) |
| 2754 required['<string>'] = (linenum, 'string') | 2827 if m: |
| 2828 # Don't warn about strings in non-STL namespaces: |
| 2829 # (We check only the first match per line; good enough.) |
| 2830 prefix = line[:m.start()] |
| 2831 if prefix.endswith('std::') or not prefix.endswith('::'): |
| 2832 required['<string>'] = (linenum, 'string') |
| 2755 | 2833 |
| 2756 for pattern, template, header in _re_pattern_algorithm_header: | 2834 for pattern, template, header in _re_pattern_algorithm_header: |
| 2757 if pattern.search(line): | 2835 if pattern.search(line): |
| 2758 required[header] = (linenum, template) | 2836 required[header] = (linenum, template) |
| 2759 | 2837 |
| 2760 # The following function is just a speed up, no semantics are changed. | 2838 # The following function is just a speed up, no semantics are changed. |
| 2761 if not '<' in line: # Reduces the cpu time usage by skipping lines. | 2839 if not '<' in line: # Reduces the cpu time usage by skipping lines. |
| 2762 continue | 2840 continue |
| 2763 | 2841 |
| 2764 for pattern, template, header in _re_pattern_templates: | 2842 for pattern, template, header in _re_pattern_templates: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2776 # Use the absolute path so that matching works properly. | 2854 # Use the absolute path so that matching works properly. |
| 2777 abs_filename = os.path.abspath(filename) | 2855 abs_filename = os.path.abspath(filename) |
| 2778 | 2856 |
| 2779 # For Emacs's flymake. | 2857 # For Emacs's flymake. |
| 2780 # If cpplint is invoked from Emacs's flymake, a temporary file is generated | 2858 # If cpplint is invoked from Emacs's flymake, a temporary file is generated |
| 2781 # by flymake and that file name might end with '_flymake.cc'. In that case, | 2859 # by flymake and that file name might end with '_flymake.cc'. In that case, |
| 2782 # restore original file name here so that the corresponding header file can be | 2860 # restore original file name here so that the corresponding header file can be |
| 2783 # found. | 2861 # found. |
| 2784 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' | 2862 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' |
| 2785 # instead of 'foo_flymake.h' | 2863 # instead of 'foo_flymake.h' |
| 2786 emacs_flymake_suffix = '_flymake.cc' | 2864 abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) |
| 2787 if abs_filename.endswith(emacs_flymake_suffix): | |
| 2788 abs_filename = abs_filename[:-len(emacs_flymake_suffix)] + '.cc' | |
| 2789 | 2865 |
| 2790 # include_state is modified during iteration, so we iterate over a copy of | 2866 # include_state is modified during iteration, so we iterate over a copy of |
| 2791 # the keys. | 2867 # the keys. |
| 2792 for header in include_state.keys(): #NOLINT | 2868 for header in include_state.keys(): #NOLINT |
| 2793 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) | 2869 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) |
| 2794 fullpath = common_path + header | 2870 fullpath = common_path + header |
| 2795 if same_module and UpdateIncludeState(fullpath, include_state, io): | 2871 if same_module and UpdateIncludeState(fullpath, include_state, io): |
| 2796 header_found = True | 2872 header_found = True |
| 2797 | 2873 |
| 2798 # If we can't find the header file for a .cc, assume it's because we don't | 2874 # If we can't find the header file for a .cc, assume it's because we don't |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2829 line: Number of line being processed. | 2905 line: Number of line being processed. |
| 2830 include_state: An _IncludeState instance in which the headers are inserted. | 2906 include_state: An _IncludeState instance in which the headers are inserted. |
| 2831 function_state: A _FunctionState instance which counts function lines, etc. | 2907 function_state: A _FunctionState instance which counts function lines, etc. |
| 2832 class_state: A _ClassState instance which maintains information about | 2908 class_state: A _ClassState instance which maintains information about |
| 2833 the current stack of nested class declarations being parsed. | 2909 the current stack of nested class declarations being parsed. |
| 2834 error: A callable to which errors are reported, which takes 4 arguments: | 2910 error: A callable to which errors are reported, which takes 4 arguments: |
| 2835 filename, line number, error level, and message | 2911 filename, line number, error level, and message |
| 2836 | 2912 |
| 2837 """ | 2913 """ |
| 2838 raw_lines = clean_lines.raw_lines | 2914 raw_lines = clean_lines.raw_lines |
| 2915 ParseNolintSuppressions(filename, raw_lines[line], line, error) |
| 2839 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) | 2916 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) |
| 2840 if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines | |
| 2841 return | |
| 2842 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) | 2917 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) |
| 2843 CheckStyle(filename, clean_lines, line, file_extension, error) | 2918 CheckStyle(filename, clean_lines, line, file_extension, error) |
| 2844 CheckLanguage(filename, clean_lines, line, file_extension, include_state, | 2919 CheckLanguage(filename, clean_lines, line, file_extension, include_state, |
| 2845 error) | 2920 error) |
| 2846 CheckForNonStandardConstructs(filename, clean_lines, line, | 2921 CheckForNonStandardConstructs(filename, clean_lines, line, |
| 2847 class_state, error) | 2922 class_state, error) |
| 2848 CheckPosixThreading(filename, clean_lines, line, error) | 2923 CheckPosixThreading(filename, clean_lines, line, error) |
| 2849 CheckInvalidIncrement(filename, clean_lines, line, error) | 2924 CheckInvalidIncrement(filename, clean_lines, line, error) |
| 2850 | 2925 |
| 2851 | 2926 |
| 2852 def ProcessFileData(filename, file_extension, lines, error): | 2927 def ProcessFileData(filename, file_extension, lines, error): |
| 2853 """Performs lint checks and reports any errors to the given error function. | 2928 """Performs lint checks and reports any errors to the given error function. |
| 2854 | 2929 |
| 2855 Args: | 2930 Args: |
| 2856 filename: Filename of the file that is being processed. | 2931 filename: Filename of the file that is being processed. |
| 2857 file_extension: The extension (dot not included) of the file. | 2932 file_extension: The extension (dot not included) of the file. |
| 2858 lines: An array of strings, each representing a line of the file, with the | 2933 lines: An array of strings, each representing a line of the file, with the |
| 2859 last element being empty if the file is termined with a newline. | 2934 last element being empty if the file is termined with a newline. |
| 2860 error: A callable to which errors are reported, which takes 4 arguments: | 2935 error: A callable to which errors are reported, which takes 4 arguments: |
| 2861 """ | 2936 """ |
| 2862 lines = (['// marker so line numbers and indices both start at 1'] + lines + | 2937 lines = (['// marker so line numbers and indices both start at 1'] + lines + |
| 2863 ['// marker so line numbers end in a known way']) | 2938 ['// marker so line numbers end in a known way']) |
| 2864 | 2939 |
| 2865 include_state = _IncludeState() | 2940 include_state = _IncludeState() |
| 2866 function_state = _FunctionState() | 2941 function_state = _FunctionState() |
| 2867 class_state = _ClassState() | 2942 class_state = _ClassState() |
| 2868 | 2943 |
| 2944 ResetNolintSuppressions() |
| 2945 |
| 2869 CheckForCopyright(filename, lines, error) | 2946 CheckForCopyright(filename, lines, error) |
| 2870 | 2947 |
| 2871 if file_extension == 'h': | 2948 if file_extension == 'h': |
| 2872 CheckForHeaderGuard(filename, lines, error) | 2949 CheckForHeaderGuard(filename, lines, error) |
| 2873 | 2950 |
| 2874 RemoveMultiLineComments(filename, lines, error) | 2951 RemoveMultiLineComments(filename, lines, error) |
| 2875 clean_lines = CleansedLines(lines) | 2952 clean_lines = CleansedLines(lines) |
| 2876 for line in xrange(clean_lines.NumLines()): | 2953 for line in xrange(clean_lines.NumLines()): |
| 2877 ProcessLine(filename, file_extension, clean_lines, line, | 2954 ProcessLine(filename, file_extension, clean_lines, line, |
| 2878 include_state, function_state, class_state, error) | 2955 include_state, function_state, class_state, error) |
| 2879 class_state.CheckFinished(filename, error) | 2956 class_state.CheckFinished(filename, error) |
| 2880 | 2957 |
| 2881 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) | 2958 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) |
| 2882 | 2959 |
| 2883 # We check here rather than inside ProcessLine so that we see raw | 2960 # We check here rather than inside ProcessLine so that we see raw |
| 2884 # lines rather than "cleaned" lines. | 2961 # lines rather than "cleaned" lines. |
| 2885 CheckForUnicodeReplacementCharacters(filename, lines, error) | 2962 CheckForUnicodeReplacementCharacters(filename, lines, error) |
| 2886 | 2963 |
| 2887 CheckForNewlineAtEOF(filename, lines, error) | 2964 CheckForNewlineAtEOF(filename, lines, error) |
| 2888 | 2965 |
| 2889 | |
| 2890 def ProcessFile(filename, vlevel): | 2966 def ProcessFile(filename, vlevel): |
| 2891 """Does google-lint on a single file. | 2967 """Does google-lint on a single file. |
| 2892 | 2968 |
| 2893 Args: | 2969 Args: |
| 2894 filename: The name of the file to parse. | 2970 filename: The name of the file to parse. |
| 2895 | 2971 |
| 2896 vlevel: The level of errors to report. Every error of confidence | 2972 vlevel: The level of errors to report. Every error of confidence |
| 2897 >= verbose_level will be reported. 0 is a good default. | 2973 >= verbose_level will be reported. 0 is a good default. |
| 2898 """ | 2974 """ |
| 2899 | 2975 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2961 sys.exit('\nFATAL ERROR: ' + message) | 3037 sys.exit('\nFATAL ERROR: ' + message) |
| 2962 else: | 3038 else: |
| 2963 sys.exit(1) | 3039 sys.exit(1) |
| 2964 | 3040 |
| 2965 | 3041 |
| 2966 def PrintCategories(): | 3042 def PrintCategories(): |
| 2967 """Prints a list of all the error-categories used by error messages. | 3043 """Prints a list of all the error-categories used by error messages. |
| 2968 | 3044 |
| 2969 These are the categories used to filter messages via --filter. | 3045 These are the categories used to filter messages via --filter. |
| 2970 """ | 3046 """ |
| 2971 sys.stderr.write(_ERROR_CATEGORIES) | 3047 sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES)) |
| 2972 sys.exit(0) | 3048 sys.exit(0) |
| 2973 | 3049 |
| 2974 | 3050 |
| 2975 def ParseArguments(args): | 3051 def ParseArguments(args): |
| 2976 """Parses the command line arguments. | 3052 """Parses the command line arguments. |
| 2977 | 3053 |
| 2978 This may set the output format and verbosity level as side-effects. | 3054 This may set the output format and verbosity level as side-effects. |
| 2979 | 3055 |
| 2980 Args: | 3056 Args: |
| 2981 args: The command line arguments: | 3057 args: The command line arguments: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3037 _cpplint_state.ResetErrorCounts() | 3113 _cpplint_state.ResetErrorCounts() |
| 3038 for filename in filenames: | 3114 for filename in filenames: |
| 3039 ProcessFile(filename, _cpplint_state.verbose_level) | 3115 ProcessFile(filename, _cpplint_state.verbose_level) |
| 3040 _cpplint_state.PrintErrorCounts() | 3116 _cpplint_state.PrintErrorCounts() |
| 3041 | 3117 |
| 3042 sys.exit(_cpplint_state.error_count > 0) | 3118 sys.exit(_cpplint_state.error_count > 0) |
| 3043 | 3119 |
| 3044 | 3120 |
| 3045 if __name__ == '__main__': | 3121 if __name__ == '__main__': |
| 3046 main() | 3122 main() |
| OLD | NEW |