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 |