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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py

Issue 1839193004: Run auto-formatter (autopep8) on webkitpy. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 8 months 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
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 # 2 #
3 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved. 3 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved.
4 # Copyright (C) 2009 Torch Mobile Inc. 4 # Copyright (C) 2009 Torch Mobile Inc.
5 # Copyright (C) 2009 Apple Inc. All rights reserved. 5 # Copyright (C) 2009 Apple Inc. All rights reserved.
6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) 6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
7 # 7 #
8 # Redistribution and use in source and binary forms, with or without 8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are 9 # modification, are permitted provided that the following conditions are
10 # met: 10 # met:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 from webkitpy.common.system.filesystem import FileSystem 49 from webkitpy.common.system.filesystem import FileSystem
50 50
51 # Headers that we consider STL headers. 51 # Headers that we consider STL headers.
52 _STL_HEADERS = frozenset([ 52 _STL_HEADERS = frozenset([
53 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception', 53 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
54 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set', 54 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
55 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h', 55 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h',
56 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack', 56 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
57 'stl_alloc.h', 'stl_relops.h', 'type_traits.h', 57 'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
58 'utility', 'vector', 'vector.h', 58 'utility', 'vector', 'vector.h',
59 ]) 59 ])
60 60
61 61
62 # Non-STL C++ system headers. 62 # Non-STL C++ system headers.
63 _CPP_HEADERS = frozenset([ 63 _CPP_HEADERS = frozenset([
64 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype', 64 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
65 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath', 65 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
66 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef', 66 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
67 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype', 67 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
68 'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream', 68 'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
69 'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip', 69 'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
70 'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h', 70 'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h',
71 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h', 71 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
72 'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h', 72 'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h',
73 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h', 73 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h',
74 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept', 74 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
75 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string', 75 'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
76 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray', 76 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
77 ]) 77 ])
78 78
79 79
80 # Assertion macros. These are defined in base/logging.h and 80 # Assertion macros. These are defined in base/logging.h and
81 # testing/base/gunit.h. Note that the _M versions need to come first 81 # testing/base/gunit.h. Note that the _M versions need to come first
82 # for substring matching to work. 82 # for substring matching to work.
83 _CHECK_MACROS = [ 83 _CHECK_MACROS = [
84 'DCHECK', 'CHECK', 84 'DCHECK', 'CHECK',
85 'EXPECT_TRUE_M', 'EXPECT_TRUE', 85 'EXPECT_TRUE_M', 'EXPECT_TRUE',
86 'ASSERT_TRUE_M', 'ASSERT_TRUE', 86 'ASSERT_TRUE_M', 'ASSERT_TRUE',
87 'EXPECT_FALSE_M', 'EXPECT_FALSE', 87 'EXPECT_FALSE_M', 'EXPECT_FALSE',
88 'ASSERT_FALSE_M', 'ASSERT_FALSE', 88 'ASSERT_FALSE_M', 'ASSERT_FALSE',
89 ] 89 ]
90 90
91 # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE 91 # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
92 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) 92 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
93 93
94 for op, replacement in [('==', 'EQ'), ('!=', 'NE'), 94 for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
95 ('>=', 'GE'), ('>', 'GT'), 95 ('>=', 'GE'), ('>', 'GT'),
96 ('<=', 'LE'), ('<', 'LT')]: 96 ('<=', 'LE'), ('<', 'LT')]:
97 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement 97 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
98 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement 98 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
99 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement 99 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 if found_match: 199 if found_match:
200 return Position(current_row, starting_offset + found_match.start()) 200 return Position(current_row, starting_offset + found_match.start())
201 201
202 # A match was not found so continue forward. 202 # A match was not found so continue forward.
203 current_row += 1 203 current_row += 1
204 starting_offset = 0 204 starting_offset = 0
205 if current_row >= len(lines): 205 if current_row >= len(lines):
206 return not_found_position 206 return not_found_position
207 current_line = lines[current_row] 207 current_line = lines[current_row]
208 208
209
209 def _rfind_in_lines(regex, lines, start_position, not_found_position): 210 def _rfind_in_lines(regex, lines, start_position, not_found_position):
210 """Does a reverse find starting at start position and going backwards until 211 """Does a reverse find starting at start position and going backwards until
211 a match is found. 212 a match is found.
212 213
213 Returns the position where the regex ended. 214 Returns the position where the regex ended.
214 """ 215 """
215 # Put the regex in a group and proceed it with a greedy expression that 216 # Put the regex in a group and proceed it with a greedy expression that
216 # matches anything to ensure that we get the last possible match in a line. 217 # matches anything to ensure that we get the last possible match in a line.
217 last_in_line_regex = r'.*(' + regex + ')' 218 last_in_line_regex = r'.*(' + regex + ')'
218 current_row = start_position.row 219 current_row = start_position.row
(...skipping 25 matching lines...) Expand all
244 # (This puts an underscore before A in isA but not A in CBA). 245 # (This puts an underscore before A in isA but not A in CBA).
245 text = sub(r'(?<=[a-z0-9])([A-Z])(?=\b)', r'_\1', text) 246 text = sub(r'(?<=[a-z0-9])([A-Z])(?=\b)', r'_\1', text)
246 247
247 # Next add underscores when you have a captial letter which is followed by a capital letter 248 # Next add underscores when you have a captial letter which is followed by a capital letter
248 # but is not proceeded by one. (This puts an underscore before A in 'WordADa y'). 249 # but is not proceeded by one. (This puts an underscore before A in 'WordADa y').
249 text = sub(r'(?<=[a-z0-9])([A-Z][A-Z_])', r'_\1', text) 250 text = sub(r'(?<=[a-z0-9])([A-Z][A-Z_])', r'_\1', text)
250 251
251 return text.lower() 252 return text.lower()
252 253
253 254
254
255 def _create_acronym(text): 255 def _create_acronym(text):
256 """Creates an acronym for the given text.""" 256 """Creates an acronym for the given text."""
257 # Removes all lower case letters except those starting words. 257 # Removes all lower case letters except those starting words.
258 text = sub(r'(?<!\b)[a-z]', '', text) 258 text = sub(r'(?<!\b)[a-z]', '', text)
259 return text.upper() 259 return text.upper()
260 260
261 261
262 def up_to_unmatched_closing_paren(s): 262 def up_to_unmatched_closing_paren(s):
263 """Splits a string into two parts up to first unmatched ')'. 263 """Splits a string into two parts up to first unmatched ')'.
264 264
265 Args: 265 Args:
266 s: a string which is a substring of line after '(' 266 s: a string which is a substring of line after '('
267 (e.g., "a == (b + c))"). 267 (e.g., "a == (b + c))").
268 268
269 Returns: 269 Returns:
270 A pair of strings (prefix before first unmatched ')', 270 A pair of strings (prefix before first unmatched ')',
271 remainder of s after first unmatched ')'), e.g., 271 remainder of s after first unmatched ')'), e.g.,
272 up_to_unmatched_closing_paren("a == (b + c)) { ") 272 up_to_unmatched_closing_paren("a == (b + c)) { ")
273 returns "a == (b + c)", " {". 273 returns "a == (b + c)", " {".
274 Returns None, None if there is no unmatched ')' 274 Returns None, None if there is no unmatched ')'
275 275
276 """ 276 """
277 i = 1 277 i = 1
278 for pos, c in enumerate(s): 278 for pos, c in enumerate(s):
279 if c == '(': 279 if c == '(':
280 i += 1 280 i += 1
281 elif c == ')': 281 elif c == ')':
282 i -= 1 282 i -= 1
283 if i == 0: 283 if i == 0:
284 return s[:pos], s[pos + 1:] 284 return s[:pos], s[pos + 1:]
285 return None, None 285 return None, None
286 286
287
287 class _IncludeState(dict): 288 class _IncludeState(dict):
288 """Tracks line numbers for includes, and the order in which includes appear. 289 """Tracks line numbers for includes, and the order in which includes appear.
289 290
290 As a dict, an _IncludeState object serves as a mapping between include 291 As a dict, an _IncludeState object serves as a mapping between include
291 filename and line number on which that file was included. 292 filename and line number on which that file was included.
292 293
293 Call check_next_include_order() once for each header in the file, passing 294 Call check_next_include_order() once for each header in the file, passing
294 in the type constants defined above. Calls in an illegal order will 295 in the type constants defined above. Calls in an illegal order will
295 raise an _IncludeError with an appropriate error message. 296 raise an _IncludeError with an appropriate error message.
296 297
297 """ 298 """
298 # self._section will move monotonically through this set. If it ever 299 # self._section will move monotonically through this set. If it ever
299 # needs to move backwards, check_next_include_order will raise an error. 300 # needs to move backwards, check_next_include_order will raise an error.
300 _INITIAL_SECTION = 0 301 _INITIAL_SECTION = 0
301 _PRIMARY_SECTION = 1 302 _PRIMARY_SECTION = 1
302 _OTHER_SECTION = 2 303 _OTHER_SECTION = 2
303 304
304 _TYPE_NAMES = { 305 _TYPE_NAMES = {
305 _PRIMARY_HEADER: 'header this file implements', 306 _PRIMARY_HEADER: 'header this file implements',
306 _OTHER_HEADER: 'other header', 307 _OTHER_HEADER: 'other header',
307 _MOC_HEADER: 'moc file', 308 _MOC_HEADER: 'moc file',
308 } 309 }
309 _SECTION_NAMES = { 310 _SECTION_NAMES = {
310 _INITIAL_SECTION: "... nothing.", 311 _INITIAL_SECTION: "... nothing.",
311 _PRIMARY_SECTION: 'a header this file implements.', 312 _PRIMARY_SECTION: 'a header this file implements.',
312 _OTHER_SECTION: 'other header.', 313 _OTHER_SECTION: 'other header.',
313 } 314 }
314 315
315 def __init__(self): 316 def __init__(self):
316 dict.__init__(self) 317 dict.__init__(self)
317 self._section = self._INITIAL_SECTION 318 self._section = self._INITIAL_SECTION
318 self._visited_primary_section = False 319 self._visited_primary_section = False
319 self.header_types = dict(); 320 self.header_types = dict()
320 321
321 def visited_primary_section(self): 322 def visited_primary_section(self):
322 return self._visited_primary_section 323 return self._visited_primary_section
323 324
324 def check_next_include_order(self, header_type, file_is_header, primary_head er_exists): 325 def check_next_include_order(self, header_type, file_is_header, primary_head er_exists):
325 """Returns a non-empty error message if the next header is out of order. 326 """Returns a non-empty error message if the next header is out of order.
326 327
327 This function also updates the internal state to be ready to check 328 This function also updates the internal state to be ready to check
328 the next include. 329 the next include.
329 330
(...skipping 10 matching lines...) Expand all
340 return 'Header file should not contain itself.' 341 return 'Header file should not contain itself.'
341 if header_type == _MOC_HEADER: 342 if header_type == _MOC_HEADER:
342 return '' 343 return ''
343 344
344 error_message = '' 345 error_message = ''
345 if self._section != self._OTHER_SECTION: 346 if self._section != self._OTHER_SECTION:
346 before_error_message = ('Found %s before %s' % 347 before_error_message = ('Found %s before %s' %
347 (self._TYPE_NAMES[header_type], 348 (self._TYPE_NAMES[header_type],
348 self._SECTION_NAMES[self._section + 1])) 349 self._SECTION_NAMES[self._section + 1]))
349 after_error_message = ('Found %s after %s' % 350 after_error_message = ('Found %s after %s' %
350 (self._TYPE_NAMES[header_type], 351 (self._TYPE_NAMES[header_type],
351 self._SECTION_NAMES[self._section])) 352 self._SECTION_NAMES[self._section]))
352 353
353 if header_type == _PRIMARY_HEADER: 354 if header_type == _PRIMARY_HEADER:
354 if self._section >= self._PRIMARY_SECTION: 355 if self._section >= self._PRIMARY_SECTION:
355 error_message = after_error_message 356 error_message = after_error_message
356 self._section = self._PRIMARY_SECTION 357 self._section = self._PRIMARY_SECTION
357 self._visited_primary_section = True 358 self._visited_primary_section = True
358 else: 359 else:
359 assert header_type == _OTHER_HEADER 360 assert header_type == _OTHER_HEADER
360 if not file_is_header and self._section < self._PRIMARY_SECTION: 361 if not file_is_header and self._section < self._PRIMARY_SECTION:
361 if primary_header_exists: 362 if primary_header_exists:
362 error_message = before_error_message 363 error_message = before_error_message
363 self._section = self._OTHER_SECTION 364 self._section = self._OTHER_SECTION
364 365
365 return error_message 366 return error_message
366 367
367 368
368 class Position(object): 369 class Position(object):
369 """Holds the position of something.""" 370 """Holds the position of something."""
371
370 def __init__(self, row, column): 372 def __init__(self, row, column):
371 self.row = row 373 self.row = row
372 self.column = column 374 self.column = column
373 375
374 def __str__(self): 376 def __str__(self):
375 return '(%s, %s)' % (self.row, self.column) 377 return '(%s, %s)' % (self.row, self.column)
376 378
377 def __cmp__(self, other): 379 def __cmp__(self, other):
378 return self.row.__cmp__(other.row) or self.column.__cmp__(other.column) 380 return self.row.__cmp__(other.row) or self.column.__cmp__(other.column)
379 381
380 382
381 class Parameter(object): 383 class Parameter(object):
382 """Information about one function parameter.""" 384 """Information about one function parameter."""
385
383 def __init__(self, parameter, parameter_name_index, row): 386 def __init__(self, parameter, parameter_name_index, row):
384 self.type = parameter[:parameter_name_index].strip() 387 self.type = parameter[:parameter_name_index].strip()
385 # Remove any initializers from the parameter name (e.g. int i = 5). 388 # Remove any initializers from the parameter name (e.g. int i = 5).
386 self.name = sub(r'=.*', '', parameter[parameter_name_index:]).strip() 389 self.name = sub(r'=.*', '', parameter[parameter_name_index:]).strip()
387 self.row = row 390 self.row = row
388 391
389 @memoized 392 @memoized
390 def lower_with_underscores_name(self): 393 def lower_with_underscores_name(self):
391 """Returns the parameter name in the lower with underscores format.""" 394 """Returns the parameter name in the lower with underscores format."""
392 return _convert_to_lower_with_underscores(self.name) 395 return _convert_to_lower_with_underscores(self.name)
393 396
394 397
395 class SingleLineView(object): 398 class SingleLineView(object):
396 """Converts multiple lines into a single line (with line breaks replaced by a 399 """Converts multiple lines into a single line (with line breaks replaced by a
397 space) to allow for easier searching.""" 400 space) to allow for easier searching."""
401
398 def __init__(self, lines, start_position, end_position): 402 def __init__(self, lines, start_position, end_position):
399 """Create a SingleLineView instance. 403 """Create a SingleLineView instance.
400 404
401 Args: 405 Args:
402 lines: a list of multiple lines to combine into a single line. 406 lines: a list of multiple lines to combine into a single line.
403 start_position: offset within lines of where to start the single line. 407 start_position: offset within lines of where to start the single line.
404 end_position: just after where to end (like a slice operation). 408 end_position: just after where to end (like a slice operation).
405 """ 409 """
406 # Get the rows of interest. 410 # Get the rows of interest.
407 trimmed_lines = lines[start_position.row:end_position.row + 1] 411 trimmed_lines = lines[start_position.row:end_position.row + 1]
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 self.lines_in_function = -1 # Don't count the open brace line. 546 self.lines_in_function = -1 # Don't count the open brace line.
543 self.current_function = function_name 547 self.current_function = function_name
544 self.function_name_start_position = function_name_start_position 548 self.function_name_start_position = function_name_start_position
545 self.body_start_position = body_start_position 549 self.body_start_position = body_start_position
546 self.end_position = end_position 550 self.end_position = end_position
547 self.is_declaration = clean_lines.elided[body_start_position.row][body_s tart_position.column] == ';' 551 self.is_declaration = clean_lines.elided[body_start_position.row][body_s tart_position.column] == ';'
548 self.parameter_start_position = parameter_start_position 552 self.parameter_start_position = parameter_start_position
549 self.parameter_end_position = parameter_end_position 553 self.parameter_end_position = parameter_end_position
550 self.is_pure = False 554 self.is_pure = False
551 if self.is_declaration: 555 if self.is_declaration:
552 characters_after_parameters = SingleLineView(clean_lines.elided, par ameter_end_position, body_start_position).single_line 556 characters_after_parameters = SingleLineView(
557 clean_lines.elided, parameter_end_position, body_start_position) .single_line
553 self.is_pure = bool(match(r'\s*=\s*0\s*', characters_after_parameter s)) 558 self.is_pure = bool(match(r'\s*=\s*0\s*', characters_after_parameter s))
554 self._clean_lines = clean_lines 559 self._clean_lines = clean_lines
555 self._parameter_list = None 560 self._parameter_list = None
556 561
557 def modifiers_and_return_type(self): 562 def modifiers_and_return_type(self):
558 """Returns the modifiers and the return type.""" 563 """Returns the modifiers and the return type."""
559 # Go backwards from where the function name is until we encounter one of several things: 564 # Go backwards from where the function name is until we encounter one of several things:
560 # ';' or '{' or '}' or 'private:', etc. or '#' or return Position(0, 0 ) 565 # ';' or '{' or '}' or 'private:', etc. or '#' or return Position(0, 0 )
561 elided = self._clean_lines.elided 566 elided = self._clean_lines.elided
562 start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected): )|(#.*)', 567 start_modifiers = _rfind_in_lines(r';|\{|\}|((private|public|protected): )|(#.*)',
563 elided, self.parameter_start_position, Position(0, 0)) 568 elided, self.parameter_start_position, Position(0, 0))
564 return SingleLineView(elided, start_modifiers, self.function_name_start_ position).single_line.strip() 569 return SingleLineView(elided, start_modifiers, self.function_name_start_ position).single_line.strip()
565 570
566 def parameter_list(self): 571 def parameter_list(self):
567 if not self._parameter_list: 572 if not self._parameter_list:
568 # Store the final result as a tuple since that is immutable. 573 # Store the final result as a tuple since that is immutable.
569 self._parameter_list = tuple(parameter_list(self._clean_lines.elided , self.parameter_start_position, self.parameter_end_position)) 574 self._parameter_list = tuple(parameter_list(self._clean_lines.elided ,
575 self.parameter_start_pos ition, self.parameter_end_position))
570 576
571 return self._parameter_list 577 return self._parameter_list
572 578
573 def count(self, line_number): 579 def count(self, line_number):
574 """Count line in current function body.""" 580 """Count line in current function body."""
575 if self.in_a_function and line_number >= self.body_start_position.row: 581 if self.in_a_function and line_number >= self.body_start_position.row:
576 self.lines_in_function += 1 582 self.lines_in_function += 1
577 583
578 def check(self, error, line_number): 584 def check(self, error, line_number):
579 """Report if too many lines in function body. 585 """Report if too many lines in function body.
580 586
581 Args: 587 Args:
582 error: The function to call with any errors found. 588 error: The function to call with any errors found.
583 line_number: The number of the line to check. 589 line_number: The number of the line to check.
584 """ 590 """
585 if match(r'T(EST|est)', self.current_function): 591 if match(r'T(EST|est)', self.current_function):
586 base_trigger = self._TEST_TRIGGER 592 base_trigger = self._TEST_TRIGGER
587 else: 593 else:
588 base_trigger = self._NORMAL_TRIGGER 594 base_trigger = self._NORMAL_TRIGGER
589 trigger = base_trigger * 2 ** self.min_confidence 595 trigger = base_trigger * 2 ** self.min_confidence
590 596
591 if self.lines_in_function > trigger: 597 if self.lines_in_function > trigger:
592 error_level = int(math.log(self.lines_in_function / base_trigger, 2) ) 598 error_level = int(math.log(self.lines_in_function / base_trigger, 2) )
593 # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... 599 # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
594 if error_level > 5: 600 if error_level > 5:
595 error_level = 5 601 error_level = 5
596 error(line_number, 'readability/fn_size', error_level, 602 error(line_number, 'readability/fn_size', error_level,
597 'Small and focused functions are preferred:' 603 'Small and focused functions are preferred:'
598 ' %s has %d non-comment lines' 604 ' %s has %d non-comment lines'
599 ' (error triggered by exceeding %d lines).' % ( 605 ' (error triggered by exceeding %d lines).' % (
600 self.current_function, self.lines_in_function, trigger)) 606 self.current_function, self.lines_in_function, trigger))
601 607
602 def end(self): 608 def end(self):
603 """Stop analyzing function body.""" 609 """Stop analyzing function body."""
604 self.in_a_function = False 610 self.in_a_function = False
605 611
606 612
607 class _IncludeError(Exception): 613 class _IncludeError(Exception):
608 """Indicates a problem with the include order in a file.""" 614 """Indicates a problem with the include order in a file."""
609 pass 615 pass
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 if not net_open: 895 if not net_open:
890 return Position(line_number, current_column) 896 return Position(line_number, current_column)
891 897
892 # Proceed to the next line. 898 # Proceed to the next line.
893 line_number += 1 899 line_number += 1
894 current_column = 0 900 current_column = 0
895 901
896 # The given item was not closed. 902 # The given item was not closed.
897 return Position(len(elided), -1) 903 return Position(len(elided), -1)
898 904
905
899 def check_for_copyright(lines, error): 906 def check_for_copyright(lines, error):
900 """Logs an error if no Copyright message appears at the top of the file.""" 907 """Logs an error if no Copyright message appears at the top of the file."""
901 908
902 # We'll say it should occur by line 10. Don't forget there's a 909 # We'll say it should occur by line 10. Don't forget there's a
903 # dummy line at the front. 910 # dummy line at the front.
904 for line in xrange(1, min(len(lines), 11)): 911 for line in xrange(1, min(len(lines), 11)):
905 if re.search(r'Copyright', lines[line], re.I): 912 if re.search(r'Copyright', lines[line], re.I):
906 break 913 break
907 else: # means no copyright line was found 914 else: # means no copyright line was found
908 error(0, 'legal/copyright', 5, 915 error(0, 'legal/copyright', 5,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 ('getgrnam(', 'getgrnam_r('), 1094 ('getgrnam(', 'getgrnam_r('),
1088 ('getlogin(', 'getlogin_r('), 1095 ('getlogin(', 'getlogin_r('),
1089 ('getpwnam(', 'getpwnam_r('), 1096 ('getpwnam(', 'getpwnam_r('),
1090 ('getpwuid(', 'getpwuid_r('), 1097 ('getpwuid(', 'getpwuid_r('),
1091 ('gmtime(', 'gmtime_r('), 1098 ('gmtime(', 'gmtime_r('),
1092 ('localtime(', 'localtime_r('), 1099 ('localtime(', 'localtime_r('),
1093 ('rand(', 'rand_r('), 1100 ('rand(', 'rand_r('),
1094 ('readdir(', 'readdir_r('), 1101 ('readdir(', 'readdir_r('),
1095 ('strtok(', 'strtok_r('), 1102 ('strtok(', 'strtok_r('),
1096 ('ttyname(', 'ttyname_r('), 1103 ('ttyname(', 'ttyname_r('),
1097 ) 1104 )
1098 1105
1099 1106
1100 def check_posix_threading(clean_lines, line_number, error): 1107 def check_posix_threading(clean_lines, line_number, error):
1101 """Checks for calls to thread-unsafe functions. 1108 """Checks for calls to thread-unsafe functions.
1102 1109
1103 Much code has been originally written without consideration of 1110 Much code has been originally written without consideration of
1104 multi-threading. Also, engineers are relying on their old experience; 1111 multi-threading. Also, engineers are relying on their old experience;
1105 they have learned posix before threading extensions were added. These 1112 they have learned posix before threading extensions were added. These
1106 tests guide the engineers to use thread-safe functions (when using 1113 tests guide the engineers to use thread-safe functions (when using
1107 posix directly). 1114 posix directly).
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 if self.classinfo_stack: 1194 if self.classinfo_stack:
1188 # Note: This test can result in false positives if #ifdef constructs 1195 # Note: This test can result in false positives if #ifdef constructs
1189 # get in the way of brace matching. See the testBuildClass test in 1196 # get in the way of brace matching. See the testBuildClass test in
1190 # cpp_style_unittest.py for an example of this. 1197 # cpp_style_unittest.py for an example of this.
1191 error(self.classinfo_stack[0].line_number, 'build/class', 5, 1198 error(self.classinfo_stack[0].line_number, 'build/class', 5,
1192 'Failed to find complete declaration of class %s' % 1199 'Failed to find complete declaration of class %s' %
1193 self.classinfo_stack[0].name) 1200 self.classinfo_stack[0].name)
1194 1201
1195 1202
1196 class _FileState(object): 1203 class _FileState(object):
1204
1197 def __init__(self, clean_lines, file_extension): 1205 def __init__(self, clean_lines, file_extension):
1198 self._did_inside_namespace_indent_warning = False 1206 self._did_inside_namespace_indent_warning = False
1199 self._clean_lines = clean_lines 1207 self._clean_lines = clean_lines
1200 if file_extension in ['m', 'mm']: 1208 if file_extension in ['m', 'mm']:
1201 self._is_objective_c = True 1209 self._is_objective_c = True
1202 self._is_c = False 1210 self._is_c = False
1203 elif file_extension == 'h': 1211 elif file_extension == 'h':
1204 # In the case of header files, it is unknown if the file 1212 # In the case of header files, it is unknown if the file
1205 # is c / objective c or not, so set this value to None and then 1213 # is c / objective c or not, so set this value to None and then
1206 # if it is requested, use heuristics to guess the value. 1214 # if it is requested, use heuristics to guess the value.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 if match(expr_all_uppercase, member): 1294 if match(expr_all_uppercase, member):
1287 found_invalid_member = not self.is_webidl_enum 1295 found_invalid_member = not self.is_webidl_enum
1288 if match(expr_starts_lowercase, member): 1296 if match(expr_starts_lowercase, member):
1289 found_invalid_member = True 1297 found_invalid_member = True
1290 if found_invalid_member: 1298 if found_invalid_member:
1291 self.is_webidl_enum = False 1299 self.is_webidl_enum = False
1292 return False 1300 return False
1293 return True 1301 return True
1294 return True 1302 return True
1295 1303
1304
1296 def check_for_non_standard_constructs(clean_lines, line_number, 1305 def check_for_non_standard_constructs(clean_lines, line_number,
1297 class_state, error): 1306 class_state, error):
1298 """Logs an error if we see certain non-ANSI constructs ignored by gcc-2. 1307 """Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
1299 1308
1300 Complain about several constructs which gcc-2 accepts, but which are 1309 Complain about several constructs which gcc-2 accepts, but which are
1301 not standard C++. Warning about these in lint is one way to ease the 1310 not standard C++. Warning about these in lint is one way to ease the
1302 transition to new compilers. 1311 transition to new compilers.
1303 - put storage class first (e.g. "static const" instead of "const static"). 1312 - put storage class first (e.g. "static const" instead of "const static").
1304 - "%lld" instead of %qd" in printf-type functions. 1313 - "%lld" instead of %qd" in printf-type functions.
1305 - "%1$d" is non-standard in printf-type functions. 1314 - "%1$d" is non-standard in printf-type functions.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 unsigned_list = ', '.join(classinfo.unsigned_bitfields) 1462 unsigned_list = ', '.join(classinfo.unsigned_bitfields)
1454 error(classinfo.line_number, 'runtime/bitfields', 5, 1463 error(classinfo.line_number, 'runtime/bitfields', 5,
1455 'The class %s contains mixed unsigned and bool bitfields, ' 1464 'The class %s contains mixed unsigned and bool bitfields, '
1456 'which will pack into separate words on the MSVC compiler.\n' 1465 'which will pack into separate words on the MSVC compiler.\n'
1457 'Bool bitfields are [%s].\nUnsigned bitfields are [%s].\n' 1466 'Bool bitfields are [%s].\nUnsigned bitfields are [%s].\n'
1458 'Consider converting bool bitfields to unsigned.' 1467 'Consider converting bool bitfields to unsigned.'
1459 % (classinfo.name, bool_list, unsigned_list)) 1468 % (classinfo.name, bool_list, unsigned_list))
1460 else: 1469 else:
1461 classinfo.brace_depth = brace_depth 1470 classinfo.brace_depth = brace_depth
1462 1471
1463 well_typed_bitfield = False; 1472 well_typed_bitfield = False
1464 # Look for bool <name> : 1 declarations. 1473 # Look for bool <name> : 1 declarations.
1465 args = search(r'\bbool\s+(\S*)\s*:\s*\d+\s*;', line) 1474 args = search(r'\bbool\s+(\S*)\s*:\s*\d+\s*;', line)
1466 if args: 1475 if args:
1467 classinfo.bool_bitfields.append('%d: %s' % (line_number, args.group(1))) 1476 classinfo.bool_bitfields.append('%d: %s' % (line_number, args.group(1)))
1468 well_typed_bitfield = True; 1477 well_typed_bitfield = True
1469 1478
1470 # Look for unsigned <name> : n declarations. 1479 # Look for unsigned <name> : n declarations.
1471 args = search(r'\bunsigned\s+(?:int\s+)?(\S+)\s*:\s*\d+\s*;', line) 1480 args = search(r'\bunsigned\s+(?:int\s+)?(\S+)\s*:\s*\d+\s*;', line)
1472 if args: 1481 if args:
1473 classinfo.unsigned_bitfields.append('%d: %s' % (line_number, args.group( 1))) 1482 classinfo.unsigned_bitfields.append('%d: %s' % (line_number, args.group( 1)))
1474 well_typed_bitfield = True; 1483 well_typed_bitfield = True
1475 1484
1476 # Look for other bitfield declarations. We don't care about those in 1485 # Look for other bitfield declarations. We don't care about those in
1477 # size-matching structs. 1486 # size-matching structs.
1478 if not (well_typed_bitfield or classinfo.name.startswith('SameSizeAs') or 1487 if not (well_typed_bitfield or classinfo.name.startswith('SameSizeAs') or
1479 classinfo.name.startswith('Expected')): 1488 classinfo.name.startswith('Expected')):
1480 args = match(r'\s*(\S+)\s+(\S+)\s*:\s*\d+\s*;', line) 1489 args = match(r'\s*(\S+)\s+(\S+)\s*:\s*\d+\s*;', line)
1481 if args: 1490 if args:
1482 error(line_number, 'runtime/bitfields', 4, 1491 error(line_number, 'runtime/bitfields', 4,
1483 'Member %s of class %s defined as a bitfield of type %s. ' 1492 'Member %s of class %s defined as a bitfield of type %s. '
1484 'Please declare all bitfields as unsigned.' 1493 'Please declare all bitfields as unsigned.'
1485 % (args.group(2), classinfo.name, args.group(1))) 1494 % (args.group(2), classinfo.name, args.group(1)))
1486 1495
1496
1487 def check_spacing_for_function_call(line, line_number, error): 1497 def check_spacing_for_function_call(line, line_number, error):
1488 """Checks for the correctness of various spacing around function calls. 1498 """Checks for the correctness of various spacing around function calls.
1489 1499
1490 Args: 1500 Args:
1491 line: The text of the line to check. 1501 line: The text of the line to check.
1492 line_number: The number of the line to check. 1502 line_number: The number of the line to check.
1493 error: The function to call with any errors found. 1503 error: The function to call with any errors found.
1494 """ 1504 """
1495 1505
1496 # Since function calls often occur inside if/for/foreach/while/switch 1506 # Since function calls often occur inside if/for/foreach/while/switch
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 elif not file_extension == "h": 1761 elif not file_extension == "h":
1752 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1762 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
1753 'WEBKIT_EXPORT should only be used in header files.') 1763 'WEBKIT_EXPORT should only be used in header files.')
1754 elif not function_state.is_declaration or search(r'\binline\b', modifier s_and_return_type): 1764 elif not function_state.is_declaration or search(r'\binline\b', modifier s_and_return_type):
1755 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1765 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
1756 'WEBKIT_EXPORT should not be used on a function with a body.') 1766 'WEBKIT_EXPORT should not be used on a function with a body.')
1757 elif function_state.is_pure: 1767 elif function_state.is_pure:
1758 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5, 1768 error(function_state.function_name_start_position.row, 'readability/ webkit_export', 5,
1759 'WEBKIT_EXPORT should not be used with a pure virtual function .') 1769 'WEBKIT_EXPORT should not be used with a pure virtual function .')
1760 1770
1761 check_function_definition_and_pass_ptr(modifiers_and_return_type, function_s tate.function_name_start_position.row, 'return', error) 1771 check_function_definition_and_pass_ptr(
1772 modifiers_and_return_type, function_state.function_name_start_position.r ow, 'return', error)
1762 1773
1763 parameter_list = function_state.parameter_list() 1774 parameter_list = function_state.parameter_list()
1764 for parameter in parameter_list: 1775 for parameter in parameter_list:
1765 check_function_definition_and_pass_ptr(parameter.type, parameter.row, 'p arameter', error) 1776 check_function_definition_and_pass_ptr(parameter.type, parameter.row, 'p arameter', error)
1766 1777
1767 # Do checks specific to function declarations and parameter names. 1778 # Do checks specific to function declarations and parameter names.
1768 if not function_state.is_declaration or not parameter.name: 1779 if not function_state.is_declaration or not parameter.name:
1769 continue 1780 continue
1770 1781
1771 # Check the parameter name against the function name for single paramete r set functions. 1782 # Check the parameter name against the function name for single paramete r set functions.
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 1928
1918 # Next, we check for proper spacing with respect to comments. 1929 # Next, we check for proper spacing with respect to comments.
1919 comment_position = line.find('//') 1930 comment_position = line.find('//')
1920 if comment_position != -1: 1931 if comment_position != -1:
1921 # Check if the // may be in quotes. If so, ignore it 1932 # Check if the // may be in quotes. If so, ignore it
1922 # Comparisons made explicit for clarity 1933 # Comparisons made explicit for clarity
1923 if (line.count('"', 0, comment_position) - line.count('\\"', 0, comment_ position)) % 2 == 0: # not in quotes 1934 if (line.count('"', 0, comment_position) - line.count('\\"', 0, comment_ position)) % 2 == 0: # not in quotes
1924 # Allow one space before end of line comment. 1935 # Allow one space before end of line comment.
1925 if (not match(r'^\s*$', line[:comment_position]) 1936 if (not match(r'^\s*$', line[:comment_position])
1926 and (comment_position >= 1 1937 and (comment_position >= 1
1927 and ((line[comment_position - 1] not in string.whitespace) 1938 and ((line[comment_position - 1] not in string.whitespace)
1928 or (comment_position >= 2 1939 or (comment_position >= 2
1929 and line[comment_position - 2] in string.whitespace)))) : 1940 and line[comment_position - 2] in string.whitespac e)))):
1930 error(line_number, 'whitespace/comments', 5, 1941 error(line_number, 'whitespace/comments', 5,
1931 'One space before end of line comments') 1942 'One space before end of line comments')
1932 # There should always be a space between the // and the comment 1943 # There should always be a space between the // and the comment
1933 commentend = comment_position + 2 1944 commentend = comment_position + 2
1934 if commentend < len(line) and not line[commentend] == ' ': 1945 if commentend < len(line) and not line[commentend] == ' ':
1935 # but some lines are exceptions -- e.g. if they're big 1946 # but some lines are exceptions -- e.g. if they're big
1936 # comment delimiters like: 1947 # comment delimiters like:
1937 # //---------------------------------------------------------- 1948 # //----------------------------------------------------------
1938 # or they begin with multiple slashes followed by a space: 1949 # or they begin with multiple slashes followed by a space:
1939 # //////// Header comment 1950 # //////// Header comment
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
2124 2135
2125 Args: 2136 Args:
2126 clean_lines: A CleansedLines instance containing the file. 2137 clean_lines: A CleansedLines instance containing the file.
2127 line_number: The number of the line to check. 2138 line_number: The number of the line to check.
2128 file_extension: The extension (dot not included) of the file. 2139 file_extension: The extension (dot not included) of the file.
2129 file_state: A _FileState instance which maintains information about 2140 file_state: A _FileState instance which maintains information about
2130 the state of things in the file. 2141 the state of things in the file.
2131 error: The function to call with any errors found. 2142 error: The function to call with any errors found.
2132 """ 2143 """
2133 2144
2134 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2145 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2135 2146
2136 namespace_match = match(r'(?P<namespace_indentation>\s*)namespace\s+\S+\s*{\ s*$', line) 2147 namespace_match = match(r'(?P<namespace_indentation>\s*)namespace\s+\S+\s*{\ s*$', line)
2137 if not namespace_match: 2148 if not namespace_match:
2138 return 2149 return
2139 2150
2140 current_indentation_level = len(namespace_match.group('namespace_indentation ')) 2151 current_indentation_level = len(namespace_match.group('namespace_indentation '))
2141 if current_indentation_level > 0: 2152 if current_indentation_level > 0:
2142 # Don't warn about an indented namespace if we already warned about inde nted code. 2153 # Don't warn about an indented namespace if we already warned about inde nted code.
2143 if not file_state.did_inside_namespace_indent_warning(): 2154 if not file_state.did_inside_namespace_indent_warning():
2144 error(line_number, 'whitespace/indent', 4, 2155 error(line_number, 'whitespace/indent', 4,
2145 'namespace should never be indented.') 2156 'namespace should never be indented.')
2146 return 2157 return
2147 looking_for_semicolon = False; 2158 looking_for_semicolon = False
2148 line_offset = 0 2159 line_offset = 0
2149 in_preprocessor_directive = False; 2160 in_preprocessor_directive = False
2150 for current_line in clean_lines.elided[line_number + 1:]: 2161 for current_line in clean_lines.elided[line_number + 1:]:
2151 line_offset += 1 2162 line_offset += 1
2152 if not current_line.strip(): 2163 if not current_line.strip():
2153 continue 2164 continue
2154 if not current_indentation_level: 2165 if not current_indentation_level:
2155 if not (in_preprocessor_directive or looking_for_semicolon): 2166 if not (in_preprocessor_directive or looking_for_semicolon):
2156 if not match(r'\S', current_line) and not file_state.did_inside_ namespace_indent_warning(): 2167 if not match(r'\S', current_line) and not file_state.did_inside_ namespace_indent_warning():
2157 file_state.set_did_inside_namespace_indent_warning() 2168 file_state.set_did_inside_namespace_indent_warning()
2158 error(line_number + line_offset, 'whitespace/indent', 4, 2169 error(line_number + line_offset, 'whitespace/indent', 4,
2159 'Code inside a namespace should not be indented.') 2170 'Code inside a namespace should not be indented.')
2160 if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax. 2171 if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax.
2161 in_preprocessor_directive = current_line[-1] == '\\' 2172 in_preprocessor_directive = current_line[-1] == '\\'
2162 else: 2173 else:
2163 looking_for_semicolon = ((current_line.find(';') == -1) and (cur rent_line.strip()[-1] != '}')) or (current_line[-1] == '\\') 2174 looking_for_semicolon = ((current_line.find(';') == -1) and (cur rent_line.strip()
2175 [-1 ] != '}')) or (current_line[-1] == '\\')
2164 else: 2176 else:
2165 looking_for_semicolon = False; # If we have a brace we may not need a semicolon. 2177 looking_for_semicolon = False # If we have a brace we may not need a semicolon.
2166 current_indentation_level += current_line.count('{') - current_line.coun t('}') 2178 current_indentation_level += current_line.count('{') - current_line.coun t('}')
2167 if current_indentation_level < 0: 2179 if current_indentation_level < 0:
2168 break; 2180 break
2169 2181
2170 2182
2171 def check_enum_casing(clean_lines, line_number, enum_state, error): 2183 def check_enum_casing(clean_lines, line_number, enum_state, error):
2172 """Looks for incorrectly named enum values. 2184 """Looks for incorrectly named enum values.
2173 2185
2174 Args: 2186 Args:
2175 clean_lines: A CleansedLines instance containing the file. 2187 clean_lines: A CleansedLines instance containing the file.
2176 line_number: The number of the line to check. 2188 line_number: The number of the line to check.
2177 enum_state: A _EnumState instance which maintains enum declaration state. 2189 enum_state: A _EnumState instance which maintains enum declaration state.
2178 error: The function to call with any errors found. 2190 error: The function to call with any errors found.
2179 """ 2191 """
2180 2192
2181 enum_state.is_webidl_enum |= bool(match(r'\s*// Web(?:Kit)?IDL enum\s*$', cl ean_lines.raw_lines[line_number])) 2193 enum_state.is_webidl_enum |= bool(match(r'\s*// Web(?:Kit)?IDL enum\s*$', cl ean_lines.raw_lines[line_number]))
2182 2194
2183 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2195 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2184 if not enum_state.process_clean_line(line): 2196 if not enum_state.process_clean_line(line):
2185 error(line_number, 'readability/enum_casing', 4, 2197 error(line_number, 'readability/enum_casing', 4,
2186 'enum members should use InterCaps with an initial capital letter. ') 2198 'enum members should use InterCaps with an initial capital letter. ')
2187 2199
2200
2188 def check_directive_indentation(clean_lines, line_number, file_state, error): 2201 def check_directive_indentation(clean_lines, line_number, file_state, error):
2189 """Looks for indentation of preprocessor directives. 2202 """Looks for indentation of preprocessor directives.
2190 2203
2191 Args: 2204 Args:
2192 clean_lines: A CleansedLines instance containing the file. 2205 clean_lines: A CleansedLines instance containing the file.
2193 line_number: The number of the line to check. 2206 line_number: The number of the line to check.
2194 file_state: A _FileState instance which maintains information about 2207 file_state: A _FileState instance which maintains information about
2195 the state of things in the file. 2208 the state of things in the file.
2196 error: The function to call with any errors found. 2209 error: The function to call with any errors found.
2197 """ 2210 """
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2238 line_number: The number of the line to check. 2251 line_number: The number of the line to check.
2239 file_state: A _FileState instance which maintains information about 2252 file_state: A _FileState instance which maintains information about
2240 the state of things in the file. 2253 the state of things in the file.
2241 error: The function to call with any errors found. 2254 error: The function to call with any errors found.
2242 """ 2255 """
2243 2256
2244 # This check doesn't apply to C or Objective-C implementation files. 2257 # This check doesn't apply to C or Objective-C implementation files.
2245 if file_state.is_c_or_objective_c(): 2258 if file_state.is_c_or_objective_c():
2246 return 2259 return
2247 2260
2248 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2261 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2249 2262
2250 using_std_match = match(r'\s*using\s+std::(?P<method_name>\S+)\s*;\s*$', lin e) 2263 using_std_match = match(r'\s*using\s+std::(?P<method_name>\S+)\s*;\s*$', lin e)
2251 if not using_std_match: 2264 if not using_std_match:
2252 return 2265 return
2253 2266
2254 method_name = using_std_match.group('method_name') 2267 method_name = using_std_match.group('method_name')
2255 # Exception for the established idiom for swapping objects in generic code. 2268 # Exception for the established idiom for swapping objects in generic code.
2256 if method_name == 'swap': 2269 if method_name == 'swap':
2257 return 2270 return
2258 error(line_number, 'build/using_std', 4, 2271 error(line_number, 'build/using_std', 4,
2259 "Use 'using namespace std;' instead of 'using std::%s;'." % method_nam e) 2272 "Use 'using namespace std;' instead of 'using std::%s;'." % method_nam e)
2260 2273
2261 2274
2262 def check_max_min_macros(clean_lines, line_number, file_state, error): 2275 def check_max_min_macros(clean_lines, line_number, file_state, error):
2263 """Looks use of MAX() and MIN() macros that should be replaced with std::max () and std::min(). 2276 """Looks use of MAX() and MIN() macros that should be replaced with std::max () and std::min().
2264 2277
2265 Args: 2278 Args:
2266 clean_lines: A CleansedLines instance containing the file. 2279 clean_lines: A CleansedLines instance containing the file.
2267 line_number: The number of the line to check. 2280 line_number: The number of the line to check.
2268 file_state: A _FileState instance which maintains information about 2281 file_state: A _FileState instance which maintains information about
2269 the state of things in the file. 2282 the state of things in the file.
2270 error: The function to call with any errors found. 2283 error: The function to call with any errors found.
2271 """ 2284 """
2272 2285
2273 # This check doesn't apply to C or Objective-C implementation files. 2286 # This check doesn't apply to C or Objective-C implementation files.
2274 if file_state.is_c_or_objective_c(): 2287 if file_state.is_c_or_objective_c():
2275 return 2288 return
2276 2289
2277 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2290 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2278 2291
2279 max_min_macros_search = search(r'\b(?P<max_min_macro>(MAX|MIN))\s*\(', line) 2292 max_min_macros_search = search(r'\b(?P<max_min_macro>(MAX|MIN))\s*\(', line)
2280 if not max_min_macros_search: 2293 if not max_min_macros_search:
2281 return 2294 return
2282 2295
2283 max_min_macro = max_min_macros_search.group('max_min_macro') 2296 max_min_macro = max_min_macros_search.group('max_min_macro')
2284 max_min_macro_lower = max_min_macro.lower() 2297 max_min_macro_lower = max_min_macro.lower()
2285 error(line_number, 'runtime/max_min_macros', 4, 2298 error(line_number, 'runtime/max_min_macros', 4,
2286 'Use std::%s() or std::%s<type>() instead of the %s() macro.' 2299 'Use std::%s() or std::%s<type>() instead of the %s() macro.'
2287 % (max_min_macro_lower, max_min_macro_lower, max_min_macro)) 2300 % (max_min_macro_lower, max_min_macro_lower, max_min_macro))
2288 2301
2289 2302
2290 def check_ctype_functions(clean_lines, line_number, file_state, error): 2303 def check_ctype_functions(clean_lines, line_number, file_state, error):
2291 """Looks for use of the standard functions in ctype.h and suggest they be re placed 2304 """Looks for use of the standard functions in ctype.h and suggest they be re placed
2292 by use of equivilent ones in <wtf/ASCIICType.h>?. 2305 by use of equivilent ones in <wtf/ASCIICType.h>?.
2293 2306
2294 Args: 2307 Args:
2295 clean_lines: A CleansedLines instance containing the file. 2308 clean_lines: A CleansedLines instance containing the file.
2296 line_number: The number of the line to check. 2309 line_number: The number of the line to check.
2297 file_state: A _FileState instance which maintains information about 2310 file_state: A _FileState instance which maintains information about
2298 the state of things in the file. 2311 the state of things in the file.
2299 error: The function to call with any errors found. 2312 error: The function to call with any errors found.
2300 """ 2313 """
2301 2314
2302 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2315 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2303 2316
2304 ctype_function_search = search(r'\b(?P<ctype_function>(isalnum|isalpha|isasc ii|isblank|iscntrl|isdigit|isgraph|islower|isprint|ispunct|isspace|isupper|isxdi git|toascii|tolower|toupper))\s*\(', line) 2317 ctype_function_search = search(
2318 r'\b(?P<ctype_function>(isalnum|isalpha|isascii|isblank|iscntrl|isdigit| isgraph|islower|isprint|ispunct|isspace|isupper|isxdigit|toascii|tolower|toupper ))\s*\(', line)
2305 if not ctype_function_search: 2319 if not ctype_function_search:
2306 return 2320 return
2307 2321
2308 ctype_function = ctype_function_search.group('ctype_function') 2322 ctype_function = ctype_function_search.group('ctype_function')
2309 error(line_number, 'runtime/ctype_function', 4, 2323 error(line_number, 'runtime/ctype_function', 4,
2310 'Use equivelent function in <wtf/ASCIICType.h> instead of the %s() fun ction.' 2324 'Use equivelent function in <wtf/ASCIICType.h> instead of the %s() fun ction.'
2311 % (ctype_function)) 2325 % (ctype_function))
2312 2326
2327
2313 def check_switch_indentation(clean_lines, line_number, error): 2328 def check_switch_indentation(clean_lines, line_number, error):
2314 """Looks for indentation errors inside of switch statements. 2329 """Looks for indentation errors inside of switch statements.
2315 2330
2316 Args: 2331 Args:
2317 clean_lines: A CleansedLines instance containing the file. 2332 clean_lines: A CleansedLines instance containing the file.
2318 line_number: The number of the line to check. 2333 line_number: The number of the line to check.
2319 error: The function to call with any errors found. 2334 error: The function to call with any errors found.
2320 """ 2335 """
2321 2336
2322 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2337 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2323 2338
2324 switch_match = match(r'(?P<switch_indentation>\s*)switch\s*\(.+\)\s*{\s*$', line) 2339 switch_match = match(r'(?P<switch_indentation>\s*)switch\s*\(.+\)\s*{\s*$', line)
2325 if not switch_match: 2340 if not switch_match:
2326 return 2341 return
2327 2342
2328 switch_indentation = switch_match.group('switch_indentation') 2343 switch_indentation = switch_match.group('switch_indentation')
2329 inner_indentation = switch_indentation + ' ' * 4 2344 inner_indentation = switch_indentation + ' ' * 4
2330 line_offset = 0 2345 line_offset = 0
2331 encountered_nested_switch = False 2346 encountered_nested_switch = False
2332 2347
2333 for current_line in clean_lines.elided[line_number + 1:]: 2348 for current_line in clean_lines.elided[line_number + 1:]:
2334 line_offset += 1 2349 line_offset += 1
2335 2350
2336 # Skip not only empty lines but also those with preprocessor directives. 2351 # Skip not only empty lines but also those with preprocessor directives.
2337 if current_line.strip() == '' or current_line.startswith('#'): 2352 if current_line.strip() == '' or current_line.startswith('#'):
2338 continue 2353 continue
2339 2354
2340 if match(r'\s*switch\s*\(.+\)\s*{\s*$', current_line): 2355 if match(r'\s*switch\s*\(.+\)\s*{\s*$', current_line):
2341 # Complexity alarm - another switch statement nested inside the one 2356 # Complexity alarm - another switch statement nested inside the one
2342 # that we're currently testing. We'll need to track the extent of 2357 # that we're currently testing. We'll need to track the extent of
2343 # that inner switch if the upcoming label tests are still supposed 2358 # that inner switch if the upcoming label tests are still supposed
2344 # to work correctly. Let's not do that; instead, we'll finish 2359 # to work correctly. Let's not do that; instead, we'll finish
2345 # checking this line, and then leave it like that. Assuming the 2360 # checking this line, and then leave it like that. Assuming the
2346 # indentation is done consistently (even if incorrectly), this will 2361 # indentation is done consistently (even if incorrectly), this will
2347 # still catch all indentation issues in practice. 2362 # still catch all indentation issues in practice.
2348 encountered_nested_switch = True 2363 encountered_nested_switch = True
2349 2364
2350 current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_li ne>.*)$', current_line); 2365 current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_li ne>.*)$', current_line)
2351 current_indentation = current_indentation_match.group('indentation') 2366 current_indentation = current_indentation_match.group('indentation')
2352 remaining_line = current_indentation_match.group('remaining_line') 2367 remaining_line = current_indentation_match.group('remaining_line')
2353 2368
2354 # End the check at the end of the switch statement. 2369 # End the check at the end of the switch statement.
2355 if remaining_line.startswith('}') and current_indentation == switch_inde ntation: 2370 if remaining_line.startswith('}') and current_indentation == switch_inde ntation:
2356 break 2371 break
2357 # Case and default branches should not be indented. The regexp also 2372 # Case and default branches should not be indented. The regexp also
2358 # catches single-line cases like "default: break;" but does not trigger 2373 # catches single-line cases like "default: break;" but does not trigger
2359 # on stuff like "Document::Foo();". 2374 # on stuff like "Document::Foo();".
2360 elif match(r'(default|case\s+.*)\s*:([^:].*)?$', remaining_line): 2375 elif match(r'(default|case\s+.*)\s*:([^:].*)?$', remaining_line):
(...skipping 21 matching lines...) Expand all
2382 2397
2383 def check_braces(clean_lines, line_number, error): 2398 def check_braces(clean_lines, line_number, error):
2384 """Looks for misplaced braces (e.g. at the end of line). 2399 """Looks for misplaced braces (e.g. at the end of line).
2385 2400
2386 Args: 2401 Args:
2387 clean_lines: A CleansedLines instance containing the file. 2402 clean_lines: A CleansedLines instance containing the file.
2388 line_number: The number of the line to check. 2403 line_number: The number of the line to check.
2389 error: The function to call with any errors found. 2404 error: The function to call with any errors found.
2390 """ 2405 """
2391 2406
2392 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2407 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2393 2408
2394 if match(r'\s*{\s*$', line): 2409 if match(r'\s*{\s*$', line):
2395 # We allow an open brace to start a line in the case where someone 2410 # We allow an open brace to start a line in the case where someone
2396 # is using braces for function definition or in a block to 2411 # is using braces for function definition or in a block to
2397 # explicitly create a new scope, which is commonly used to control 2412 # explicitly create a new scope, which is commonly used to control
2398 # the lifetime of stack-allocated variables. We don't detect this 2413 # the lifetime of stack-allocated variables. We don't detect this
2399 # perfectly: we just don't complain if the last non-whitespace 2414 # perfectly: we just don't complain if the last non-whitespace
2400 # character on the previous non-blank line is ';', ':', '{', '}', 2415 # character on the previous non-blank line is ';', ':', '{', '}',
2401 # ')' or is like a function declaration, and doesn't begin with 2416 # ')' or is like a function declaration, and doesn't begin with
2402 # 'if|for|while|switch|else' without a beginning '{'. 2417 # 'if|for|while|switch|else' without a beginning '{'.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2452 """Looks for else or else-if statements that should be written as an 2467 """Looks for else or else-if statements that should be written as an
2453 if statement when the prior if concludes with a return, break, continue or 2468 if statement when the prior if concludes with a return, break, continue or
2454 goto statement. 2469 goto statement.
2455 2470
2456 Args: 2471 Args:
2457 clean_lines: A CleansedLines instance containing the file. 2472 clean_lines: A CleansedLines instance containing the file.
2458 line_number: The number of the line to check. 2473 line_number: The number of the line to check.
2459 error: The function to call with any errors found. 2474 error: The function to call with any errors found.
2460 """ 2475 """
2461 2476
2462 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2477 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2463 2478
2464 else_match = match(r'(?P<else_indentation>\s*)(\}\s*)?else(\s+if\s*\(|(?P<el se>\s*(\{\s*)?\Z))', line) 2479 else_match = match(r'(?P<else_indentation>\s*)(\}\s*)?else(\s+if\s*\(|(?P<el se>\s*(\{\s*)?\Z))', line)
2465 if not else_match: 2480 if not else_match:
2466 return 2481 return
2467 2482
2468 else_indentation = else_match.group('else_indentation') 2483 else_indentation = else_match.group('else_indentation')
2469 inner_indentation = else_indentation + ' ' * 4 2484 inner_indentation = else_indentation + ' ' * 4
2470 2485
2471 previous_lines = clean_lines.elided[:line_number] 2486 previous_lines = clean_lines.elided[:line_number]
2472 previous_lines.reverse() 2487 previous_lines.reverse()
2473 line_offset = 0 2488 line_offset = 0
2474 encountered_exit_statement = False 2489 encountered_exit_statement = False
2475 2490
2476 for current_line in previous_lines: 2491 for current_line in previous_lines:
2477 line_offset -= 1 2492 line_offset -= 1
2478 2493
2479 # Skip not only empty lines but also those with preprocessor directives 2494 # Skip not only empty lines but also those with preprocessor directives
2480 # and goto labels. 2495 # and goto labels.
2481 if current_line.strip() == '' or current_line.startswith('#') or match(r '\w+\s*:\s*$', current_line): 2496 if current_line.strip() == '' or current_line.startswith('#') or match(r '\w+\s*:\s*$', current_line):
2482 continue 2497 continue
2483 2498
2484 # Skip lines with closing braces on the original indentation level. 2499 # Skip lines with closing braces on the original indentation level.
2485 # Even though the styleguide says they should be on the same line as 2500 # Even though the styleguide says they should be on the same line as
2486 # the "else if" statement, we also want to check for instances where 2501 # the "else if" statement, we also want to check for instances where
2487 # the current code does not comply with the coding style. Thus, ignore 2502 # the current code does not comply with the coding style. Thus, ignore
2488 # these lines and proceed to the line before that. 2503 # these lines and proceed to the line before that.
2489 if current_line == else_indentation + '}': 2504 if current_line == else_indentation + '}':
2490 continue 2505 continue
2491 2506
2492 current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_li ne>.*)$', current_line); 2507 current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_li ne>.*)$', current_line)
2493 current_indentation = current_indentation_match.group('indentation') 2508 current_indentation = current_indentation_match.group('indentation')
2494 remaining_line = current_indentation_match.group('remaining_line') 2509 remaining_line = current_indentation_match.group('remaining_line')
2495 2510
2496 # As we're going up the lines, the first real statement to encounter 2511 # As we're going up the lines, the first real statement to encounter
2497 # has to be an exit statement (return, break, continue or goto) - 2512 # has to be an exit statement (return, break, continue or goto) -
2498 # otherwise, this check doesn't apply. 2513 # otherwise, this check doesn't apply.
2499 if not encountered_exit_statement: 2514 if not encountered_exit_statement:
2500 # We only want to find exit statements if they are on exactly 2515 # We only want to find exit statements if they are on exactly
2501 # the same level of indentation as expected from the code inside 2516 # the same level of indentation as expected from the code inside
2502 # the block. If the indentation doesn't strictly match then we 2517 # the block. If the indentation doesn't strictly match then we
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 return 2643 return
2629 2644
2630 # Don't warn about NULL usage in gst_*(). See Bug 70498. 2645 # Don't warn about NULL usage in gst_*(). See Bug 70498.
2631 if search(r'\bgst(_[a-z]+)+\b', line): 2646 if search(r'\bgst(_[a-z]+)+\b', line):
2632 return 2647 return
2633 2648
2634 # Don't warn about NULL usage in gdk_pixbuf_save_to_*{join,concat}(). See Bu g 43090. 2649 # Don't warn about NULL usage in gdk_pixbuf_save_to_*{join,concat}(). See Bu g 43090.
2635 if search(r'\bgdk_pixbuf_save_to\w+\b', line): 2650 if search(r'\bgdk_pixbuf_save_to\w+\b', line):
2636 return 2651 return
2637 2652
2638 # Don't warn about NULL usage in gtk_widget_style_get(), gtk_style_context_g et_style(), or gtk_style_context_get(). See Bug 51758 2653 # Don't warn about NULL usage in gtk_widget_style_get(),
2654 # gtk_style_context_get_style(), or gtk_style_context_get(). See Bug 51758
2639 if search(r'\bgtk_widget_style_get\(\w+\b', line) or search(r'\bgtk_style_co ntext_get_style\(\w+\b', line) or search(r'\bgtk_style_context_get\(\w+\b', line ): 2655 if search(r'\bgtk_widget_style_get\(\w+\b', line) or search(r'\bgtk_style_co ntext_get_style\(\w+\b', line) or search(r'\bgtk_style_context_get\(\w+\b', line ):
2640 return 2656 return
2641 2657
2642 # Don't warn about NULL usage in soup_server_new(). See Bug 77890. 2658 # Don't warn about NULL usage in soup_server_new(). See Bug 77890.
2643 if search(r'\bsoup_server_new\(\w+\b', line): 2659 if search(r'\bsoup_server_new\(\w+\b', line):
2644 return 2660 return
2645 2661
2646 if search(r'\bNULL\b', line): 2662 if search(r'\bNULL\b', line):
2647 error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.') 2663 error(line_number, 'readability/null', 5, 'Use 0 instead of NULL.')
2648 return 2664 return
2649 2665
2650 line = clean_lines.raw_lines[line_number] 2666 line = clean_lines.raw_lines[line_number]
2651 # See if NULL occurs in any comments in the line. If the search for NULL usi ng the raw line 2667 # See if NULL occurs in any comments in the line. If the search for NULL usi ng the raw line
2652 # matches, then do the check with strings collapsed to avoid giving errors f or 2668 # matches, then do the check with strings collapsed to avoid giving errors f or
2653 # NULLs occurring in strings. 2669 # NULLs occurring in strings.
2654 if search(r'\bNULL\b', line) and search(r'\bNULL\b', CleansedLines.collapse_ strings(line)): 2670 if search(r'\bNULL\b', line) and search(r'\bNULL\b', CleansedLines.collapse_ strings(line)):
2655 error(line_number, 'readability/null', 4, 'Use 0 or null instead of NULL (even in *comments*).') 2671 error(line_number, 'readability/null', 4, 'Use 0 or null instead of NULL (even in *comments*).')
2656 2672
2673
2657 def get_line_width(line): 2674 def get_line_width(line):
2658 """Determines the width of the line in column positions. 2675 """Determines the width of the line in column positions.
2659 2676
2660 Args: 2677 Args:
2661 line: A string, which may be a Unicode string. 2678 line: A string, which may be a Unicode string.
2662 2679
2663 Returns: 2680 Returns:
2664 The width of the line in column positions, accounting for Unicode 2681 The width of the line in column positions, accounting for Unicode
2665 combining characters and wide characters. 2682 combining characters and wide characters.
2666 """ 2683 """
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 """ 3038 """
3022 3039
3023 # If it is a system header we know it is classified as _OTHER_HEADER. 3040 # If it is a system header we know it is classified as _OTHER_HEADER.
3024 if is_system and not include.startswith('public/'): 3041 if is_system and not include.startswith('public/'):
3025 return _OTHER_HEADER 3042 return _OTHER_HEADER
3026 3043
3027 # There cannot be primary includes in header files themselves. Only an 3044 # There cannot be primary includes in header files themselves. Only an
3028 # include exactly matches the header filename will be is flagged as 3045 # include exactly matches the header filename will be is flagged as
3029 # primary, so that it triggers the "don't include yourself" check. 3046 # primary, so that it triggers the "don't include yourself" check.
3030 if filename.endswith('.h') and filename != include: 3047 if filename.endswith('.h') and filename != include:
3031 return _OTHER_HEADER; 3048 return _OTHER_HEADER
3032 3049
3033 # Qt's moc files do not follow the naming and ordering rules, so they should be skipped 3050 # Qt's moc files do not follow the naming and ordering rules, so they should be skipped
3034 if include.startswith('moc_') and include.endswith('.cpp'): 3051 if include.startswith('moc_') and include.endswith('.cpp'):
3035 return _MOC_HEADER 3052 return _MOC_HEADER
3036 3053
3037 if include.endswith('.moc'): 3054 if include.endswith('.moc'):
3038 return _MOC_HEADER 3055 return _MOC_HEADER
3039 3056
3040 # If the target file basename starts with the include we're checking 3057 # If the target file basename starts with the include we're checking
3041 # then we consider it the primary header. 3058 # then we consider it the primary header.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3139 # 1) for implementation files: primary header, blank line, alphabetically so rted 3156 # 1) for implementation files: primary header, blank line, alphabetically so rted
3140 # 2) for header files: alphabetically sorted 3157 # 2) for header files: alphabetically sorted
3141 # The include_state object keeps track of the last type seen 3158 # The include_state object keeps track of the last type seen
3142 # and complains if the header types are out of order or missing. 3159 # and complains if the header types are out of order or missing.
3143 error_message = include_state.check_next_include_order(header_type, 3160 error_message = include_state.check_next_include_order(header_type,
3144 file_extension == "h" , 3161 file_extension == "h" ,
3145 primary_header_exists ) 3162 primary_header_exists )
3146 3163
3147 # Check to make sure we have a blank line after primary header. 3164 # Check to make sure we have a blank line after primary header.
3148 if not error_message and header_type == _PRIMARY_HEADER: 3165 if not error_message and header_type == _PRIMARY_HEADER:
3149 next_line = clean_lines.raw_lines[line_number + 1] 3166 next_line = clean_lines.raw_lines[line_number + 1]
3150 if not is_blank_line(next_line): 3167 if not is_blank_line(next_line):
3151 error(line_number, 'build/include_order', 4, 3168 error(line_number, 'build/include_order', 4,
3152 'You should add a blank line after implementation file\'s own header.') 3169 'You should add a blank line after implementation file\'s own header.')
3153 3170
3154 # Check to make sure all headers besides the primary header are 3171 # Check to make sure all headers besides the primary header are
3155 # alphabetically sorted. Skip Qt's moc files. 3172 # alphabetically sorted. Skip Qt's moc files.
3156 if not error_message and header_type == _OTHER_HEADER: 3173 if not error_message and header_type == _OTHER_HEADER:
3157 previous_line_number = line_number - 1; 3174 previous_line_number = line_number - 1
3158 previous_line = clean_lines.lines[previous_line_number] 3175 previous_line = clean_lines.lines[previous_line_number]
3159 previous_match = _RE_PATTERN_INCLUDE.search(previous_line) 3176 previous_match = _RE_PATTERN_INCLUDE.search(previous_line)
3160 while (not previous_match and previous_line_number > 0 3177 while (not previous_match and previous_line_number > 0
3161 and not search(r'\A(#if|#ifdef|#ifndef|#else|#elif|#endif)', pre vious_line)): 3178 and not search(r'\A(#if|#ifdef|#ifndef|#else|#elif|#endif)', prev ious_line)):
3162 previous_line_number -= 1; 3179 previous_line_number -= 1
3163 previous_line = clean_lines.lines[previous_line_number] 3180 previous_line = clean_lines.lines[previous_line_number]
3164 previous_match = _RE_PATTERN_INCLUDE.search(previous_line) 3181 previous_match = _RE_PATTERN_INCLUDE.search(previous_line)
3165 if previous_match: 3182 if previous_match:
3166 previous_header_type = include_state.header_types[previous_line_numb er] 3183 previous_header_type = include_state.header_types[previous_line_numb er]
3167 if previous_header_type == _OTHER_HEADER and previous_line.strip() > line.strip(): 3184 if previous_header_type == _OTHER_HEADER and previous_line.strip() > line.strip():
3168 # This type of error is potentially a problem with this line or the previous one, 3185 # This type of error is potentially a problem with this line or the previous one,
3169 # so if the error is filtered for one line, report it for the ne xt. This is so that 3186 # so if the error is filtered for one line, report it for the ne xt. This is so that
3170 # we properly handle patches, for which only modified lines prod uce errors. 3187 # we properly handle patches, for which only modified lines prod uce errors.
3171 if not error(line_number - 1, 'build/include_order', 4, 'Alphabe tical sorting problem.'): 3188 if not error(line_number - 1, 'build/include_order', 4, 'Alphabe tical sorting problem.'):
3172 error(line_number, 'build/include_order', 4, 'Alphabetical s orting problem.') 3189 error(line_number, 'build/include_order', 4, 'Alphabetical s orting problem.')
3173 3190
3174 if error_message: 3191 if error_message:
3175 if file_extension == 'h': 3192 if file_extension == 'h':
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
3382 and search(r'\bnamespace\s*{', line) 3399 and search(r'\bnamespace\s*{', line)
3383 and line[-1] != '\\'): 3400 and line[-1] != '\\'):
3384 error(line_number, 'build/namespaces', 4, 3401 error(line_number, 'build/namespaces', 4,
3385 'Do not use unnamed namespaces in header files. See ' 3402 'Do not use unnamed namespaces in header files. See '
3386 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Na mespaces' 3403 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Na mespaces'
3387 ' for more information.') 3404 ' for more information.')
3388 3405
3389 # Check for plain bitfields declared without either "singed" or "unsigned". 3406 # Check for plain bitfields declared without either "singed" or "unsigned".
3390 # Most compilers treat such bitfields as signed, but there are still compile rs like 3407 # Most compilers treat such bitfields as signed, but there are still compile rs like
3391 # RVCT 4.0 that use unsigned by default. 3408 # RVCT 4.0 that use unsigned by default.
3392 matched = re.match(r'\s*((const|mutable)\s+)?(char|(short(\s+int)?)|int|long (\s+(long|int))?)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\d+\s*;', line) 3409 matched = re.match(
3410 r'\s*((const|mutable)\s+)?(char|(short(\s+int)?)|int|long(\s+(long|int)) ?)\s+[a-zA-Z_][a-zA-Z0-9_]*\s*:\s*\d+\s*;', line)
3393 if matched: 3411 if matched:
3394 error(line_number, 'runtime/bitfields', 5, 3412 error(line_number, 'runtime/bitfields', 5,
3395 'Please declare integral type bitfields with either signed or unsi gned.') 3413 'Please declare integral type bitfields with either signed or unsi gned.')
3396 3414
3397 check_identifier_name_in_declaration(filename, line_number, line, file_state , error) 3415 check_identifier_name_in_declaration(filename, line_number, line, file_state , error)
3398 3416
3399 # Check for unsigned int (should be just 'unsigned') 3417 # Check for unsigned int (should be just 'unsigned')
3400 if search(r'\bunsigned int\b', line): 3418 if search(r'\bunsigned int\b', line):
3401 error(line_number, 'runtime/unsigned', 1, 3419 error(line_number, 'runtime/unsigned', 1,
3402 'Omit int when using unsigned') 3420 'Omit int when using unsigned')
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3511 and not modified_identifier.startswith('Ecore_') 3529 and not modified_identifier.startswith('Ecore_')
3512 and not modified_identifier.startswith('Eina_') 3530 and not modified_identifier.startswith('Eina_')
3513 and not modified_identifier.startswith('Evas_') 3531 and not modified_identifier.startswith('Evas_')
3514 and not modified_identifier.startswith('Ewk_') 3532 and not modified_identifier.startswith('Ewk_')
3515 and not modified_identifier.startswith('cti_') 3533 and not modified_identifier.startswith('cti_')
3516 and not modified_identifier.find('::qt_') >= 0 3534 and not modified_identifier.find('::qt_') >= 0
3517 and not modified_identifier.find('::_q_') >= 0 3535 and not modified_identifier.find('::_q_') >= 0
3518 and not modified_identifier == "const_iterator" 3536 and not modified_identifier == "const_iterator"
3519 and not modified_identifier == "vm_throw" 3537 and not modified_identifier == "vm_throw"
3520 and not modified_identifier == "DFG_OPERATION"): 3538 and not modified_identifier == "DFG_OPERATION"):
3521 error(line_number, 'readability/naming/underscores', 4, identifi er + " is incorrectly named. Don't use underscores in your identifier names.") 3539 error(line_number, 'readability/naming/underscores', 4, identifi er +
3540 " is incorrectly named. Don't use underscores in your iden tifier names.")
3522 3541
3523 # Check for variables named 'l', these are too easy to confuse with '1' in some fonts 3542 # Check for variables named 'l', these are too easy to confuse with '1' in some fonts
3524 if modified_identifier == 'l': 3543 if modified_identifier == 'l':
3525 error(line_number, 'readability/naming', 4, identifier + " is incorr ectly named. Don't use the single letter 'l' as an identifier name.") 3544 error(line_number, 'readability/naming', 4, identifier +
3545 " is incorrectly named. Don't use the single letter 'l' as an identifier name.")
3526 3546
3527 # There can be only one declaration in non-for-control statements. 3547 # There can be only one declaration in non-for-control statements.
3528 if control_statement: 3548 if control_statement:
3529 return 3549 return
3530 # We should continue checking if this is a function 3550 # We should continue checking if this is a function
3531 # declaration because we need to check its arguments. 3551 # declaration because we need to check its arguments.
3532 # Also, we need to check multiple declarations. 3552 # Also, we need to check multiple declarations.
3533 if character_after_identifier != '(' and character_after_identifier != ' ,': 3553 if character_after_identifier != '(' and character_after_identifier != ' ,':
3534 return 3554 return
3535 3555
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
3739 'unary_negate', 'not1', 'binary_negate', 'not2', 3759 'unary_negate', 'not1', 'binary_negate', 'not2',
3740 'bind1st', 'bind2nd', 3760 'bind1st', 'bind2nd',
3741 'pointer_to_unary_function', 3761 'pointer_to_unary_function',
3742 'pointer_to_binary_function', 3762 'pointer_to_binary_function',
3743 'ptr_fun', 3763 'ptr_fun',
3744 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', 3764 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
3745 'mem_fun_ref_t', 3765 'mem_fun_ref_t',
3746 'const_mem_fun_t', 'const_mem_fun1_t', 3766 'const_mem_fun_t', 'const_mem_fun1_t',
3747 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', 3767 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
3748 'mem_fun_ref', 3768 'mem_fun_ref',
3749 )), 3769 )),
3750 ('<limits>', ('numeric_limits',)), 3770 ('<limits>', ('numeric_limits',)),
3751 ('<list>', ('list',)), 3771 ('<list>', ('list',)),
3752 ('<map>', ('map', 'multimap',)), 3772 ('<map>', ('map', 'multimap',)),
3753 ('<memory>', ('allocator',)), 3773 ('<memory>', ('allocator',)),
3754 ('<queue>', ('queue', 'priority_queue',)), 3774 ('<queue>', ('queue', 'priority_queue',)),
3755 ('<set>', ('set', 'multiset',)), 3775 ('<set>', ('set', 'multiset',)),
3756 ('<stack>', ('stack',)), 3776 ('<stack>', ('stack',)),
3757 ('<string>', ('char_traits', 'basic_string',)), 3777 ('<string>', ('char_traits', 'basic_string',)),
3758 ('<utility>', ('pair',)), 3778 ('<utility>', ('pair',)),
3759 ('<vector>', ('vector',)), 3779 ('<vector>', ('vector',)),
3760 3780
3761 # gcc extensions. 3781 # gcc extensions.
3762 # Note: std::hash is their hash, ::hash is our hash 3782 # Note: std::hash is their hash, ::hash is our hash
3763 ('<hash_map>', ('hash_map', 'hash_multimap',)), 3783 ('<hash_map>', ('hash_map', 'hash_multimap',)),
3764 ('<hash_set>', ('hash_set', 'hash_multiset',)), 3784 ('<hash_set>', ('hash_set', 'hash_multiset',)),
3765 ('<slist>', ('slist',)), 3785 ('<slist>', ('slist',)),
3766 ) 3786 )
3767 3787
3768 _HEADERS_ACCEPTED_BUT_NOT_PROMOTED = { 3788 _HEADERS_ACCEPTED_BUT_NOT_PROMOTED = {
3769 # We can trust with reasonable confidence that map gives us pair<>, too. 3789 # We can trust with reasonable confidence that map gives us pair<>, too.
3770 'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap') 3790 'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap')
3771 } 3791 }
3772 3792
3773 _RE_PATTERN_STRING = re.compile(r'\bstring\b') 3793 _RE_PATTERN_STRING = re.compile(r'\bstring\b')
3774 3794
3775 _re_pattern_algorithm_header = [] 3795 _re_pattern_algorithm_header = []
3776 for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap', 3796 for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3884 less<> in a .h file, only one (the latter in the file) of these will be 3904 less<> in a .h file, only one (the latter in the file) of these will be
3885 reported as a reason to include the <functional>. 3905 reported as a reason to include the <functional>.
3886 3906
3887 Args: 3907 Args:
3888 filename: The name of the current file. 3908 filename: The name of the current file.
3889 clean_lines: A CleansedLines instance containing the file. 3909 clean_lines: A CleansedLines instance containing the file.
3890 include_state: An _IncludeState instance. 3910 include_state: An _IncludeState instance.
3891 error: The function to call with any errors found. 3911 error: The function to call with any errors found.
3892 """ 3912 """
3893 required = {} # A map of header name to line_number and the template entity . 3913 required = {} # A map of header name to line_number and the template entity .
3894 # Example of required: { '<functional>': (1219, 'less<>') } 3914 # Example of required: { '<functional>': (1219, 'less<>') }
3895 3915
3896 for line_number in xrange(clean_lines.num_lines()): 3916 for line_number in xrange(clean_lines.num_lines()):
3897 line = clean_lines.elided[line_number] 3917 line = clean_lines.elided[line_number]
3898 if not line or line[0] == '#': 3918 if not line or line[0] == '#':
3899 continue 3919 continue
3900 3920
3901 # String is special -- it is a non-templatized type in STL. 3921 # String is special -- it is a non-templatized type in STL.
3902 if _RE_PATTERN_STRING.search(line): 3922 if _RE_PATTERN_STRING.search(line):
3903 required['<string>'] = (line_number, 'string') 3923 required['<string>'] = (line_number, 'string')
3904 3924
(...skipping 24 matching lines...) Expand all
3929 # If cpp_style is invoked from Emacs's flymake, a temporary file is generate d 3949 # If cpp_style is invoked from Emacs's flymake, a temporary file is generate d
3930 # by flymake and that file name might end with '_flymake.cpp'. In that case, 3950 # by flymake and that file name might end with '_flymake.cpp'. In that case,
3931 # restore original file name here so that the corresponding header file can be 3951 # restore original file name here so that the corresponding header file can be
3932 # found. 3952 # found.
3933 # e.g. If the file name is 'foo_flymake.cpp', we should search for 'foo.h' 3953 # e.g. If the file name is 'foo_flymake.cpp', we should search for 'foo.h'
3934 # instead of 'foo_flymake.h' 3954 # instead of 'foo_flymake.h'
3935 abs_filename = re.sub(r'_flymake\.cpp$', '.cpp', abs_filename) 3955 abs_filename = re.sub(r'_flymake\.cpp$', '.cpp', abs_filename)
3936 3956
3937 # include_state is modified during iteration, so we iterate over a copy of 3957 # include_state is modified during iteration, so we iterate over a copy of
3938 # the keys. 3958 # the keys.
3939 for header in include_state.keys(): #NOLINT 3959 for header in include_state.keys(): # NOLINT
3940 (same_module, common_path) = files_belong_to_same_module(abs_filename, h eader) 3960 (same_module, common_path) = files_belong_to_same_module(abs_filename, h eader)
3941 fullpath = common_path + header 3961 fullpath = common_path + header
3942 if same_module and update_include_state(fullpath, include_state): 3962 if same_module and update_include_state(fullpath, include_state):
3943 header_found = True 3963 header_found = True
3944 3964
3945 # If we can't find the header file for a .cpp, assume it's because we don't 3965 # If we can't find the header file for a .cpp, assume it's because we don't
3946 # know where to look. In that case we'll give up as we're not sure they 3966 # know where to look. In that case we'll give up as we're not sure they
3947 # didn't include it in the .h file. 3967 # didn't include it in the .h file.
3948 # FIXME: Do a better job of finding .h files so we are confident that 3968 # FIXME: Do a better job of finding .h files so we are confident that
3949 # not having the .h file means there isn't one. 3969 # not having the .h file means there isn't one.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4000 check_style(clean_lines, line, file_extension, class_state, file_state, enum _state, error) 4020 check_style(clean_lines, line, file_extension, class_state, file_state, enum _state, error)
4001 check_language(filename, clean_lines, line, file_extension, include_state, 4021 check_language(filename, clean_lines, line, file_extension, include_state,
4002 file_state, error) 4022 file_state, error)
4003 check_for_non_standard_constructs(clean_lines, line, class_state, error) 4023 check_for_non_standard_constructs(clean_lines, line, class_state, error)
4004 check_posix_threading(clean_lines, line, error) 4024 check_posix_threading(clean_lines, line, error)
4005 check_invalid_increment(clean_lines, line, error) 4025 check_invalid_increment(clean_lines, line, error)
4006 check_conditional_and_loop_bodies_for_brace_violations(clean_lines, line, er ror) 4026 check_conditional_and_loop_bodies_for_brace_violations(clean_lines, line, er ror)
4007 check_redundant_virtual(clean_lines, line, error) 4027 check_redundant_virtual(clean_lines, line, error)
4008 check_redundant_override(clean_lines, line, error) 4028 check_redundant_override(clean_lines, line, error)
4009 4029
4030
4010 def _process_lines(filename, file_extension, lines, error, min_confidence): 4031 def _process_lines(filename, file_extension, lines, error, min_confidence):
4011 """Performs lint checks and reports any errors to the given error function. 4032 """Performs lint checks and reports any errors to the given error function.
4012 4033
4013 Args: 4034 Args:
4014 filename: Filename of the file that is being processed. 4035 filename: Filename of the file that is being processed.
4015 file_extension: The extension (dot not included) of the file. 4036 file_extension: The extension (dot not included) of the file.
4016 lines: An array of strings, each representing a line of the file, with the 4037 lines: An array of strings, each representing a line of the file, with the
4017 last element being empty if the file is termined with a newline. 4038 last element being empty if the file is termined with a newline.
4018 error: A callable to which errors are reported, which takes 4 arguments: 4039 error: A callable to which errors are reported, which takes 4 arguments:
4019 """ 4040 """
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4122 'whitespace/end_of_line', 4143 'whitespace/end_of_line',
4123 'whitespace/ending_newline', 4144 'whitespace/ending_newline',
4124 'whitespace/indent', 4145 'whitespace/indent',
4125 'whitespace/line_length', 4146 'whitespace/line_length',
4126 'whitespace/newline', 4147 'whitespace/newline',
4127 'whitespace/operators', 4148 'whitespace/operators',
4128 'whitespace/parens', 4149 'whitespace/parens',
4129 'whitespace/semicolon', 4150 'whitespace/semicolon',
4130 'whitespace/tab', 4151 'whitespace/tab',
4131 'whitespace/todo', 4152 'whitespace/todo',
4132 ]) 4153 ])
4133 4154
4134 fs = None 4155 fs = None
4135 4156
4136 def __init__(self, file_path, file_extension, handle_style_error, 4157 def __init__(self, file_path, file_extension, handle_style_error,
4137 min_confidence, fs=None): 4158 min_confidence, fs=None):
4138 """Create a CppChecker instance. 4159 """Create a CppChecker instance.
4139 4160
4140 Args: 4161 Args:
4141 file_extension: A string that is the file extension, without 4162 file_extension: A string that is the file extension, without
4142 the leading dot. 4163 the leading dot.
(...skipping 26 matching lines...) Expand all
4169 4190
4170 def check(self, lines): 4191 def check(self, lines):
4171 _process_lines(self.file_path, self.file_extension, lines, 4192 _process_lines(self.file_path, self.file_extension, lines,
4172 self.handle_style_error, self.min_confidence) 4193 self.handle_style_error, self.min_confidence)
4173 4194
4174 4195
4175 # FIXME: Remove this function (requires refactoring unit tests). 4196 # FIXME: Remove this function (requires refactoring unit tests).
4176 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None): 4197 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None):
4177 checker = CppChecker(filename, file_extension, error, min_confidence, fs) 4198 checker = CppChecker(filename, file_extension, error, min_confidence, fs)
4178 checker.check(lines) 4199 checker.check(lines)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698