Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1101)

Side by Side Diff: cpplint.py

Issue 5186001: Update cpplint.py to r62. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 # up the directory tree for the top of the SVN checkout 705 # up the directory tree for the top of the SVN checkout
649 root_dir = project_dir 706 root_dir = project_dir
650 one_up_dir = os.path.dirname(root_dir) 707 one_up_dir = os.path.dirname(root_dir)
651 while os.path.exists(os.path.join(one_up_dir, ".svn")): 708 while os.path.exists(os.path.join(one_up_dir, ".svn")):
652 root_dir = os.path.dirname(root_dir) 709 root_dir = os.path.dirname(root_dir)
653 one_up_dir = os.path.dirname(one_up_dir) 710 one_up_dir = os.path.dirname(one_up_dir)
654 711
655 prefix = os.path.commonprefix([root_dir, project_dir]) 712 prefix = os.path.commonprefix([root_dir, project_dir])
656 return fullname[len(prefix) + 1:] 713 return fullname[len(prefix) + 1:]
657 714
658 # Not SVN? Try to find a git top level directory by searching up from the 715 # Not SVN? Try to find a git or hg top level directory by searching up
659 # current path. 716 # from the current path.
660 root_dir = os.path.dirname(fullname) 717 root_dir = os.path.dirname(fullname)
661 while (root_dir != os.path.dirname(root_dir) and 718 while (root_dir != os.path.dirname(root_dir) and
662 not os.path.exists(os.path.join(root_dir, ".git"))): 719 not os.path.exists(os.path.join(root_dir, ".git")) and
720 not os.path.exists(os.path.join(root_dir, ".hg"))):
663 root_dir = os.path.dirname(root_dir) 721 root_dir = os.path.dirname(root_dir)
664 if os.path.exists(os.path.join(root_dir, ".git")): 722
665 prefix = os.path.commonprefix([root_dir, project_dir]) 723 if (os.path.exists(os.path.join(root_dir, ".git")) or
666 return fullname[len(prefix) + 1:] 724 os.path.exists(os.path.join(root_dir, ".hg"))):
725 prefix = os.path.commonprefix([root_dir, project_dir])
726 return fullname[len(prefix) + 1:]
667 727
668 # Don't know what to do; header guard warnings may be wrong... 728 # Don't know what to do; header guard warnings may be wrong...
669 return fullname 729 return fullname
670 730
671 def Split(self): 731 def Split(self):
672 """Splits the file into the directory, basename, and extension. 732 """Splits the file into the directory, basename, and extension.
673 733
674 For 'chrome/browser/browser.cc', Split() would 734 For 'chrome/browser/browser.cc', Split() would
675 return ('chrome/browser', 'browser', '.cc') 735 return ('chrome/browser', 'browser', '.cc')
676 736
(...skipping 15 matching lines...) Expand all
692 752
693 def NoExtension(self): 753 def NoExtension(self):
694 """File has no source file extension.""" 754 """File has no source file extension."""
695 return '/'.join(self.Split()[0:2]) 755 return '/'.join(self.Split()[0:2])
696 756
697 def IsSource(self): 757 def IsSource(self):
698 """File has a source file extension.""" 758 """File has a source file extension."""
699 return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') 759 return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
700 760
701 761
702 def _ShouldPrintError(category, confidence): 762 def _ShouldPrintError(category, confidence, linenum):
703 """Returns true iff confidence >= verbose, and category passes filter.""" 763 """Returns true iff confidence >= verbose, category passes
704 # There are two ways we might decide not to print an error message: 764 filter and is not NOLINT-suppressed."""
765
766 # There are three ways we might decide not to print an error message:
767 # a "NOLINT(category)" comment appears in the source,
705 # the verbosity level isn't high enough, or the filters filter it out. 768 # the verbosity level isn't high enough, or the filters filter it out.
769 if IsErrorSuppressedByNolint(category, linenum):
770 return False
706 if confidence < _cpplint_state.verbose_level: 771 if confidence < _cpplint_state.verbose_level:
707 return False 772 return False
708 773
709 is_filtered = False 774 is_filtered = False
710 for one_filter in _Filters(): 775 for one_filter in _Filters():
711 if one_filter.startswith('-'): 776 if one_filter.startswith('-'):
712 if category.startswith(one_filter[1:]): 777 if category.startswith(one_filter[1:]):
713 is_filtered = True 778 is_filtered = True
714 elif one_filter.startswith('+'): 779 elif one_filter.startswith('+'):
715 if category.startswith(one_filter[1:]): 780 if category.startswith(one_filter[1:]):
716 is_filtered = False 781 is_filtered = False
717 else: 782 else:
718 assert False # should have been checked for in SetFilter. 783 assert False # should have been checked for in SetFilter.
719 if is_filtered: 784 if is_filtered:
720 return False 785 return False
721 786
722 return True 787 return True
723 788
724 789
725 def Error(filename, linenum, category, confidence, message): 790 def Error(filename, linenum, category, confidence, message):
726 """Logs the fact we've found a lint error. 791 """Logs the fact we've found a lint error.
727 792
728 We log where the error was found, and also our confidence in the error, 793 We log where the error was found, and also our confidence in the error,
729 that is, how certain we are this is a legitimate style regression, and 794 that is, how certain we are this is a legitimate style regression, and
730 not a misidentification or a use that's sometimes justified. 795 not a misidentification or a use that's sometimes justified.
731 796
797 False positives can be suppressed by the use of
798 "cpplint(category)" comments on the offending line. These are
799 parsed into _error_suppressions.
800
732 Args: 801 Args:
733 filename: The name of the file containing the error. 802 filename: The name of the file containing the error.
734 linenum: The number of the line containing the error. 803 linenum: The number of the line containing the error.
735 category: A string used to describe the "category" this bug 804 category: A string used to describe the "category" this bug
736 falls under: "whitespace", say, or "runtime". Categories 805 falls under: "whitespace", say, or "runtime". Categories
737 may have a hierarchy separated by slashes: "whitespace/indent". 806 may have a hierarchy separated by slashes: "whitespace/indent".
738 confidence: A number from 1-5 representing a confidence score for 807 confidence: A number from 1-5 representing a confidence score for
739 the error, with 5 meaning that we are certain of the problem, 808 the error, with 5 meaning that we are certain of the problem,
740 and 1 meaning that it could be a legitimate construct. 809 and 1 meaning that it could be a legitimate construct.
741 message: The error message. 810 message: The error message.
742 """ 811 """
743 # There are two ways we might decide not to print an error message: 812 if _ShouldPrintError(category, confidence, linenum):
744 # the verbosity level isn't high enough, or the filters filter it out.
745 if _ShouldPrintError(category, confidence):
746 _cpplint_state.IncrementErrorCount(category) 813 _cpplint_state.IncrementErrorCount(category)
747 if _cpplint_state.output_format == 'vs7': 814 if _cpplint_state.output_format == 'vs7':
748 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( 815 sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
749 filename, linenum, message, category, confidence)) 816 filename, linenum, message, category, confidence))
750 else: 817 else:
751 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( 818 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
752 filename, linenum, message, category, confidence)) 819 filename, linenum, message, category, confidence))
753 820
754 821
755 # Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard. 822 # 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
953 1020
954 Args: 1021 Args:
955 filename: The name of a C++ header file. 1022 filename: The name of a C++ header file.
956 1023
957 Returns: 1024 Returns:
958 The CPP variable that should be used as a header guard in the 1025 The CPP variable that should be used as a header guard in the
959 named file. 1026 named file.
960 1027
961 """ 1028 """
962 1029
1030 # Restores original filename in case that cpplint is invoked from Emacs's
1031 # flymake.
1032 filename = re.sub(r'_flymake\.h$', '.h', filename)
1033
963 fileinfo = FileInfo(filename) 1034 fileinfo = FileInfo(filename)
964 return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_' 1035 return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper() + '_'
965 1036
966 1037
967 def CheckForHeaderGuard(filename, lines, error): 1038 def CheckForHeaderGuard(filename, lines, error):
968 """Checks that the file contains a header guard. 1039 """Checks that the file contains a header guard.
969 1040
970 Logs an error if no #ifndef header guard is present. For other 1041 Logs an error if no #ifndef header guard is present. For other
971 headers, checks that the full pathname is used. 1042 headers, checks that the full pathname is used.
972 1043
(...skipping 26 matching lines...) Expand all
999 endif_linenum = linenum 1070 endif_linenum = linenum
1000 1071
1001 if not ifndef or not define or ifndef != define: 1072 if not ifndef or not define or ifndef != define:
1002 error(filename, 0, 'build/header_guard', 5, 1073 error(filename, 0, 'build/header_guard', 5,
1003 'No #ifndef header guard found, suggested CPP variable is: %s' % 1074 'No #ifndef header guard found, suggested CPP variable is: %s' %
1004 cppvar) 1075 cppvar)
1005 return 1076 return
1006 1077
1007 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ 1078 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
1008 # for backward compatibility. 1079 # for backward compatibility.
1009 if ifndef != cppvar and not Search(r'\bNOLINT\b', lines[ifndef_linenum]): 1080 if ifndef != cppvar:
1010 error_level = 0 1081 error_level = 0
1011 if ifndef != cppvar + '_': 1082 if ifndef != cppvar + '_':
1012 error_level = 5 1083 error_level = 5
1013 1084
1085 ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum,
1086 error)
1014 error(filename, ifndef_linenum, 'build/header_guard', error_level, 1087 error(filename, ifndef_linenum, 'build/header_guard', error_level,
1015 '#ifndef header guard has wrong style, please use: %s' % cppvar) 1088 '#ifndef header guard has wrong style, please use: %s' % cppvar)
1016 1089
1017 if (endif != ('#endif // %s' % cppvar) and 1090 if endif != ('#endif // %s' % cppvar):
1018 not Search(r'\bNOLINT\b', lines[endif_linenum])):
1019 error_level = 0 1091 error_level = 0
1020 if endif != ('#endif // %s' % (cppvar + '_')): 1092 if endif != ('#endif // %s' % (cppvar + '_')):
1021 error_level = 5 1093 error_level = 5
1022 1094
1095 ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum,
1096 error)
1023 error(filename, endif_linenum, 'build/header_guard', error_level, 1097 error(filename, endif_linenum, 'build/header_guard', error_level,
1024 '#endif line should be "#endif // %s"' % cppvar) 1098 '#endif line should be "#endif // %s"' % cppvar)
1025 1099
1026 1100
1027 def CheckForUnicodeReplacementCharacters(filename, lines, error): 1101 def CheckForUnicodeReplacementCharacters(filename, lines, error):
1028 """Logs an error for each line containing Unicode replacement characters. 1102 """Logs an error for each line containing Unicode replacement characters.
1029 1103
1030 These indicate that either the file contained invalid UTF-8 (likely) 1104 These indicate that either the file contained invalid UTF-8 (likely)
1031 or Unicode replacement characters (which it shouldn't). Note that 1105 or Unicode replacement characters (which it shouldn't). Note that
1032 it's possible for this to throw off line numbering if the invalid 1106 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
1510 function += parameter_regexp.group(1) 1584 function += parameter_regexp.group(1)
1511 else: 1585 else:
1512 function += '()' 1586 function += '()'
1513 function_state.Begin(function) 1587 function_state.Begin(function)
1514 break 1588 break
1515 if not body_found: 1589 if not body_found:
1516 # No body for the function (or evidence of a non-function) was found. 1590 # No body for the function (or evidence of a non-function) was found.
1517 error(filename, linenum, 'readability/fn_size', 5, 1591 error(filename, linenum, 'readability/fn_size', 5,
1518 'Lint failed to find start of function body.') 1592 'Lint failed to find start of function body.')
1519 elif Match(r'^\}\s*$', line): # function end 1593 elif Match(r'^\}\s*$', line): # function end
1520 if not Search(r'\bNOLINT\b', raw_line): 1594 function_state.Check(error, filename, linenum)
1521 function_state.Check(error, filename, linenum)
1522 function_state.End() 1595 function_state.End()
1523 elif not Match(r'^\s*$', line): 1596 elif not Match(r'^\s*$', line):
1524 function_state.Count() # Count non-blank/non-comment lines. 1597 function_state.Count() # Count non-blank/non-comment lines.
1525 1598
1526 1599
1527 _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') 1600 _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
1528 1601
1529 1602
1530 def CheckComment(comment, filename, linenum, error): 1603 def CheckComment(comment, filename, linenum, error):
1531 """Checks for common mistakes in TODO comments. 1604 """Checks for common mistakes in TODO comments.
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 (commentpos >= 2 and 1729 (commentpos >= 2 and
1657 line[commentpos-2] not in string.whitespace))): 1730 line[commentpos-2] not in string.whitespace))):
1658 error(filename, linenum, 'whitespace/comments', 2, 1731 error(filename, linenum, 'whitespace/comments', 2,
1659 'At least two spaces is best between code and comments') 1732 'At least two spaces is best between code and comments')
1660 # There should always be a space between the // and the comment 1733 # There should always be a space between the // and the comment
1661 commentend = commentpos + 2 1734 commentend = commentpos + 2
1662 if commentend < len(line) and not line[commentend] == ' ': 1735 if commentend < len(line) and not line[commentend] == ' ':
1663 # but some lines are exceptions -- e.g. if they're big 1736 # but some lines are exceptions -- e.g. if they're big
1664 # comment delimiters like: 1737 # comment delimiters like:
1665 # //---------------------------------------------------------- 1738 # //----------------------------------------------------------
1739 # or are an empty C++ style Doxygen comment, like:
1740 # ///
1666 # or they begin with multiple slashes followed by a space: 1741 # or they begin with multiple slashes followed by a space:
1667 # //////// Header comment 1742 # //////// Header comment
1668 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or 1743 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
1744 Search(r'^/$', line[commentend:]) or
1669 Search(r'^/+ ', line[commentend:])) 1745 Search(r'^/+ ', line[commentend:]))
1670 if not match: 1746 if not match:
1671 error(filename, linenum, 'whitespace/comments', 4, 1747 error(filename, linenum, 'whitespace/comments', 4,
1672 'Should have a space between // and comment') 1748 'Should have a space between // and comment')
1673 CheckComment(line[commentpos:], filename, linenum, error) 1749 CheckComment(line[commentpos:], filename, linenum, error)
1674 1750
1675 line = clean_lines.elided[linenum] # get rid of comments and strings 1751 line = clean_lines.elided[linenum] # get rid of comments and strings
1676 1752
1677 # Don't try to do spacing checks for operator methods 1753 # Don't try to do spacing checks for operator methods
1678 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) 1754 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 elif ((initial_spaces == 1 or initial_spaces == 3) and 2094 elif ((initial_spaces == 1 or initial_spaces == 3) and
2019 not Match(r'\s*\w+\s*:\s*$', cleansed_line)): 2095 not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
2020 error(filename, linenum, 'whitespace/indent', 3, 2096 error(filename, linenum, 'whitespace/indent', 3,
2021 'Weird number of spaces at line-start. ' 2097 'Weird number of spaces at line-start. '
2022 'Are you using a 2-space indent?') 2098 'Are you using a 2-space indent?')
2023 # Labels should always be indented at least one space. 2099 # Labels should always be indented at least one space.
2024 elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$', 2100 elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
2025 line): 2101 line):
2026 error(filename, linenum, 'whitespace/labels', 4, 2102 error(filename, linenum, 'whitespace/labels', 4,
2027 'Labels should always be indented at least one space. ' 2103 'Labels should always be indented at least one space. '
2028 'If this is a member-initializer list in a constructor, ' 2104 'If this is a member-initializer list in a constructor or '
2029 'the colon should be on the line after the definition header.') 2105 'the base class list in a class definition, the colon should '
2106 'be on the following line.')
2107
2030 2108
2031 # Check if the line is a header guard. 2109 # Check if the line is a header guard.
2032 is_header_guard = False 2110 is_header_guard = False
2033 if file_extension == 'h': 2111 if file_extension == 'h':
2034 cppvar = GetHeaderGuardCPPVariable(filename) 2112 cppvar = GetHeaderGuardCPPVariable(filename)
2035 if (line.startswith('#ifndef %s' % cppvar) or 2113 if (line.startswith('#ifndef %s' % cppvar) or
2036 line.startswith('#define %s' % cppvar) or 2114 line.startswith('#define %s' % cppvar) or
2037 line.startswith('#endif // %s' % cppvar)): 2115 line.startswith('#endif // %s' % cppvar)):
2038 is_header_guard = True 2116 is_header_guard = True
2039 # #include lines and header guards can be long, since there's no clean way to 2117 # #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
2392 error(filename, linenum, 'runtime/int', 4, 2470 error(filename, linenum, 'runtime/int', 4,
2393 'Use "unsigned short" for ports, not "short"') 2471 'Use "unsigned short" for ports, not "short"')
2394 else: 2472 else:
2395 match = Search(r'\b(short|long(?! +double)|long long)\b', line) 2473 match = Search(r'\b(short|long(?! +double)|long long)\b', line)
2396 if match: 2474 if match:
2397 error(filename, linenum, 'runtime/int', 4, 2475 error(filename, linenum, 'runtime/int', 4,
2398 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) 2476 'Use int16/int64/etc, rather than the C type %s' % match.group(1))
2399 2477
2400 # When snprintf is used, the second argument shouldn't be a literal. 2478 # When snprintf is used, the second argument shouldn't be a literal.
2401 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) 2479 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
2402 if match: 2480 if match and match.group(2) != '0':
2481 # If 2nd arg is zero, snprintf is used to calculate size.
2403 error(filename, linenum, 'runtime/printf', 3, 2482 error(filename, linenum, 'runtime/printf', 3,
2404 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' 2483 'If you can, use sizeof(%s) instead of %s as the 2nd arg '
2405 'to snprintf.' % (match.group(1), match.group(2))) 2484 'to snprintf.' % (match.group(1), match.group(2)))
2406 2485
2407 # Check if some verboten C functions are being used. 2486 # Check if some verboten C functions are being used.
2408 if Search(r'\bsprintf\b', line): 2487 if Search(r'\bsprintf\b', line):
2409 error(filename, linenum, 'runtime/printf', 5, 2488 error(filename, linenum, 'runtime/printf', 5,
2410 'Never use sprintf. Use snprintf instead.') 2489 'Never use sprintf. Use snprintf instead.')
2411 match = Search(r'\b(strcpy|strcat)\b', line) 2490 match = Search(r'\b(strcpy|strcat)\b', line)
2412 if match: 2491 if match:
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 """ 2820 """
2742 required = {} # A map of header name to linenumber and the template entity. 2821 required = {} # A map of header name to linenumber and the template entity.
2743 # Example of required: { '<functional>': (1219, 'less<>') } 2822 # Example of required: { '<functional>': (1219, 'less<>') }
2744 2823
2745 for linenum in xrange(clean_lines.NumLines()): 2824 for linenum in xrange(clean_lines.NumLines()):
2746 line = clean_lines.elided[linenum] 2825 line = clean_lines.elided[linenum]
2747 if not line or line[0] == '#': 2826 if not line or line[0] == '#':
2748 continue 2827 continue
2749 2828
2750 # String is special -- it is a non-templatized type in STL. 2829 # String is special -- it is a non-templatized type in STL.
2751 if _RE_PATTERN_STRING.search(line): 2830 m = _RE_PATTERN_STRING.search(line)
2752 required['<string>'] = (linenum, 'string') 2831 if m:
2832 # Don't warn about strings in non-STL namespaces:
2833 # (We check only the first match per line; good enough.)
2834 prefix = line[:m.start()]
2835 if prefix.endswith('std::') or not prefix.endswith('::'):
2836 required['<string>'] = (linenum, 'string')
2753 2837
2754 for pattern, template, header in _re_pattern_algorithm_header: 2838 for pattern, template, header in _re_pattern_algorithm_header:
2755 if pattern.search(line): 2839 if pattern.search(line):
2756 required[header] = (linenum, template) 2840 required[header] = (linenum, template)
2757 2841
2758 # The following function is just a speed up, no semantics are changed. 2842 # The following function is just a speed up, no semantics are changed.
2759 if not '<' in line: # Reduces the cpu time usage by skipping lines. 2843 if not '<' in line: # Reduces the cpu time usage by skipping lines.
2760 continue 2844 continue
2761 2845
2762 for pattern, template, header in _re_pattern_templates: 2846 for pattern, template, header in _re_pattern_templates:
(...skipping 11 matching lines...) Expand all
2774 # Use the absolute path so that matching works properly. 2858 # Use the absolute path so that matching works properly.
2775 abs_filename = os.path.abspath(filename) 2859 abs_filename = os.path.abspath(filename)
2776 2860
2777 # For Emacs's flymake. 2861 # For Emacs's flymake.
2778 # If cpplint is invoked from Emacs's flymake, a temporary file is generated 2862 # If cpplint is invoked from Emacs's flymake, a temporary file is generated
2779 # by flymake and that file name might end with '_flymake.cc'. In that case, 2863 # by flymake and that file name might end with '_flymake.cc'. In that case,
2780 # restore original file name here so that the corresponding header file can be 2864 # restore original file name here so that the corresponding header file can be
2781 # found. 2865 # found.
2782 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' 2866 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
2783 # instead of 'foo_flymake.h' 2867 # instead of 'foo_flymake.h'
2784 emacs_flymake_suffix = '_flymake.cc' 2868 abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename)
2785 if abs_filename.endswith(emacs_flymake_suffix):
2786 abs_filename = abs_filename[:-len(emacs_flymake_suffix)] + '.cc'
2787 2869
2788 # include_state is modified during iteration, so we iterate over a copy of 2870 # include_state is modified during iteration, so we iterate over a copy of
2789 # the keys. 2871 # the keys.
2790 for header in include_state.keys(): #NOLINT 2872 for header in include_state.keys(): #NOLINT
2791 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) 2873 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
2792 fullpath = common_path + header 2874 fullpath = common_path + header
2793 if same_module and UpdateIncludeState(fullpath, include_state, io): 2875 if same_module and UpdateIncludeState(fullpath, include_state, io):
2794 header_found = True 2876 header_found = True
2795 2877
2796 # If we can't find the header file for a .cc, assume it's because we don't 2878 # If we can't find the header file for a .cc, assume it's because we don't
(...skipping 30 matching lines...) Expand all
2827 line: Number of line being processed. 2909 line: Number of line being processed.
2828 include_state: An _IncludeState instance in which the headers are inserted. 2910 include_state: An _IncludeState instance in which the headers are inserted.
2829 function_state: A _FunctionState instance which counts function lines, etc. 2911 function_state: A _FunctionState instance which counts function lines, etc.
2830 class_state: A _ClassState instance which maintains information about 2912 class_state: A _ClassState instance which maintains information about
2831 the current stack of nested class declarations being parsed. 2913 the current stack of nested class declarations being parsed.
2832 error: A callable to which errors are reported, which takes 4 arguments: 2914 error: A callable to which errors are reported, which takes 4 arguments:
2833 filename, line number, error level, and message 2915 filename, line number, error level, and message
2834 2916
2835 """ 2917 """
2836 raw_lines = clean_lines.raw_lines 2918 raw_lines = clean_lines.raw_lines
2919 ParseNolintSuppressions(filename, raw_lines[line], line, error)
2837 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) 2920 CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
2838 if Search(r'\bNOLINT\b', raw_lines[line]): # ignore nolint lines
2839 return
2840 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) 2921 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
2841 CheckStyle(filename, clean_lines, line, file_extension, error) 2922 CheckStyle(filename, clean_lines, line, file_extension, error)
2842 CheckLanguage(filename, clean_lines, line, file_extension, include_state, 2923 CheckLanguage(filename, clean_lines, line, file_extension, include_state,
2843 error) 2924 error)
2844 CheckForNonStandardConstructs(filename, clean_lines, line, 2925 CheckForNonStandardConstructs(filename, clean_lines, line,
2845 class_state, error) 2926 class_state, error)
2846 CheckPosixThreading(filename, clean_lines, line, error) 2927 CheckPosixThreading(filename, clean_lines, line, error)
2847 CheckInvalidIncrement(filename, clean_lines, line, error) 2928 CheckInvalidIncrement(filename, clean_lines, line, error)
2848 2929
2849 2930
2850 def ProcessFileData(filename, file_extension, lines, error): 2931 def ProcessFileData(filename, file_extension, lines, error):
2851 """Performs lint checks and reports any errors to the given error function. 2932 """Performs lint checks and reports any errors to the given error function.
2852 2933
2853 Args: 2934 Args:
2854 filename: Filename of the file that is being processed. 2935 filename: Filename of the file that is being processed.
2855 file_extension: The extension (dot not included) of the file. 2936 file_extension: The extension (dot not included) of the file.
2856 lines: An array of strings, each representing a line of the file, with the 2937 lines: An array of strings, each representing a line of the file, with the
2857 last element being empty if the file is termined with a newline. 2938 last element being empty if the file is termined with a newline.
2858 error: A callable to which errors are reported, which takes 4 arguments: 2939 error: A callable to which errors are reported, which takes 4 arguments:
2859 """ 2940 """
2860 lines = (['// marker so line numbers and indices both start at 1'] + lines + 2941 lines = (['// marker so line numbers and indices both start at 1'] + lines +
2861 ['// marker so line numbers end in a known way']) 2942 ['// marker so line numbers end in a known way'])
2862 2943
2863 include_state = _IncludeState() 2944 include_state = _IncludeState()
2864 function_state = _FunctionState() 2945 function_state = _FunctionState()
2865 class_state = _ClassState() 2946 class_state = _ClassState()
2866 2947
2948 ResetNolintSuppressions()
2949
2867 CheckForCopyright(filename, lines, error) 2950 CheckForCopyright(filename, lines, error)
2868 2951
2869 if file_extension == 'h': 2952 if file_extension == 'h':
2870 CheckForHeaderGuard(filename, lines, error) 2953 CheckForHeaderGuard(filename, lines, error)
2871 2954
2872 RemoveMultiLineComments(filename, lines, error) 2955 RemoveMultiLineComments(filename, lines, error)
2873 clean_lines = CleansedLines(lines) 2956 clean_lines = CleansedLines(lines)
2874 for line in xrange(clean_lines.NumLines()): 2957 for line in xrange(clean_lines.NumLines()):
2875 ProcessLine(filename, file_extension, clean_lines, line, 2958 ProcessLine(filename, file_extension, clean_lines, line,
2876 include_state, function_state, class_state, error) 2959 include_state, function_state, class_state, error)
2877 class_state.CheckFinished(filename, error) 2960 class_state.CheckFinished(filename, error)
2878 2961
2879 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) 2962 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
2880 2963
2881 # We check here rather than inside ProcessLine so that we see raw 2964 # We check here rather than inside ProcessLine so that we see raw
2882 # lines rather than "cleaned" lines. 2965 # lines rather than "cleaned" lines.
2883 CheckForUnicodeReplacementCharacters(filename, lines, error) 2966 CheckForUnicodeReplacementCharacters(filename, lines, error)
2884 2967
2885 CheckForNewlineAtEOF(filename, lines, error) 2968 CheckForNewlineAtEOF(filename, lines, error)
2886 2969
2887
2888 def ProcessFile(filename, vlevel): 2970 def ProcessFile(filename, vlevel):
2889 """Does google-lint on a single file. 2971 """Does google-lint on a single file.
2890 2972
2891 Args: 2973 Args:
2892 filename: The name of the file to parse. 2974 filename: The name of the file to parse.
2893 2975
2894 vlevel: The level of errors to report. Every error of confidence 2976 vlevel: The level of errors to report. Every error of confidence
2895 >= verbose_level will be reported. 0 is a good default. 2977 >= verbose_level will be reported. 0 is a good default.
2896 """ 2978 """
2897 2979
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 sys.exit('\nFATAL ERROR: ' + message) 3041 sys.exit('\nFATAL ERROR: ' + message)
2960 else: 3042 else:
2961 sys.exit(1) 3043 sys.exit(1)
2962 3044
2963 3045
2964 def PrintCategories(): 3046 def PrintCategories():
2965 """Prints a list of all the error-categories used by error messages. 3047 """Prints a list of all the error-categories used by error messages.
2966 3048
2967 These are the categories used to filter messages via --filter. 3049 These are the categories used to filter messages via --filter.
2968 """ 3050 """
2969 sys.stderr.write(_ERROR_CATEGORIES) 3051 sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES))
2970 sys.exit(0) 3052 sys.exit(0)
2971 3053
2972 3054
2973 def ParseArguments(args): 3055 def ParseArguments(args):
2974 """Parses the command line arguments. 3056 """Parses the command line arguments.
2975 3057
2976 This may set the output format and verbosity level as side-effects. 3058 This may set the output format and verbosity level as side-effects.
2977 3059
2978 Args: 3060 Args:
2979 args: The command line arguments: 3061 args: The command line arguments:
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 _cpplint_state.ResetErrorCounts() 3117 _cpplint_state.ResetErrorCounts()
3036 for filename in filenames: 3118 for filename in filenames:
3037 ProcessFile(filename, _cpplint_state.verbose_level) 3119 ProcessFile(filename, _cpplint_state.verbose_level)
3038 _cpplint_state.PrintErrorCounts() 3120 _cpplint_state.PrintErrorCounts()
3039 3121
3040 sys.exit(_cpplint_state.error_count > 0) 3122 sys.exit(_cpplint_state.error_count > 0)
3041 3123
3042 3124
3043 if __name__ == '__main__': 3125 if __name__ == '__main__':
3044 main() 3126 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698