OLD | NEW |
1 #!/usr/bin/python2.4 | 1 #!/usr/bin/python2.4 |
2 # | 2 # |
3 # cpplint.py is Copyright (C) 2009 Google Inc. | 3 # cpplint.py is Copyright (C) 2009 Google Inc. |
4 # | 4 # |
5 # It is free software; you can redistribute it and/or modify it under the | 5 # It is free software; you can redistribute it and/or modify it under the |
6 # terms of either: | 6 # terms of either: |
7 # | 7 # |
8 # a) the GNU General Public License as published by the Free Software | 8 # a) the GNU General Public License as published by the Free Software |
9 # Foundation; either version 1, or (at your option) any later version, or | 9 # Foundation; either version 1, or (at your option) any later version, or |
10 # | 10 # |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 --filter=-,+build/include_what_you_use | 111 --filter=-,+build/include_what_you_use |
112 | 112 |
113 To see a list of all the categories used in cpplint, pass no arg: | 113 To see a list of all the categories used in cpplint, pass no arg: |
114 --filter= | 114 --filter= |
115 """ | 115 """ |
116 | 116 |
117 # We categorize each error message we print. Here are the categories. | 117 # We categorize each error message we print. Here are the categories. |
118 # We want an explicit list so we can list them all in cpplint --filter=. | 118 # We want an explicit list so we can list them all in cpplint --filter=. |
119 # If you add a new error message with a new category, add it to the list | 119 # If you add a new error message with a new category, add it to the list |
120 # here! cpplint_unittest.py should tell you if you forget to do this. | 120 # here! cpplint_unittest.py should tell you if you forget to do this. |
121 _ERROR_CATEGORIES = """\ | 121 # \ used for clearer layout -- pylint: disable-msg=C6013 |
| 122 _ERROR_CATEGORIES = '''\ |
122 build/class | 123 build/class |
123 build/deprecated | 124 build/deprecated |
124 build/endif_comment | 125 build/endif_comment |
125 build/forward_decl | 126 build/forward_decl |
126 build/header_guard | 127 build/header_guard |
127 build/include | 128 build/include |
128 build/include_order | 129 build/include_order |
129 build/include_what_you_use | 130 build/include_what_you_use |
130 build/namespaces | 131 build/namespaces |
131 build/printf_format | 132 build/printf_format |
132 build/storage_class | 133 build/storage_class |
133 legal/copyright | 134 legal/copyright |
134 readability/braces | 135 readability/braces |
135 readability/casting | 136 readability/casting |
136 readability/check | 137 readability/check |
137 readability/constructors | 138 readability/constructors |
138 readability/fn_size | 139 readability/fn_size |
139 readability/function | 140 readability/function |
140 readability/multiline_comment | 141 readability/multiline_comment |
141 readability/multiline_string | 142 readability/multiline_string |
142 readability/streams | 143 readability/streams |
143 readability/todo | 144 readability/todo |
144 readability/utf8 | 145 readability/utf8 |
145 runtime/arrays | 146 runtime/arrays |
146 runtime/casting | 147 runtime/casting |
147 runtime/explicit | 148 runtime/explicit |
148 runtime/int | 149 runtime/int |
149 runtime/init | 150 runtime/init |
| 151 runtime/invalid_increment |
150 runtime/memset | 152 runtime/memset |
151 runtime/printf | 153 runtime/printf |
152 runtime/printf_format | 154 runtime/printf_format |
153 runtime/references | 155 runtime/references |
154 runtime/rtti | 156 runtime/rtti |
155 runtime/sizeof | 157 runtime/sizeof |
156 runtime/string | 158 runtime/string |
157 runtime/threadsafe_fn | 159 runtime/threadsafe_fn |
158 runtime/virtual | 160 runtime/virtual |
159 whitespace/blank_line | 161 whitespace/blank_line |
160 whitespace/braces | 162 whitespace/braces |
161 whitespace/comma | 163 whitespace/comma |
162 whitespace/comments | 164 whitespace/comments |
163 whitespace/end_of_line | 165 whitespace/end_of_line |
164 whitespace/ending_newline | 166 whitespace/ending_newline |
165 whitespace/indent | 167 whitespace/indent |
166 whitespace/labels | 168 whitespace/labels |
167 whitespace/line_length | 169 whitespace/line_length |
168 whitespace/newline | 170 whitespace/newline |
169 whitespace/operators | 171 whitespace/operators |
170 whitespace/parens | 172 whitespace/parens |
171 whitespace/semicolon | 173 whitespace/semicolon |
172 whitespace/tab | 174 whitespace/tab |
173 whitespace/todo | 175 whitespace/todo |
174 """ | 176 ''' |
| 177 |
| 178 # The default state of the category filter. This is overrided by the --filter= |
| 179 # flag. By default all errors are on, so only add here categories that should be |
| 180 # off by default (i.e., categories that must be enabled by the --filter= flags). |
| 181 # All entries here should start with a '-' or '+', as in the --filter= flag. |
| 182 _DEFAULT_FILTERS = [] |
175 | 183 |
176 # We used to check for high-bit characters, but after much discussion we | 184 # We used to check for high-bit characters, but after much discussion we |
177 # decided those were OK, as long as they were in UTF-8 and didn't represent | 185 # decided those were OK, as long as they were in UTF-8 and didn't represent |
178 # hard-coded international strings, which belong in a seperate i18n file. | 186 # hard-coded international strings, which belong in a seperate i18n file. |
179 | 187 |
180 # Headers that we consider STL headers. | 188 # Headers that we consider STL headers. |
181 _STL_HEADERS = frozenset([ | 189 _STL_HEADERS = frozenset([ |
182 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', | 190 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', |
183 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', | 191 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', |
184 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h', | 192 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h', |
(...skipping 18 matching lines...) Expand all Loading... |
203 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept', | 211 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept', |
204 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string', | 212 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string', |
205 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray', | 213 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray', |
206 ]) | 214 ]) |
207 | 215 |
208 | 216 |
209 # Assertion macros. These are defined in base/logging.h and | 217 # Assertion macros. These are defined in base/logging.h and |
210 # testing/base/gunit.h. Note that the _M versions need to come first | 218 # testing/base/gunit.h. Note that the _M versions need to come first |
211 # for substring matching to work. | 219 # for substring matching to work. |
212 _CHECK_MACROS = [ | 220 _CHECK_MACROS = [ |
213 'CHECK', | 221 'DCHECK', 'CHECK', |
214 'EXPECT_TRUE_M', 'EXPECT_TRUE', | 222 'EXPECT_TRUE_M', 'EXPECT_TRUE', |
215 'ASSERT_TRUE_M', 'ASSERT_TRUE', | 223 'ASSERT_TRUE_M', 'ASSERT_TRUE', |
216 'EXPECT_FALSE_M', 'EXPECT_FALSE', | 224 'EXPECT_FALSE_M', 'EXPECT_FALSE', |
217 'ASSERT_FALSE_M', 'ASSERT_FALSE', | 225 'ASSERT_FALSE_M', 'ASSERT_FALSE', |
218 ] | 226 ] |
219 | 227 |
220 # Replacement macros for CHECK/EXPECT_TRUE/EXPECT_FALSE | 228 # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE |
221 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) | 229 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) |
222 | 230 |
223 for op, replacement in [('==', 'EQ'), ('!=', 'NE'), | 231 for op, replacement in [('==', 'EQ'), ('!=', 'NE'), |
224 ('>=', 'GE'), ('>', 'GT'), | 232 ('>=', 'GE'), ('>', 'GT'), |
225 ('<=', 'LE'), ('<', 'LT')]: | 233 ('<=', 'LE'), ('<', 'LT')]: |
| 234 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement |
226 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement | 235 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement |
227 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement | 236 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement |
228 _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement | 237 _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement |
229 _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement | 238 _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement |
230 _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement | 239 _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement |
231 | 240 |
232 for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), | 241 for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), |
233 ('>=', 'LT'), ('>', 'LE'), | 242 ('>=', 'LT'), ('>', 'LE'), |
234 ('<=', 'GT'), ('<', 'GE')]: | 243 ('<=', 'GT'), ('<', 'GE')]: |
235 _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement | 244 _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 360 |
352 return '' | 361 return '' |
353 | 362 |
354 | 363 |
355 class _CppLintState(object): | 364 class _CppLintState(object): |
356 """Maintains module-wide state..""" | 365 """Maintains module-wide state..""" |
357 | 366 |
358 def __init__(self): | 367 def __init__(self): |
359 self.verbose_level = 1 # global setting. | 368 self.verbose_level = 1 # global setting. |
360 self.error_count = 0 # global count of reported errors | 369 self.error_count = 0 # global count of reported errors |
361 self.filters = [] # filters to apply when emitting error messages | 370 # filters to apply when emitting error messages |
| 371 self.filters = _DEFAULT_FILTERS[:] |
362 | 372 |
363 # output format: | 373 # output format: |
364 # "emacs" - format that emacs can parse (default) | 374 # "emacs" - format that emacs can parse (default) |
365 # "vs7" - format that Microsoft Visual Studio 7 can parse | 375 # "vs7" - format that Microsoft Visual Studio 7 can parse |
366 self.output_format = 'emacs' | 376 self.output_format = 'emacs' |
367 | 377 |
368 def SetOutputFormat(self, output_format): | 378 def SetOutputFormat(self, output_format): |
369 """Sets the output format for errors.""" | 379 """Sets the output format for errors.""" |
370 self.output_format = output_format | 380 self.output_format = output_format |
371 | 381 |
372 def SetVerboseLevel(self, level): | 382 def SetVerboseLevel(self, level): |
373 """Sets the module's verbosity, and returns the previous setting.""" | 383 """Sets the module's verbosity, and returns the previous setting.""" |
374 last_verbose_level = self.verbose_level | 384 last_verbose_level = self.verbose_level |
375 self.verbose_level = level | 385 self.verbose_level = level |
376 return last_verbose_level | 386 return last_verbose_level |
377 | 387 |
378 def SetFilters(self, filters): | 388 def SetFilters(self, filters): |
379 """Sets the error-message filters. | 389 """Sets the error-message filters. |
380 | 390 |
381 These filters are applied when deciding whether to emit a given | 391 These filters are applied when deciding whether to emit a given |
382 error message. | 392 error message. |
383 | 393 |
384 Args: | 394 Args: |
385 filters: A string of comma-separated filters (eg "+whitespace/indent"). | 395 filters: A string of comma-separated filters (eg "+whitespace/indent"). |
386 Each filter should start with + or -; else we die. | 396 Each filter should start with + or -; else we die. |
| 397 |
| 398 Raises: |
| 399 ValueError: The comma-separated filters did not all start with '+' or '-'. |
| 400 E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" |
387 """ | 401 """ |
388 if not filters: | 402 # Default filters always have less priority than the flag ones. |
389 self.filters = [] | 403 self.filters = _DEFAULT_FILTERS[:] |
390 else: | 404 for filt in filters.split(','): |
391 self.filters = filters.split(',') | 405 clean_filt = filt.strip() |
| 406 if clean_filt: |
| 407 self.filters.append(clean_filt) |
392 for filt in self.filters: | 408 for filt in self.filters: |
393 if not (filt.startswith('+') or filt.startswith('-')): | 409 if not (filt.startswith('+') or filt.startswith('-')): |
394 raise ValueError('Every filter in --filters must start with + or -' | 410 raise ValueError('Every filter in --filters must start with + or -' |
395 ' (%s does not)' % filt) | 411 ' (%s does not)' % filt) |
396 | 412 |
397 def ResetErrorCount(self): | 413 def ResetErrorCount(self): |
398 """Sets the module's error statistic back to zero.""" | 414 """Sets the module's error statistic back to zero.""" |
399 self.error_count = 0 | 415 self.error_count = 0 |
400 | 416 |
401 def IncrementErrorCount(self): | 417 def IncrementErrorCount(self): |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 Returns: | 751 Returns: |
736 The line with single-line comments removed. | 752 The line with single-line comments removed. |
737 """ | 753 """ |
738 commentpos = line.find('//') | 754 commentpos = line.find('//') |
739 if commentpos != -1 and not IsCppString(line[:commentpos]): | 755 if commentpos != -1 and not IsCppString(line[:commentpos]): |
740 line = line[:commentpos] | 756 line = line[:commentpos] |
741 # get rid of /* ... */ | 757 # get rid of /* ... */ |
742 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) | 758 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) |
743 | 759 |
744 | 760 |
745 class CleansedLines: | 761 class CleansedLines(object): |
746 """Holds 3 copies of all lines with different preprocessing applied to them. | 762 """Holds 3 copies of all lines with different preprocessing applied to them. |
747 | 763 |
748 1) elided member contains lines without strings and comments, | 764 1) elided member contains lines without strings and comments, |
749 2) lines member contains lines without comments, and | 765 2) lines member contains lines without comments, and |
750 3) raw member contains all the lines without processing. | 766 3) raw member contains all the lines without processing. |
751 All these three members are of <type 'list'>, and of the same length. | 767 All these three members are of <type 'list'>, and of the same length. |
752 """ | 768 """ |
753 | 769 |
754 def __init__(self, lines): | 770 def __init__(self, lines): |
755 self.elided = [] | 771 self.elided = [] |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 | 867 |
852 """ | 868 """ |
853 | 869 |
854 fileinfo = FileInfo(filename) | 870 fileinfo = FileInfo(filename) |
855 return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' | 871 return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' |
856 | 872 |
857 | 873 |
858 def CheckForHeaderGuard(filename, lines, error): | 874 def CheckForHeaderGuard(filename, lines, error): |
859 """Checks that the file contains a header guard. | 875 """Checks that the file contains a header guard. |
860 | 876 |
861 Logs an error if no #ifndef header guard is present. For google3 | 877 Logs an error if no #ifndef header guard is present. For other |
862 headers, checks that the full pathname is used. | 878 headers, checks that the full pathname is used. |
863 | 879 |
864 Args: | 880 Args: |
865 filename: The name of the C++ header file. | 881 filename: The name of the C++ header file. |
866 lines: An array of strings, each representing a line of the file. | 882 lines: An array of strings, each representing a line of the file. |
867 error: The function to call with any errors found. | 883 error: The function to call with any errors found. |
868 """ | 884 """ |
869 | 885 |
870 cppvar = GetHeaderGuardCPPVariable(filename) | 886 cppvar = GetHeaderGuardCPPVariable(filename) |
871 | 887 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 | 1033 |
1018 Args: | 1034 Args: |
1019 filename: The name of the current file. | 1035 filename: The name of the current file. |
1020 clean_lines: A CleansedLines instance containing the file. | 1036 clean_lines: A CleansedLines instance containing the file. |
1021 linenum: The number of the line to check. | 1037 linenum: The number of the line to check. |
1022 error: The function to call with any errors found. | 1038 error: The function to call with any errors found. |
1023 """ | 1039 """ |
1024 line = clean_lines.elided[linenum] | 1040 line = clean_lines.elided[linenum] |
1025 for single_thread_function, multithread_safe_function in threading_list: | 1041 for single_thread_function, multithread_safe_function in threading_list: |
1026 ix = line.find(single_thread_function) | 1042 ix = line.find(single_thread_function) |
| 1043 # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 |
1027 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and | 1044 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and |
1028 line[ix - 1] not in ('_', '.', '>'))): | 1045 line[ix - 1] not in ('_', '.', '>'))): |
1029 error(filename, linenum, 'runtime/threadsafe_fn', 2, | 1046 error(filename, linenum, 'runtime/threadsafe_fn', 2, |
1030 'Consider using ' + multithread_safe_function + | 1047 'Consider using ' + multithread_safe_function + |
1031 '...) instead of ' + single_thread_function + | 1048 '...) instead of ' + single_thread_function + |
1032 '...) for improved thread safety.') | 1049 '...) for improved thread safety.') |
1033 | 1050 |
1034 | 1051 |
| 1052 # Matches invalid increment: *count++, which moves pointer insead of |
| 1053 # incrementing a value. |
| 1054 _RE_PATTERN_IVALID_INCREMENT = re.compile( |
| 1055 r'^\s*\*\w+(\+\+|--);') |
| 1056 |
| 1057 |
| 1058 def CheckInvalidIncrement(filename, clean_lines, linenum, error): |
| 1059 """Checks for invalud increment *count++. |
| 1060 |
| 1061 For example following function: |
| 1062 void increment_counter(int* count) { |
| 1063 *count++; |
| 1064 } |
| 1065 is invalid, because it effectively does count++, moving pointer, and should |
| 1066 be replaced with ++*count, (*count)++ or *count += 1. |
| 1067 |
| 1068 Args: |
| 1069 filename: The name of the current file. |
| 1070 clean_lines: A CleansedLines instance containing the file. |
| 1071 linenum: The number of the line to check. |
| 1072 error: The function to call with any errors found. |
| 1073 """ |
| 1074 line = clean_lines.elided[linenum] |
| 1075 if _RE_PATTERN_IVALID_INCREMENT.match(line): |
| 1076 error(filename, linenum, 'runtime/invalid_increment', 5, |
| 1077 'Changing pointer instead of value (or unused value of operator*).') |
| 1078 |
| 1079 |
1035 class _ClassInfo(object): | 1080 class _ClassInfo(object): |
1036 """Stores information about a class.""" | 1081 """Stores information about a class.""" |
1037 | 1082 |
1038 def __init__(self, name, linenum): | 1083 def __init__(self, name, linenum): |
1039 self.name = name | 1084 self.name = name |
1040 self.linenum = linenum | 1085 self.linenum = linenum |
1041 self.seen_open_brace = False | 1086 self.seen_open_brace = False |
1042 self.is_derived = False | 1087 self.is_derived = False |
1043 self.virtual_method_linenumber = None | 1088 self.virtual_method_linenumber = None |
1044 self.has_virtual_destructor = False | 1089 self.has_virtual_destructor = False |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 # " (something)(maybe-something," or | 1307 # " (something)(maybe-something," or |
1263 # " (something)[something]" | 1308 # " (something)[something]" |
1264 # Note that we assume the contents of [] to be short enough that | 1309 # Note that we assume the contents of [] to be short enough that |
1265 # they'll never need to wrap. | 1310 # they'll never need to wrap. |
1266 if ( # Ignore control structures. | 1311 if ( # Ignore control structures. |
1267 not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and | 1312 not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and |
1268 # Ignore pointers/references to functions. | 1313 # Ignore pointers/references to functions. |
1269 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and | 1314 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and |
1270 # Ignore pointers/references to arrays. | 1315 # Ignore pointers/references to arrays. |
1271 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): | 1316 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): |
1272 if Search(r'\w\s*\(\s', fncall): # a ( used for a fn call | 1317 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call |
1273 error(filename, linenum, 'whitespace/parens', 4, | 1318 error(filename, linenum, 'whitespace/parens', 4, |
1274 'Extra space after ( in function call') | 1319 'Extra space after ( in function call') |
1275 elif Search(r'\(\s+[^(]', fncall): | 1320 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): |
1276 error(filename, linenum, 'whitespace/parens', 2, | 1321 error(filename, linenum, 'whitespace/parens', 2, |
1277 'Extra space after (') | 1322 'Extra space after (') |
1278 if (Search(r'\w\s+\(', fncall) and | 1323 if (Search(r'\w\s+\(', fncall) and |
1279 not Search(r'#\s*define|typedef', fncall)): | 1324 not Search(r'#\s*define|typedef', fncall)): |
1280 error(filename, linenum, 'whitespace/parens', 4, | 1325 error(filename, linenum, 'whitespace/parens', 4, |
1281 'Extra space before ( in function call') | 1326 'Extra space before ( in function call') |
1282 # If the ) is followed only by a newline or a { + newline, assume it's | 1327 # If the ) is followed only by a newline or a { + newline, assume it's |
1283 # part of a control statement (if/while/etc), and don't complain | 1328 # part of a control statement (if/while/etc), and don't complain |
1284 if Search(r'[^)]\s+\)\s*[^{\s]', fncall): | 1329 if Search(r'[^)]\s+\)\s*[^{\s]', fncall): |
1285 error(filename, linenum, 'whitespace/parens', 2, | 1330 error(filename, linenum, 'whitespace/parens', 2, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 function_state: Current function name and lines in body so far. | 1369 function_state: Current function name and lines in body so far. |
1325 error: The function to call with any errors found. | 1370 error: The function to call with any errors found. |
1326 """ | 1371 """ |
1327 lines = clean_lines.lines | 1372 lines = clean_lines.lines |
1328 line = lines[linenum] | 1373 line = lines[linenum] |
1329 raw = clean_lines.raw_lines | 1374 raw = clean_lines.raw_lines |
1330 raw_line = raw[linenum] | 1375 raw_line = raw[linenum] |
1331 joined_line = '' | 1376 joined_line = '' |
1332 | 1377 |
1333 starting_func = False | 1378 starting_func = False |
1334 regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... | 1379 regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... |
1335 match_result = Match(regexp, line) | 1380 match_result = Match(regexp, line) |
1336 if match_result: | 1381 if match_result: |
1337 # If the name is all caps and underscores, figure it's a macro and | 1382 # If the name is all caps and underscores, figure it's a macro and |
1338 # ignore it, unless it's TEST or TEST_F. | 1383 # ignore it, unless it's TEST or TEST_F. |
1339 function_name = match_result.group(1).split()[-1] | 1384 function_name = match_result.group(1).split()[-1] |
1340 if function_name == 'TEST' or function_name == 'TEST_F' or ( | 1385 if function_name == 'TEST' or function_name == 'TEST_F' or ( |
1341 not Match(r'[A-Z_]+$', function_name)): | 1386 not Match(r'[A-Z_]+$', function_name)): |
1342 starting_func = True | 1387 starting_func = True |
1343 | 1388 |
1344 if starting_func: | 1389 if starting_func: |
1345 body_found = False | 1390 body_found = False |
1346 # Don't look too far for the function body. Lint might be mistaken about | 1391 for start_linenum in xrange(linenum, clean_lines.NumLines()): |
1347 # whether it's a function definition. | |
1348 for start_linenum in xrange(linenum, | |
1349 min(linenum+100, clean_lines.NumLines())): | |
1350 start_line = lines[start_linenum] | 1392 start_line = lines[start_linenum] |
1351 joined_line += ' ' + start_line.lstrip() | 1393 joined_line += ' ' + start_line.lstrip() |
1352 if Search(r'(;|})', start_line): # Declarations and trivial functions | 1394 if Search(r'(;|})', start_line): # Declarations and trivial functions |
1353 body_found = True | 1395 body_found = True |
1354 break # ... ignore | 1396 break # ... ignore |
1355 elif Search(r'{', start_line): | 1397 elif Search(r'{', start_line): |
1356 body_found = True | 1398 body_found = True |
1357 function = Search(r'((\w|:)*)\(', line).group(1) | 1399 function = Search(r'((\w|:)*)\(', line).group(1) |
1358 if Match(r'TEST', function): # Handle TEST... macros | 1400 if Match(r'TEST', function): # Handle TEST... macros |
1359 parameter_regexp = Search(r'(\(.*\))', joined_line) | 1401 parameter_regexp = Search(r'(\(.*\))', joined_line) |
1360 if parameter_regexp: # Ignore bad syntax | 1402 if parameter_regexp: # Ignore bad syntax |
1361 function += parameter_regexp.group(1) | 1403 function += parameter_regexp.group(1) |
1362 else: | 1404 else: |
1363 function += '()' | 1405 function += '()' |
1364 function_state.Begin(function) | 1406 function_state.Begin(function) |
1365 break | 1407 break |
1366 if not body_found: | 1408 if not body_found: |
1367 # 50 lines after finding a line deemed to start a function | 1409 # No body for the function (or evidence of a non-function) was found. |
1368 # definition, no body for the function was found. A macro | |
1369 # invocation with no terminating semicolon could trigger this. | |
1370 error(filename, linenum, 'readability/fn_size', 5, | 1410 error(filename, linenum, 'readability/fn_size', 5, |
1371 'Lint failed to find start of function body.') | 1411 'Lint failed to find start of function body.') |
1372 elif Match(r'^\}\s*$', line): # function end | 1412 elif Match(r'^\}\s*$', line): # function end |
1373 if not Search(r'\bNOLINT\b', raw_line): | 1413 if not Search(r'\bNOLINT\b', raw_line): |
1374 function_state.Check(error, filename, linenum) | 1414 function_state.Check(error, filename, linenum) |
1375 function_state.End() | 1415 function_state.End() |
1376 elif not Match(r'^\s*$', line): | 1416 elif not Match(r'^\s*$', line): |
1377 function_state.Count() # Count non-blank/non-comment lines. | 1417 function_state.Count() # Count non-blank/non-comment lines. |
1378 | 1418 |
1379 | 1419 |
(...skipping 17 matching lines...) Expand all Loading... |
1397 error(filename, linenum, 'whitespace/todo', 2, | 1437 error(filename, linenum, 'whitespace/todo', 2, |
1398 'Too many spaces before TODO') | 1438 'Too many spaces before TODO') |
1399 | 1439 |
1400 username = match.group(2) | 1440 username = match.group(2) |
1401 if not username: | 1441 if not username: |
1402 error(filename, linenum, 'readability/todo', 2, | 1442 error(filename, linenum, 'readability/todo', 2, |
1403 'Missing username in TODO; it should look like ' | 1443 'Missing username in TODO; it should look like ' |
1404 '"// TODO(my_username): Stuff."') | 1444 '"// TODO(my_username): Stuff."') |
1405 | 1445 |
1406 middle_whitespace = match.group(3) | 1446 middle_whitespace = match.group(3) |
| 1447 # Comparisons made explicit for correctness -- pylint: disable-msg=C6403 |
1407 if middle_whitespace != ' ' and middle_whitespace != '': | 1448 if middle_whitespace != ' ' and middle_whitespace != '': |
1408 error(filename, linenum, 'whitespace/todo', 2, | 1449 error(filename, linenum, 'whitespace/todo', 2, |
1409 'TODO(my_username) should be followed by a space') | 1450 'TODO(my_username) should be followed by a space') |
1410 | 1451 |
1411 | 1452 |
1412 def CheckSpacing(filename, clean_lines, linenum, error): | 1453 def CheckSpacing(filename, clean_lines, linenum, error): |
1413 """Checks for the correctness of various spacing issues in the code. | 1454 """Checks for the correctness of various spacing issues in the code. |
1414 | 1455 |
1415 Things we check for: spaces around operators, spaces after | 1456 Things we check for: spaces around operators, spaces after |
1416 if/for/while/switch, no spaces around parens in function calls, two | 1457 if/for/while/switch, no spaces around parens in function calls, two |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 and Match(r'\s*}', next_line) | 1532 and Match(r'\s*}', next_line) |
1492 and next_line.find('namespace') == -1 | 1533 and next_line.find('namespace') == -1 |
1493 and next_line.find('} else ') == -1): | 1534 and next_line.find('} else ') == -1): |
1494 error(filename, linenum, 'whitespace/blank_line', 3, | 1535 error(filename, linenum, 'whitespace/blank_line', 3, |
1495 'Blank line at the end of a code block. Is this needed?') | 1536 'Blank line at the end of a code block. Is this needed?') |
1496 | 1537 |
1497 # Next, we complain if there's a comment too near the text | 1538 # Next, we complain if there's a comment too near the text |
1498 commentpos = line.find('//') | 1539 commentpos = line.find('//') |
1499 if commentpos != -1: | 1540 if commentpos != -1: |
1500 # Check if the // may be in quotes. If so, ignore it | 1541 # Check if the // may be in quotes. If so, ignore it |
| 1542 # Comparisons made explicit for clarity -- pylint: disable-msg=C6403 |
1501 if (line.count('"', 0, commentpos) - | 1543 if (line.count('"', 0, commentpos) - |
1502 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes | 1544 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes |
1503 # Allow one space for new scopes, two spaces otherwise: | 1545 # Allow one space for new scopes, two spaces otherwise: |
1504 if (not Match(r'^\s*{ //', line) and | 1546 if (not Match(r'^\s*{ //', line) and |
1505 ((commentpos >= 1 and | 1547 ((commentpos >= 1 and |
1506 line[commentpos-1] not in string.whitespace) or | 1548 line[commentpos-1] not in string.whitespace) or |
1507 (commentpos >= 2 and | 1549 (commentpos >= 2 and |
1508 line[commentpos-2] not in string.whitespace))): | 1550 line[commentpos-2] not in string.whitespace))): |
1509 error(filename, linenum, 'whitespace/comments', 2, | 1551 error(filename, linenum, 'whitespace/comments', 2, |
1510 'At least two spaces is best between code and comments') | 1552 'At least two spaces is best between code and comments') |
1511 # There should always be a space between the // and the comment | 1553 # There should always be a space between the // and the comment |
1512 commentend = commentpos + 2 | 1554 commentend = commentpos + 2 |
1513 if commentend < len(line) and not line[commentend] == ' ': | 1555 if commentend < len(line) and not line[commentend] == ' ': |
1514 # but some lines are exceptions -- e.g. if they're big | 1556 # but some lines are exceptions -- e.g. if they're big |
1515 # comment delimiters like: | 1557 # comment delimiters like: |
1516 # //---------------------------------------------------------- | 1558 # //---------------------------------------------------------- |
1517 match = Search(r'[=/-]{4,}\s*$', line[commentend:]) | 1559 # or they begin with multiple slashes followed by a space: |
| 1560 # //////// Header comment |
| 1561 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or |
| 1562 Search(r'^/+ ', line[commentend:])) |
1518 if not match: | 1563 if not match: |
1519 error(filename, linenum, 'whitespace/comments', 4, | 1564 error(filename, linenum, 'whitespace/comments', 4, |
1520 'Should have a space between // and comment') | 1565 'Should have a space between // and comment') |
1521 CheckComment(line[commentpos:], filename, linenum, error) | 1566 CheckComment(line[commentpos:], filename, linenum, error) |
1522 | 1567 |
1523 line = clean_lines.elided[linenum] # get rid of comments and strings | 1568 line = clean_lines.elided[linenum] # get rid of comments and strings |
1524 | 1569 |
1525 # Don't try to do spacing checks for operator methods | 1570 # Don't try to do spacing checks for operator methods |
1526 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) | 1571 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) |
1527 | 1572 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 # A pet peeve of mine: no spaces after an if, while, switch, or for | 1613 # A pet peeve of mine: no spaces after an if, while, switch, or for |
1569 match = Search(r' (if\(|for\(|while\(|switch\()', line) | 1614 match = Search(r' (if\(|for\(|while\(|switch\()', line) |
1570 if match: | 1615 if match: |
1571 error(filename, linenum, 'whitespace/parens', 5, | 1616 error(filename, linenum, 'whitespace/parens', 5, |
1572 'Missing space before ( in %s' % match.group(1)) | 1617 'Missing space before ( in %s' % match.group(1)) |
1573 | 1618 |
1574 # For if/for/while/switch, the left and right parens should be | 1619 # For if/for/while/switch, the left and right parens should be |
1575 # consistent about how many spaces are inside the parens, and | 1620 # consistent about how many spaces are inside the parens, and |
1576 # there should either be zero or one spaces inside the parens. | 1621 # there should either be zero or one spaces inside the parens. |
1577 # We don't want: "if ( foo)" or "if ( foo )". | 1622 # We don't want: "if ( foo)" or "if ( foo )". |
1578 # Exception: "for ( ; foo; bar)" is allowed. | 1623 # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. |
1579 match = Search(r'\b(if|for|while|switch)\s*' | 1624 match = Search(r'\b(if|for|while|switch)\s*' |
1580 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', | 1625 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', |
1581 line) | 1626 line) |
1582 if match: | 1627 if match: |
1583 if len(match.group(2)) != len(match.group(4)): | 1628 if len(match.group(2)) != len(match.group(4)): |
1584 if not (match.group(3) == ';' and | 1629 if not (match.group(3) == ';' and |
1585 len(match.group(2)) == 1 + len(match.group(4))): | 1630 len(match.group(2)) == 1 + len(match.group(4)) or |
| 1631 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): |
1586 error(filename, linenum, 'whitespace/parens', 5, | 1632 error(filename, linenum, 'whitespace/parens', 5, |
1587 'Mismatching spaces inside () in %s' % match.group(1)) | 1633 'Mismatching spaces inside () in %s' % match.group(1)) |
1588 if not len(match.group(2)) in [0, 1]: | 1634 if not len(match.group(2)) in [0, 1]: |
1589 error(filename, linenum, 'whitespace/parens', 5, | 1635 error(filename, linenum, 'whitespace/parens', 5, |
1590 'Should have zero or one spaces inside ( and ) in %s' % | 1636 'Should have zero or one spaces inside ( and ) in %s' % |
1591 match.group(1)) | 1637 match.group(1)) |
1592 | 1638 |
1593 # You should always have a space after a comma (either as fn arg or operator) | 1639 # You should always have a space after a comma (either as fn arg or operator) |
1594 if Search(r',[^\s]', line): | 1640 if Search(r',[^\s]', line): |
1595 error(filename, linenum, 'whitespace/comma', 3, | 1641 error(filename, linenum, 'whitespace/comma', 3, |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1878 # Check if the line is a header guard. | 1924 # Check if the line is a header guard. |
1879 is_header_guard = False | 1925 is_header_guard = False |
1880 if file_extension == 'h': | 1926 if file_extension == 'h': |
1881 cppvar = GetHeaderGuardCPPVariable(filename) | 1927 cppvar = GetHeaderGuardCPPVariable(filename) |
1882 if (line.startswith('#ifndef %s' % cppvar) or | 1928 if (line.startswith('#ifndef %s' % cppvar) or |
1883 line.startswith('#define %s' % cppvar) or | 1929 line.startswith('#define %s' % cppvar) or |
1884 line.startswith('#endif // %s' % cppvar)): | 1930 line.startswith('#endif // %s' % cppvar)): |
1885 is_header_guard = True | 1931 is_header_guard = True |
1886 # #include lines and header guards can be long, since there's no clean way to | 1932 # #include lines and header guards can be long, since there's no clean way to |
1887 # split them. | 1933 # split them. |
1888 if not line.startswith('#include') and not is_header_guard: | 1934 # |
| 1935 # URLs can be long too. It's possible to split these, but it makes them |
| 1936 # harder to cut&paste. |
| 1937 if (not line.startswith('#include') and not is_header_guard and |
| 1938 not Match(r'^\s*//.*http(s?)://\S*$', line)): |
1889 line_width = GetLineWidth(line) | 1939 line_width = GetLineWidth(line) |
1890 if line_width > 100: | 1940 if line_width > 100: |
1891 error(filename, linenum, 'whitespace/line_length', 4, | 1941 error(filename, linenum, 'whitespace/line_length', 4, |
1892 'Lines should very rarely be longer than 100 characters') | 1942 'Lines should very rarely be longer than 100 characters') |
1893 elif line_width > 80: | 1943 elif line_width > 80: |
1894 error(filename, linenum, 'whitespace/line_length', 2, | 1944 error(filename, linenum, 'whitespace/line_length', 2, |
1895 'Lines should be <= 80 characters long') | 1945 'Lines should be <= 80 characters long') |
1896 | 1946 |
1897 if (cleansed_line.count(';') > 1 and | 1947 if (cleansed_line.count(';') > 1 and |
1898 # for loops are allowed two ;'s (and may run over two lines). | 1948 # for loops are allowed two ;'s (and may run over two lines). |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2019 target_first_component = _RE_FIRST_COMPONENT.match(target_base) | 2069 target_first_component = _RE_FIRST_COMPONENT.match(target_base) |
2020 include_first_component = _RE_FIRST_COMPONENT.match(include_base) | 2070 include_first_component = _RE_FIRST_COMPONENT.match(include_base) |
2021 if (target_first_component and include_first_component and | 2071 if (target_first_component and include_first_component and |
2022 target_first_component.group(0) == | 2072 target_first_component.group(0) == |
2023 include_first_component.group(0)): | 2073 include_first_component.group(0)): |
2024 return _POSSIBLE_MY_HEADER | 2074 return _POSSIBLE_MY_HEADER |
2025 | 2075 |
2026 return _OTHER_HEADER | 2076 return _OTHER_HEADER |
2027 | 2077 |
2028 | 2078 |
2029 def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state, | |
2030 error): | |
2031 """Checks rules from the 'C++ language rules' section of cppguide.html. | |
2032 | 2079 |
2033 Some of these rules are hard to test (function overloading, using | 2080 def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): |
2034 uint32 inappropriately), but we do the best we can. | 2081 """Check rules that are applicable to #include lines. |
| 2082 |
| 2083 Strings on #include lines are NOT removed from elided line, to make |
| 2084 certain tasks easier. However, to prevent false positives, checks |
| 2085 applicable to #include lines in CheckLanguage must be put here. |
2035 | 2086 |
2036 Args: | 2087 Args: |
2037 filename: The name of the current file. | 2088 filename: The name of the current file. |
2038 clean_lines: A CleansedLines instance containing the file. | 2089 clean_lines: A CleansedLines instance containing the file. |
2039 linenum: The number of the line to check. | 2090 linenum: The number of the line to check. |
2040 file_extension: The extension (without the dot) of the filename. | |
2041 include_state: An _IncludeState instance in which the headers are inserted. | 2091 include_state: An _IncludeState instance in which the headers are inserted. |
2042 error: The function to call with any errors found. | 2092 error: The function to call with any errors found. |
2043 """ | 2093 """ |
2044 fileinfo = FileInfo(filename) | 2094 fileinfo = FileInfo(filename) |
2045 | 2095 |
2046 # get rid of comments | 2096 line = clean_lines.lines[linenum] |
2047 comment_elided_line = clean_lines.lines[linenum] | |
2048 | 2097 |
2049 # "include" should use the new style "foo/bar.h" instead of just "bar.h" | 2098 # "include" should use the new style "foo/bar.h" instead of just "bar.h" |
2050 if _RE_PATTERN_INCLUDE_NEW_STYLE.search(comment_elided_line): | 2099 if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line): |
2051 error(filename, linenum, 'build/include', 4, | 2100 error(filename, linenum, 'build/include', 4, |
2052 'Include the directory when naming .h files') | 2101 'Include the directory when naming .h files') |
2053 | 2102 |
2054 # we shouldn't include a file more than once. actually, there are a | 2103 # we shouldn't include a file more than once. actually, there are a |
2055 # handful of instances where doing so is okay, but in general it's | 2104 # handful of instances where doing so is okay, but in general it's |
2056 # not. | 2105 # not. |
2057 match = _RE_PATTERN_INCLUDE.search(comment_elided_line) | 2106 match = _RE_PATTERN_INCLUDE.search(line) |
2058 if match: | 2107 if match: |
2059 include = match.group(2) | 2108 include = match.group(2) |
2060 is_system = (match.group(1) == '<') | 2109 is_system = (match.group(1) == '<') |
2061 if include in include_state: | 2110 if include in include_state: |
2062 error(filename, linenum, 'build/include', 4, | 2111 error(filename, linenum, 'build/include', 4, |
2063 '"%s" already included at %s:%s' % | 2112 '"%s" already included at %s:%s' % |
2064 (include, filename, include_state[include])) | 2113 (include, filename, include_state[include])) |
2065 else: | 2114 else: |
2066 include_state[include] = linenum | 2115 include_state[include] = linenum |
2067 | 2116 |
2068 # We want to ensure that headers appear in the right order: | 2117 # We want to ensure that headers appear in the right order: |
2069 # 1) for foo.cc, foo.h (preferred location) | 2118 # 1) for foo.cc, foo.h (preferred location) |
2070 # 2) c system files | 2119 # 2) c system files |
2071 # 3) cpp system files | 2120 # 3) cpp system files |
2072 # 4) for foo.cc, foo.h (deprecated location) | 2121 # 4) for foo.cc, foo.h (deprecated location) |
2073 # 5) other google headers | 2122 # 5) other google headers |
2074 # | 2123 # |
2075 # We classify each include statement as one of those 5 types | 2124 # We classify each include statement as one of those 5 types |
2076 # using a number of techniques. The include_state object keeps | 2125 # using a number of techniques. The include_state object keeps |
2077 # track of the highest type seen, and complains if we see a | 2126 # track of the highest type seen, and complains if we see a |
2078 # lower type after that. | 2127 # lower type after that. |
2079 error_message = include_state.CheckNextIncludeOrder( | 2128 error_message = include_state.CheckNextIncludeOrder( |
2080 _ClassifyInclude(fileinfo, include, is_system)) | 2129 _ClassifyInclude(fileinfo, include, is_system)) |
2081 if error_message: | 2130 if error_message: |
2082 error(filename, linenum, 'build/include_order', 4, | 2131 error(filename, linenum, 'build/include_order', 4, |
2083 '%s. Should be: %s.h, c system, c++ system, other.' % | 2132 '%s. Should be: %s.h, c system, c++ system, other.' % |
2084 (error_message, fileinfo.BaseName())) | 2133 (error_message, fileinfo.BaseName())) |
2085 | 2134 |
| 2135 # Look for any of the stream classes that are part of standard C++. |
| 2136 match = _RE_PATTERN_INCLUDE.match(line) |
| 2137 if match: |
| 2138 include = match.group(2) |
| 2139 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): |
| 2140 # Many unit tests use cout, so we exempt them. |
| 2141 if not _IsTestFilename(filename): |
| 2142 error(filename, linenum, 'readability/streams', 3, |
| 2143 'Streams are highly discouraged.') |
| 2144 |
| 2145 def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state, |
| 2146 error): |
| 2147 """Checks rules from the 'C++ language rules' section of cppguide.html. |
| 2148 |
| 2149 Some of these rules are hard to test (function overloading, using |
| 2150 uint32 inappropriately), but we do the best we can. |
| 2151 |
| 2152 Args: |
| 2153 filename: The name of the current file. |
| 2154 clean_lines: A CleansedLines instance containing the file. |
| 2155 linenum: The number of the line to check. |
| 2156 file_extension: The extension (without the dot) of the filename. |
| 2157 include_state: An _IncludeState instance in which the headers are inserted. |
| 2158 error: The function to call with any errors found. |
| 2159 """ |
2086 # If the line is empty or consists of entirely a comment, no need to | 2160 # If the line is empty or consists of entirely a comment, no need to |
2087 # check it. | 2161 # check it. |
2088 line = clean_lines.elided[linenum] | 2162 line = clean_lines.elided[linenum] |
2089 if not line: | 2163 if not line: |
2090 return | 2164 return |
2091 | 2165 |
| 2166 match = _RE_PATTERN_INCLUDE.search(line) |
| 2167 if match: |
| 2168 CheckIncludeLine(filename, clean_lines, linenum, include_state, error) |
| 2169 return |
| 2170 |
2092 # Create an extended_line, which is the concatenation of the current and | 2171 # Create an extended_line, which is the concatenation of the current and |
2093 # next lines, for more effective checking of code that may span more than one | 2172 # next lines, for more effective checking of code that may span more than one |
2094 # line. | 2173 # line. |
2095 if linenum + 1 < clean_lines.NumLines(): | 2174 if linenum + 1 < clean_lines.NumLines(): |
2096 extended_line = line + clean_lines.elided[linenum + 1] | 2175 extended_line = line + clean_lines.elided[linenum + 1] |
2097 else: | 2176 else: |
2098 extended_line = line | 2177 extended_line = line |
2099 | 2178 |
2100 # Make Windows paths like Unix. | 2179 # Make Windows paths like Unix. |
2101 fullname = os.path.abspath(filename).replace('\\', '/') | 2180 fullname = os.path.abspath(filename).replace('\\', '/') |
2102 | 2181 |
2103 # TODO(unknown): figure out if they're using default arguments in fn proto. | 2182 # TODO(unknown): figure out if they're using default arguments in fn proto. |
2104 | 2183 |
2105 # Look for any of the stream classes that are part of standard C++. | |
2106 match = _RE_PATTERN_INCLUDE.match(line) | |
2107 if match: | |
2108 include = match.group(2) | |
2109 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): | |
2110 # Many unit tests use cout, so we exempt them. | |
2111 if not _IsTestFilename(filename): | |
2112 error(filename, linenum, 'readability/streams', 3, | |
2113 'Streams are highly discouraged.') | |
2114 | |
2115 # Check for non-const references in functions. This is tricky because & | 2184 # Check for non-const references in functions. This is tricky because & |
2116 # is also used to take the address of something. We allow <> for templates, | 2185 # is also used to take the address of something. We allow <> for templates, |
2117 # (ignoring whatever is between the braces) and : for classes. | 2186 # (ignoring whatever is between the braces) and : for classes. |
2118 # These are complicated re's. They try to capture the following: | 2187 # These are complicated re's. They try to capture the following: |
2119 # paren (for fn-prototype start), typename, &, varname. For the const | 2188 # paren (for fn-prototype start), typename, &, varname. For the const |
2120 # version, we're willing for const to be before typename or after | 2189 # version, we're willing for const to be before typename or after |
2121 # Don't check the implemention on same line. | 2190 # Don't check the implemention on same line. |
2122 fnline = line.split('{', 1)[0] | 2191 fnline = line.split('{', 1)[0] |
2123 if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) > | 2192 if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) > |
2124 len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?' | 2193 len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?' |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2421 ) | 2490 ) |
2422 | 2491 |
2423 _HEADERS_ACCEPTED_BUT_NOT_PROMOTED = { | 2492 _HEADERS_ACCEPTED_BUT_NOT_PROMOTED = { |
2424 # We can trust with reasonable confidence that map gives us pair<>, too. | 2493 # We can trust with reasonable confidence that map gives us pair<>, too. |
2425 'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap') | 2494 'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap') |
2426 } | 2495 } |
2427 | 2496 |
2428 _RE_PATTERN_STRING = re.compile(r'\bstring\b') | 2497 _RE_PATTERN_STRING = re.compile(r'\bstring\b') |
2429 | 2498 |
2430 _re_pattern_algorithm_header = [] | 2499 _re_pattern_algorithm_header = [] |
2431 for _template in ('copy', 'max', 'min', 'sort', 'swap'): | 2500 for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap', |
| 2501 'transform'): |
2432 # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or | 2502 # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or |
2433 # type::max(). | 2503 # type::max(). |
2434 _re_pattern_algorithm_header.append( | 2504 _re_pattern_algorithm_header.append( |
2435 (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), | 2505 (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), |
2436 _template, | 2506 _template, |
2437 '<algorithm>')) | 2507 '<algorithm>')) |
2438 | 2508 |
2439 _re_pattern_templates = [] | 2509 _re_pattern_templates = [] |
2440 for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: | 2510 for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: |
2441 for _template in _templates: | 2511 for _template in _templates: |
2442 _re_pattern_templates.append( | 2512 _re_pattern_templates.append( |
2443 (re.compile(r'(\<|\b)' + _template + r'\s*\<'), | 2513 (re.compile(r'(\<|\b)' + _template + r'\s*\<'), |
2444 _template + '<>', | 2514 _template + '<>', |
2445 _header)) | 2515 _header)) |
2446 | 2516 |
2447 | 2517 |
2448 def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error): | 2518 def FilesBelongToSameModule(filename_cc, filename_h): |
| 2519 """Check if these two filenames belong to the same module. |
| 2520 |
| 2521 The concept of a 'module' here is a as follows: |
| 2522 foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the |
| 2523 same 'module' if they are in the same directory. |
| 2524 some/path/public/xyzzy and some/path/internal/xyzzy are also considered |
| 2525 to belong to the same module here. |
| 2526 |
| 2527 If the filename_cc contains a longer path than the filename_h, for example, |
| 2528 '/absolute/path/to/base/sysinfo.cc', and this file would include |
| 2529 'base/sysinfo.h', this function also produces the prefix needed to open the |
| 2530 header. This is used by the caller of this function to more robustly open the |
| 2531 header file. We don't have access to the real include paths in this context, |
| 2532 so we need this guesswork here. |
| 2533 |
| 2534 Known bugs: tools/base/bar.cc and base/bar.h belong to the same module |
| 2535 according to this implementation. Because of this, this function gives |
| 2536 some false positives. This should be sufficiently rare in practice. |
| 2537 |
| 2538 Args: |
| 2539 filename_cc: is the path for the .cc file |
| 2540 filename_h: is the path for the header path |
| 2541 |
| 2542 Returns: |
| 2543 Tuple with a bool and a string: |
| 2544 bool: True if filename_cc and filename_h belong to the same module. |
| 2545 string: the additional prefix needed to open the header file. |
| 2546 """ |
| 2547 |
| 2548 if not filename_cc.endswith('.cc'): |
| 2549 return (False, '') |
| 2550 filename_cc = filename_cc[:-len('.cc')] |
| 2551 if filename_cc.endswith('_unittest'): |
| 2552 filename_cc = filename_cc[:-len('_unittest')] |
| 2553 elif filename_cc.endswith('_test'): |
| 2554 filename_cc = filename_cc[:-len('_test')] |
| 2555 filename_cc = filename_cc.replace('/public/', '/') |
| 2556 filename_cc = filename_cc.replace('/internal/', '/') |
| 2557 |
| 2558 if not filename_h.endswith('.h'): |
| 2559 return (False, '') |
| 2560 filename_h = filename_h[:-len('.h')] |
| 2561 if filename_h.endswith('-inl'): |
| 2562 filename_h = filename_h[:-len('-inl')] |
| 2563 filename_h = filename_h.replace('/public/', '/') |
| 2564 filename_h = filename_h.replace('/internal/', '/') |
| 2565 |
| 2566 files_belong_to_same_module = filename_cc.endswith(filename_h) |
| 2567 common_path = '' |
| 2568 if files_belong_to_same_module: |
| 2569 common_path = filename_cc[:-len(filename_h)] |
| 2570 return files_belong_to_same_module, common_path |
| 2571 |
| 2572 |
| 2573 def UpdateIncludeState(filename, include_state, io=codecs): |
| 2574 """Fill up the include_state with new includes found from the file. |
| 2575 |
| 2576 Args: |
| 2577 filename: the name of the header to read. |
| 2578 include_state: an _IncludeState instance in which the headers are inserted. |
| 2579 io: The io factory to use to read the file. Provided for testability. |
| 2580 |
| 2581 Returns: |
| 2582 True if a header was succesfully added. False otherwise. |
| 2583 """ |
| 2584 headerfile = None |
| 2585 try: |
| 2586 headerfile = io.open(filename, 'r', 'utf8', 'replace') |
| 2587 except IOError: |
| 2588 return False |
| 2589 linenum = 0 |
| 2590 for line in headerfile: |
| 2591 linenum += 1 |
| 2592 clean_line = CleanseComments(line) |
| 2593 match = _RE_PATTERN_INCLUDE.search(clean_line) |
| 2594 if match: |
| 2595 include = match.group(2) |
| 2596 # The value formatting is cute, but not really used right now. |
| 2597 # What matters here is that the key is in include_state. |
| 2598 include_state.setdefault(include, '%s:%d' % (filename, linenum)) |
| 2599 return True |
| 2600 |
| 2601 |
| 2602 def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, |
| 2603 io=codecs): |
2449 """Reports for missing stl includes. | 2604 """Reports for missing stl includes. |
2450 | 2605 |
2451 This function will output warnings to make sure you are including the headers | 2606 This function will output warnings to make sure you are including the headers |
2452 necessary for the stl containers and functions that you use. We only give one | 2607 necessary for the stl containers and functions that you use. We only give one |
2453 reason to include a header. For example, if you use both equal_to<> and | 2608 reason to include a header. For example, if you use both equal_to<> and |
2454 less<> in a .h file, only one (the latter in the file) of these will be | 2609 less<> in a .h file, only one (the latter in the file) of these will be |
2455 reported as a reason to include the <functional>. | 2610 reported as a reason to include the <functional>. |
2456 | 2611 |
2457 We only check headers. We do not check inside cc-files. .cc files should be | |
2458 able to depend on their respective header files for includes. However, there | |
2459 is no simple way of producing this logic here. | |
2460 | |
2461 Args: | 2612 Args: |
2462 filename: The name of the current file. | 2613 filename: The name of the current file. |
2463 clean_lines: A CleansedLines instance containing the file. | 2614 clean_lines: A CleansedLines instance containing the file. |
2464 include_state: An _IncludeState instance. | 2615 include_state: An _IncludeState instance. |
2465 error: The function to call with any errors found. | 2616 error: The function to call with any errors found. |
| 2617 io: The IO factory to use to read the header file. Provided for unittest |
| 2618 injection. |
2466 """ | 2619 """ |
2467 if filename.endswith('.cc'): | |
2468 return | |
2469 | |
2470 required = {} # A map of header name to linenumber and the template entity. | 2620 required = {} # A map of header name to linenumber and the template entity. |
2471 # Example of required: { '<functional>': (1219, 'less<>') } | 2621 # Example of required: { '<functional>': (1219, 'less<>') } |
2472 | 2622 |
2473 for linenum in xrange(clean_lines.NumLines()): | 2623 for linenum in xrange(clean_lines.NumLines()): |
2474 line = clean_lines.elided[linenum] | 2624 line = clean_lines.elided[linenum] |
2475 if not line or line[0] == '#': | 2625 if not line or line[0] == '#': |
2476 continue | 2626 continue |
2477 | 2627 |
2478 # String is special -- it is a non-templatized type in STL. | 2628 # String is special -- it is a non-templatized type in STL. |
2479 if _RE_PATTERN_STRING.search(line): | 2629 if _RE_PATTERN_STRING.search(line): |
2480 required['<string>'] = (linenum, 'string') | 2630 required['<string>'] = (linenum, 'string') |
2481 | 2631 |
2482 for pattern, template, header in _re_pattern_algorithm_header: | 2632 for pattern, template, header in _re_pattern_algorithm_header: |
2483 if pattern.search(line): | 2633 if pattern.search(line): |
2484 required[header] = (linenum, template) | 2634 required[header] = (linenum, template) |
2485 | 2635 |
2486 # The following function is just a speed up, no semantics are changed. | 2636 # The following function is just a speed up, no semantics are changed. |
2487 if not '<' in line: # Reduces the cpu time usage by skipping lines. | 2637 if not '<' in line: # Reduces the cpu time usage by skipping lines. |
2488 continue | 2638 continue |
2489 | 2639 |
2490 for pattern, template, header in _re_pattern_templates: | 2640 for pattern, template, header in _re_pattern_templates: |
2491 if pattern.search(line): | 2641 if pattern.search(line): |
2492 required[header] = (linenum, template) | 2642 required[header] = (linenum, template) |
2493 | 2643 |
| 2644 # The policy is that if you #include something in foo.h you don't need to |
| 2645 # include it again in foo.cc. Here, we will look at possible includes. |
| 2646 # Let's copy the include_state so it is only messed up within this function. |
| 2647 include_state = include_state.copy() |
| 2648 |
| 2649 # Did we find the header for this file (if any) and succesfully load it? |
| 2650 header_found = False |
| 2651 |
| 2652 # Use the absolute path so that matching works properly. |
| 2653 abs_filename = os.path.abspath(filename) |
| 2654 |
| 2655 # For Emacs's flymake. |
| 2656 # If cpplint is invoked from Emacs's flymake, a temporary file is generated |
| 2657 # by flymake and that file name might end with '_flymake.cc'. In that case, |
| 2658 # restore original file name here so that the corresponding header file can be |
| 2659 # found. |
| 2660 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' |
| 2661 # instead of 'foo_flymake.h' |
| 2662 emacs_flymake_suffix = '_flymake.cc' |
| 2663 if abs_filename.endswith(emacs_flymake_suffix): |
| 2664 abs_filename = abs_filename[:-len(emacs_flymake_suffix)] + '.cc' |
| 2665 |
| 2666 # include_state is modified during iteration, so we iterate over a copy of |
| 2667 # the keys. |
| 2668 for header in include_state.keys(): #NOLINT |
| 2669 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) |
| 2670 fullpath = common_path + header |
| 2671 if same_module and UpdateIncludeState(fullpath, include_state, io): |
| 2672 header_found = True |
| 2673 |
| 2674 # If we can't find the header file for a .cc, assume it's because we don't |
| 2675 # know where to look. In that case we'll give up as we're not sure they |
| 2676 # didn't include it in the .h file. |
| 2677 # TODO(unknown): Do a better job of finding .h files so we are confident that |
| 2678 # not having the .h file means there isn't one. |
| 2679 if filename.endswith('.cc') and not header_found: |
| 2680 return |
| 2681 |
2494 # All the lines have been processed, report the errors found. | 2682 # All the lines have been processed, report the errors found. |
2495 for required_header_unstripped in required: | 2683 for required_header_unstripped in required: |
2496 template = required[required_header_unstripped][1] | 2684 template = required[required_header_unstripped][1] |
2497 if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED: | 2685 if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED: |
2498 headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template] | 2686 headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template] |
2499 if [True for header in headers if header in include_state]: | 2687 if [True for header in headers if header in include_state]: |
2500 continue | 2688 continue |
2501 if required_header_unstripped.strip('<>"') not in include_state: | 2689 if required_header_unstripped.strip('<>"') not in include_state: |
2502 error(filename, required[required_header_unstripped][0], | 2690 error(filename, required[required_header_unstripped][0], |
2503 'build/include_what_you_use', 4, | 2691 'build/include_what_you_use', 4, |
(...skipping 23 matching lines...) Expand all Loading... |
2527 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) | 2715 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) |
2528 if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines | 2716 if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines |
2529 return | 2717 return |
2530 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) | 2718 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) |
2531 CheckStyle(filename, clean_lines, line, file_extension, error) | 2719 CheckStyle(filename, clean_lines, line, file_extension, error) |
2532 CheckLanguage(filename, clean_lines, line, file_extension, include_state, | 2720 CheckLanguage(filename, clean_lines, line, file_extension, include_state, |
2533 error) | 2721 error) |
2534 CheckForNonStandardConstructs(filename, clean_lines, line, | 2722 CheckForNonStandardConstructs(filename, clean_lines, line, |
2535 class_state, error) | 2723 class_state, error) |
2536 CheckPosixThreading(filename, clean_lines, line, error) | 2724 CheckPosixThreading(filename, clean_lines, line, error) |
| 2725 CheckInvalidIncrement(filename, clean_lines, line, error) |
2537 | 2726 |
2538 | 2727 |
2539 def ProcessFileData(filename, file_extension, lines, error): | 2728 def ProcessFileData(filename, file_extension, lines, error): |
2540 """Performs lint checks and reports any errors to the given error function. | 2729 """Performs lint checks and reports any errors to the given error function. |
2541 | 2730 |
2542 Args: | 2731 Args: |
2543 filename: Filename of the file that is being processed. | 2732 filename: Filename of the file that is being processed. |
2544 file_extension: The extension (dot not included) of the file. | 2733 file_extension: The extension (dot not included) of the file. |
2545 lines: An array of strings, each representing a line of the file, with the | 2734 lines: An array of strings, each representing a line of the file, with the |
2546 last element being empty if the file is termined with a newline. | 2735 last element being empty if the file is termined with a newline. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2684 if opt == '--help': | 2873 if opt == '--help': |
2685 PrintUsage(None) | 2874 PrintUsage(None) |
2686 elif opt == '--output': | 2875 elif opt == '--output': |
2687 if not val in ('emacs', 'vs7'): | 2876 if not val in ('emacs', 'vs7'): |
2688 PrintUsage('The only allowed output formats are emacs and vs7.') | 2877 PrintUsage('The only allowed output formats are emacs and vs7.') |
2689 output_format = val | 2878 output_format = val |
2690 elif opt == '--verbose': | 2879 elif opt == '--verbose': |
2691 verbosity = int(val) | 2880 verbosity = int(val) |
2692 elif opt == '--filter': | 2881 elif opt == '--filter': |
2693 filters = val | 2882 filters = val |
2694 if filters == '': | 2883 if not filters: |
2695 PrintCategories() | 2884 PrintCategories() |
2696 | 2885 |
2697 if not filenames: | 2886 if not filenames: |
2698 PrintUsage('No files were specified.') | 2887 PrintUsage('No files were specified.') |
2699 | 2888 |
2700 _SetOutputFormat(output_format) | 2889 _SetOutputFormat(output_format) |
2701 _SetVerboseLevel(verbosity) | 2890 _SetVerboseLevel(verbosity) |
2702 _SetFilters(filters) | 2891 _SetFilters(filters) |
2703 | 2892 |
2704 return filenames | 2893 return filenames |
(...skipping 11 matching lines...) Expand all Loading... |
2716 | 2905 |
2717 _cpplint_state.ResetErrorCount() | 2906 _cpplint_state.ResetErrorCount() |
2718 for filename in filenames: | 2907 for filename in filenames: |
2719 ProcessFile(filename, _cpplint_state.verbose_level) | 2908 ProcessFile(filename, _cpplint_state.verbose_level) |
2720 sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count) | 2909 sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count) |
2721 sys.exit(_cpplint_state.error_count > 0) | 2910 sys.exit(_cpplint_state.error_count > 0) |
2722 | 2911 |
2723 | 2912 |
2724 if __name__ == '__main__': | 2913 if __name__ == '__main__': |
2725 main() | 2914 main() |
OLD | NEW |