~ubuntu-branches/ubuntu/saucy/drizzle/saucy-proposed

« back to all changes in this revision

Viewing changes to extra/cpplint.py

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python2.4
 
2
#
 
3
# cpplint.py is Copyright (C) 2009 Google Inc.
 
4
#
 
5
# It is free software; you can redistribute it and/or modify it under the
 
6
# terms of either:
 
7
#
 
8
# a) the GNU General Public License as published by the Free Software
 
9
# Foundation; either version 1, or (at your option) any later version, or
 
10
#
 
11
# b) the "Artistic License".
 
12
 
 
13
# Modified for Drizzle by Monty Taylor & Robert Collins
 
14
 
 
15
# Here are some issues that I've had people identify in my code during reviews,
 
16
# that I think are possible to flag automatically in a lint tool.  If these were
 
17
# caught by lint, it would save time both for myself and that of my reviewers.
 
18
# Most likely, some of these are beyond the scope of the current lint framework,
 
19
# but I think it is valuable to retain these wish-list items even if they cannot
 
20
# be immediately implemented.
 
21
#
 
22
#  Suggestions
 
23
#  -----------
 
24
#  - Check for no 'explicit' for multi-arg ctor
 
25
#  - Check for boolean assign RHS in parens
 
26
#  - Check for ctor initializer-list colon position and spacing
 
27
#  - Check that if there's a ctor, there should be a dtor
 
28
#  - Check accessors that return non-pointer member variables are
 
29
#    declared const
 
30
#  - Check accessors that return non-const pointer member vars are
 
31
#    *not* declared const
 
32
#  - Check for using public includes for testing
 
33
#  - Check for spaces between brackets in one-line inline method
 
34
#  - Check for no assert()
 
35
#  - Check for spaces surrounding operators
 
36
#  - Check for 0 in pointer context (should be NULL)
 
37
#  - Check for 0 in char context (should be '\0')
 
38
#  - Check for camel-case method name conventions for methods
 
39
#    that are not simple inline getters and setters
 
40
#  - Check that base classes have virtual destructors
 
41
#    put "  // namespace" after } that closes a namespace, with
 
42
#    namespace's name after 'namespace' if it is named.
 
43
#  - Do not indent namespace contents
 
44
#  - Avoid inlining non-trivial constructors in header files
 
45
#    include base/basictypes.h if DISALLOW_EVIL_CONSTRUCTORS is used
 
46
#  - Check for old-school (void) cast for call-sites of functions
 
47
#    ignored return value
 
48
#  - Check gUnit usage of anonymous namespace
 
49
#  - Check for class declaration order (typedefs, consts, enums,
 
50
#    ctor(s?), dtor, friend declarations, methods, member vars)
 
51
#
 
52
 
 
53
"""Does google-lint on c++ files.
 
54
 
 
55
The goal of this script is to identify places in the code that *may*
 
56
be in non-compliance with google style.  It does not attempt to fix
 
57
up these problems -- the point is to educate.  It does also not
 
58
attempt to find all problems, or to ensure that everything it does
 
59
find is legitimately a problem.
 
60
 
 
61
In particular, we can get very confused by /* and // inside strings!
 
62
We do a small hack, which is to ignore //'s with "'s after them on the
 
63
same line, but it is far from perfect (in either direction).
 
64
"""
 
65
 
 
66
import codecs
 
67
import getopt
 
68
import math  # for log
 
69
import os
 
70
import re
 
71
import sre_compile
 
72
import string
 
73
import sys
 
74
import unicodedata
 
75
 
 
76
 
 
77
_USAGE = """
 
78
Syntax: cpplint.py [--verbose=#] [--output=vs7] [--deps=path] [--filter=-x,+y,...]
 
79
        <file> [file] ...
 
80
 
 
81
  The style guidelines this tries to follow are those in
 
82
    http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
 
83
 
 
84
  Every problem is given a confidence score from 1-5, with 5 meaning we are
 
85
  certain of the problem, and 1 meaning it could be a legitimate construct.
 
86
  This will miss some errors, and is not a substitute for a code review.
 
87
 
 
88
  To prevent specific lines from being linted, add a '// NOLINT' comment to the
 
89
  end of the line.
 
90
 
 
91
  The files passed in will be linted; at least one file must be provided.
 
92
  Linted extensions are .cc, .cpp, and .h.  Other file types will be ignored.
 
93
 
 
94
  Flags:
 
95
 
 
96
    output=vs7
 
97
      By default, the output is formatted to ease emacs parsing.  Visual Studio
 
98
      compatible output (vs7) may also be used.  Other formats are unsupported.
 
99
 
 
100
    verbose=#
 
101
      Specify a number 0-5 to restrict errors to certain verbosity levels.
 
102
 
 
103
    deps=path
 
104
      write out a Makefile that can be included listing the files included
 
105
      during the lint process as make style dependencies with null-build rules
 
106
      (so that deleted headers will not cause failures). This can be useful to
 
107
      perform on-demand linting. The top level target will be the name of the
 
108
      lint file itself.
 
109
 
 
110
    filter=-x,+y,...
 
111
      Specify a comma-separated list of category-filters to apply: only
 
112
      error messages whose category names pass the filters will be printed.
 
113
      (Category names are printed with the message and look like
 
114
      "[whitespace/indent]".)  Filters are evaluated left to right.
 
115
      "-FOO" and "FOO" means "do not print categories that start with FOO".
 
116
      "+FOO" means "do print categories that start with FOO".
 
117
 
 
118
      Examples: --filter=-whitespace,+whitespace/braces
 
119
                --filter=whitespace,runtime/printf,+runtime/printf_format
 
120
                --filter=-,+build/include_what_you_use
 
121
 
 
122
      To see a list of all the categories used in cpplint, pass no arg:
 
123
         --filter=
 
124
"""
 
125
 
 
126
# We categorize each error message we print.  Here are the categories.
 
127
# We want an explicit list so we can list them all in cpplint --filter=.
 
128
# If you add a new error message with a new category, add it to the list
 
129
# here!  cpplint_unittest.py should tell you if you forget to do this.
 
130
# \ used for clearer layout -- pylint: disable-msg=C6013
 
131
_ERROR_CATEGORIES = '''\
 
132
  build/class
 
133
  build/deprecated
 
134
  build/endif_comment
 
135
  build/forward_decl
 
136
  build/header_guard
 
137
  build/include
 
138
  build/include_config
 
139
  build/include_order
 
140
  build/include_what_you_use
 
141
  build/namespaces
 
142
  build/printf_format
 
143
  build/storage_class
 
144
  legal/copyright
 
145
  readability/braces
 
146
  readability/casting
 
147
  readability/check
 
148
  readability/constructors
 
149
  readability/fn_size
 
150
  readability/function
 
151
  readability/multiline_comment
 
152
  readability/multiline_string
 
153
  readability/streams
 
154
  readability/todo
 
155
  readability/utf8
 
156
  runtime/arrays
 
157
  runtime/casting
 
158
  runtime/explicit
 
159
  runtime/int
 
160
  runtime/init
 
161
  runtime/invalid_increment
 
162
  runtime/memset
 
163
  runtime/printf
 
164
  runtime/printf_format
 
165
  runtime/references
 
166
  runtime/rtti
 
167
  runtime/sizeof
 
168
  runtime/string
 
169
  runtime/threadsafe_fn
 
170
  runtime/virtual
 
171
  whitespace/blank_line
 
172
  whitespace/braces
 
173
  whitespace/comma
 
174
  whitespace/comments
 
175
  whitespace/end_of_line
 
176
  whitespace/ending_newline
 
177
  whitespace/indent
 
178
  whitespace/labels
 
179
  whitespace/line_length
 
180
  whitespace/newline
 
181
  whitespace/operators
 
182
  whitespace/parens
 
183
  whitespace/semicolon
 
184
  whitespace/tab
 
185
  whitespace/todo
 
186
'''
 
187
 
 
188
# The default state of the category filter. This is overrided by the --filter=
 
189
# flag. By default all errors are on, so only add here categories that should be
 
190
# off by default (i.e., categories that must be enabled by the --filter= flags).
 
191
# All entries here should start with a '-' or '+', as in the --filter= flag.
 
192
_DEFAULT_FILTERS = []
 
193
 
 
194
# We used to check for high-bit characters, but after much discussion we
 
195
# decided those were OK, as long as they were in UTF-8 and didn't represent
 
196
# hard-coded international strings, which belong in a seperate i18n file.
 
197
 
 
198
# Headers that we consider STL headers.
 
199
_STL_HEADERS = frozenset([
 
200
    'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
 
201
    'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
 
202
    'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'pair.h',
 
203
    'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
 
204
    'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
 
205
    'utility', 'vector', 'vector.h',
 
206
    ])
 
207
 
 
208
 
 
209
# Non-STL C++ system headers.
 
210
_CPP_HEADERS = frozenset([
 
211
    'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
 
212
    'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
 
213
    'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
 
214
    'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
 
215
    'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
 
216
    'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
 
217
    'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream.h',
 
218
    'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
 
219
    'numeric', 'ostream.h', 'parsestream.h', 'pfstream.h', 'PlotFile.h',
 
220
    'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h', 'ropeimpl.h',
 
221
    'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
 
222
    'stdiostream.h', 'streambuf.h', 'stream.h', 'strfile.h', 'string',
 
223
    'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo', 'valarray',
 
224
    ])
 
225
 
 
226
 
 
227
# Assertion macros.  These are defined in base/logging.h and
 
228
# testing/base/gunit.h.  Note that the _M versions need to come first
 
229
# for substring matching to work.
 
230
_CHECK_MACROS = [
 
231
    'DCHECK', 'CHECK',
 
232
    'EXPECT_TRUE_M', 'EXPECT_TRUE',
 
233
    'ASSERT_TRUE_M', 'ASSERT_TRUE',
 
234
    'EXPECT_FALSE_M', 'EXPECT_FALSE',
 
235
    'ASSERT_FALSE_M', 'ASSERT_FALSE',
 
236
    ]
 
237
 
 
238
# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
 
239
_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
 
240
 
 
241
for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
 
242
                        ('>=', 'GE'), ('>', 'GT'),
 
243
                        ('<=', 'LE'), ('<', 'LT')]:
 
244
  _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
 
245
  _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
 
246
  _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
 
247
  _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
 
248
  _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
 
249
  _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
 
250
 
 
251
for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
 
252
                            ('>=', 'LT'), ('>', 'LE'),
 
253
                            ('<=', 'GT'), ('<', 'GE')]:
 
254
  _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
 
255
  _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
 
256
  _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
 
257
  _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
 
258
 
 
259
 
 
260
# These constants define types of headers for use with
 
261
# _IncludeState.CheckNextIncludeOrder().
 
262
_C_SYS_HEADER = 1
 
263
_CPP_SYS_HEADER = 2
 
264
_LIKELY_MY_HEADER = 3
 
265
_POSSIBLE_MY_HEADER = 4
 
266
_OTHER_HEADER = 5
 
267
 
 
268
 
 
269
_regexp_compile_cache = {}
 
270
 
 
271
 
 
272
def Match(pattern, s):
 
273
  """Matches the string with the pattern, caching the compiled regexp."""
 
274
  # The regexp compilation caching is inlined in both Match and Search for
 
275
  # performance reasons; factoring it out into a separate function turns out
 
276
  # to be noticeably expensive.
 
277
  if not pattern in _regexp_compile_cache:
 
278
    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
 
279
  return _regexp_compile_cache[pattern].match(s)
 
280
 
 
281
 
 
282
def Search(pattern, s):
 
283
  """Searches the string for the pattern, caching the compiled regexp."""
 
284
  if not pattern in _regexp_compile_cache:
 
285
    _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
 
286
  return _regexp_compile_cache[pattern].search(s)
 
287
 
 
288
 
 
289
class _IncludeState(dict):
 
290
  """Tracks line numbers for includes, and the order in which includes appear.
 
291
 
 
292
  As a dict, an _IncludeState object serves as a mapping between include
 
293
  filename and line number on which that file was included.
 
294
 
 
295
  Call CheckNextIncludeOrder() once for each header in the file, passing
 
296
  in the type constants defined above. Calls in an illegal order will
 
297
  raise an _IncludeError with an appropriate error message.
 
298
 
 
299
  """
 
300
  # self._section will move monotonically through this set. If it ever
 
301
  # needs to move backwards, CheckNextIncludeOrder will raise an error.
 
302
  _INITIAL_SECTION = 0
 
303
  _MY_H_SECTION = 1
 
304
  _C_SECTION = 2
 
305
  _CPP_SECTION = 3
 
306
  _OTHER_H_SECTION = 4
 
307
 
 
308
  _TYPE_NAMES = {
 
309
      _C_SYS_HEADER: 'C system header',
 
310
      _CPP_SYS_HEADER: 'C++ system header',
 
311
      _LIKELY_MY_HEADER: 'header this file implements',
 
312
      _POSSIBLE_MY_HEADER: 'header this file may implement',
 
313
      _OTHER_HEADER: 'other header',
 
314
      }
 
315
  _SECTION_NAMES = {
 
316
      _INITIAL_SECTION: "... nothing. (This can't be an error.)",
 
317
      _MY_H_SECTION: 'a header this file implements',
 
318
      _C_SECTION: 'C system header',
 
319
      _CPP_SECTION: 'C++ system header',
 
320
      _OTHER_H_SECTION: 'other header',
 
321
      }
 
322
 
 
323
  def __init__(self):
 
324
    dict.__init__(self)
 
325
    self._section = self._INITIAL_SECTION
 
326
 
 
327
  def CheckNextIncludeOrder(self, header_type):
 
328
    """Returns a non-empty error message if the next header is out of order.
 
329
 
 
330
    This function also updates the internal state to be ready to check
 
331
    the next include.
 
332
 
 
333
    Args:
 
334
      header_type: One of the _XXX_HEADER constants defined above.
 
335
 
 
336
    Returns:
 
337
      The empty string if the header is in the right order, or an
 
338
      error message describing what's wrong.
 
339
 
 
340
    """
 
341
    error_message = ('Found %s after %s' %
 
342
                     (self._TYPE_NAMES[header_type],
 
343
                      self._SECTION_NAMES[self._section]))
 
344
 
 
345
    if header_type == _C_SYS_HEADER:
 
346
      if self._section <= self._C_SECTION:
 
347
        self._section = self._C_SECTION
 
348
      else:
 
349
        return error_message
 
350
    elif header_type == _CPP_SYS_HEADER:
 
351
      if self._section <= self._CPP_SECTION:
 
352
        self._section = self._CPP_SECTION
 
353
      else:
 
354
        return error_message
 
355
    elif header_type == _LIKELY_MY_HEADER:
 
356
      if self._section <= self._MY_H_SECTION:
 
357
        self._section = self._MY_H_SECTION
 
358
      else:
 
359
        self._section = self._OTHER_H_SECTION
 
360
    elif header_type == _POSSIBLE_MY_HEADER:
 
361
      if self._section <= self._MY_H_SECTION:
 
362
        self._section = self._MY_H_SECTION
 
363
      else:
 
364
        # This will always be the fallback because we're not sure
 
365
        # enough that the header is associated with this file.
 
366
        self._section = self._OTHER_H_SECTION
 
367
    else:
 
368
      assert header_type == _OTHER_HEADER
 
369
      self._section = self._OTHER_H_SECTION
 
370
 
 
371
    return ''
 
372
 
 
373
 
 
374
class _CppLintState(object):
 
375
  """Maintains module-wide state.."""
 
376
 
 
377
  def __init__(self):
 
378
    self.verbose_level = 1  # global setting.
 
379
    self.error_count = 0    # global count of reported errors
 
380
    # filters to apply when emitting error messages
 
381
    self.filters = _DEFAULT_FILTERS[:]
 
382
 
 
383
    # output format:
 
384
    # "emacs" - format that emacs can parse (default)
 
385
    # "vs7" - format that Microsoft Visual Studio 7 can parse
 
386
    self.output_format = 'emacs'
 
387
 
 
388
    # deps
 
389
    self.depfilename = None
 
390
    self.seen_fnames = set()
 
391
 
 
392
  def finished(self):
 
393
    """Complete things that wait for the end of the lint operation."""
 
394
    if self.depfilename is not None:
 
395
      if self.error_count:
 
396
          # Don't alter dependency data
 
397
          return
 
398
      depfile = file(self.depfilename, 'w+')
 
399
      # depend on what we read
 
400
      depfile.write("%s: " % self.depfilename)
 
401
      names = sorted(self.seen_fnames)
 
402
      depfile.write(' '.join(names))
 
403
      depfile.write('\n')
 
404
      # anything we read shouldn't cause an error if its missing - so claim
 
405
      # it can be made.
 
406
      for name in names:
 
407
        depfile.write('%s:\n' % name)
 
408
      depfile.close()
 
409
 
 
410
  def seen_file(self, fname):
 
411
    self.seen_fnames.add(fname)
 
412
 
 
413
  def SetOutputFormat(self, output_format):
 
414
    """Sets the output format for errors."""
 
415
    self.output_format = output_format
 
416
 
 
417
  def SetVerboseLevel(self, level):
 
418
    """Sets the module's verbosity, and returns the previous setting."""
 
419
    last_verbose_level = self.verbose_level
 
420
    self.verbose_level = level
 
421
    return last_verbose_level
 
422
 
 
423
  def SetFilters(self, filters):
 
424
    """Sets the error-message filters.
 
425
 
 
426
    These filters are applied when deciding whether to emit a given
 
427
    error message.
 
428
 
 
429
    Args:
 
430
      filters: A string of comma-separated filters (eg "+whitespace/indent").
 
431
               Each filter should start with + or -; else we die.
 
432
 
 
433
    Raises:
 
434
      ValueError: The comma-separated filters did not all start with '+' or '-'.
 
435
                  E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
 
436
    """
 
437
    # Default filters always have less priority than the flag ones.
 
438
    self.filters = _DEFAULT_FILTERS[:]
 
439
    for filt in filters.split(','):
 
440
      clean_filt = filt.strip()
 
441
      if clean_filt:
 
442
        self.filters.append(clean_filt)
 
443
    for filt in self.filters:
 
444
      if not (filt.startswith('+') or filt.startswith('-')):
 
445
        raise ValueError('Every filter in --filters must start with + or -'
 
446
                         ' (%s does not)' % filt)
 
447
 
 
448
  def ResetErrorCount(self):
 
449
    """Sets the module's error statistic back to zero."""
 
450
    self.error_count = 0
 
451
 
 
452
  def IncrementErrorCount(self):
 
453
    """Bumps the module's error statistic."""
 
454
    self.error_count += 1
 
455
 
 
456
 
 
457
_cpplint_state = _CppLintState()
 
458
 
 
459
 
 
460
def _OutputFormat():
 
461
  """Gets the module's output format."""
 
462
  return _cpplint_state.output_format
 
463
 
 
464
 
 
465
def _SetOutputFormat(output_format):
 
466
  """Sets the module's output format."""
 
467
  _cpplint_state.SetOutputFormat(output_format)
 
468
 
 
469
 
 
470
def _VerboseLevel():
 
471
  """Returns the module's verbosity setting."""
 
472
  return _cpplint_state.verbose_level
 
473
 
 
474
 
 
475
def _SetVerboseLevel(level):
 
476
  """Sets the module's verbosity, and returns the previous setting."""
 
477
  return _cpplint_state.SetVerboseLevel(level)
 
478
 
 
479
 
 
480
def _Filters():
 
481
  """Returns the module's list of output filters, as a list."""
 
482
  return _cpplint_state.filters
 
483
 
 
484
 
 
485
def _SetFilters(filters):
 
486
  """Sets the module's error-message filters.
 
487
 
 
488
  These filters are applied when deciding whether to emit a given
 
489
  error message.
 
490
 
 
491
  Args:
 
492
    filters: A string of comma-separated filters (eg "whitespace/indent").
 
493
             Each filter should start with + or -; else we die.
 
494
  """
 
495
  _cpplint_state.SetFilters(filters)
 
496
 
 
497
 
 
498
class _FunctionState(object):
 
499
  """Tracks current function name and the number of lines in its body."""
 
500
 
 
501
  _NORMAL_TRIGGER = 250  # for --v=0, 500 for --v=1, etc.
 
502
  _TEST_TRIGGER = 400    # about 50% more than _NORMAL_TRIGGER.
 
503
 
 
504
  def __init__(self):
 
505
    self.in_a_function = False
 
506
    self.lines_in_function = 0
 
507
    self.current_function = ''
 
508
 
 
509
  def Begin(self, function_name):
 
510
    """Start analyzing function body.
 
511
 
 
512
    Args:
 
513
      function_name: The name of the function being tracked.
 
514
    """
 
515
    self.in_a_function = True
 
516
    self.lines_in_function = 0
 
517
    self.current_function = function_name
 
518
 
 
519
  def Count(self):
 
520
    """Count line in current function body."""
 
521
    if self.in_a_function:
 
522
      self.lines_in_function += 1
 
523
 
 
524
  def Check(self, error, filename, linenum):
 
525
    """Report if too many lines in function body.
 
526
 
 
527
    Args:
 
528
      error: The function to call with any errors found.
 
529
      filename: The name of the current file.
 
530
      linenum: The number of the line to check.
 
531
    """
 
532
    if Match(r'T(EST|est)', self.current_function):
 
533
      base_trigger = self._TEST_TRIGGER
 
534
    else:
 
535
      base_trigger = self._NORMAL_TRIGGER
 
536
    trigger = base_trigger * 2**_VerboseLevel()
 
537
 
 
538
    if self.lines_in_function > trigger:
 
539
      error_level = int(math.log(self.lines_in_function / base_trigger, 2))
 
540
      # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
 
541
      if error_level > 5:
 
542
        error_level = 5
 
543
      error(filename, linenum, 'readability/fn_size', error_level,
 
544
            'Small and focused functions are preferred:'
 
545
            ' %s has %d non-comment lines'
 
546
            ' (error triggered by exceeding %d lines).'  % (
 
547
                self.current_function, self.lines_in_function, trigger))
 
548
 
 
549
  def End(self):
 
550
    """Stop analizing function body."""
 
551
    self.in_a_function = False
 
552
 
 
553
 
 
554
class _IncludeError(Exception):
 
555
  """Indicates a problem with the include order in a file."""
 
556
  pass
 
557
 
 
558
 
 
559
class FileInfo:
 
560
  """Provides utility functions for filenames.
 
561
 
 
562
  FileInfo provides easy access to the components of a file's path
 
563
  relative to the project root.
 
564
  """
 
565
 
 
566
  def __init__(self, filename):
 
567
    self._filename = filename
 
568
 
 
569
  def FullName(self):
 
570
    """Make Windows paths like Unix."""
 
571
    return os.path.abspath(self._filename).replace('\\', '/')
 
572
 
 
573
  def RepositoryName(self):
 
574
    """FullName after removing the local path to the repository.
 
575
 
 
576
    If we have a real absolute path name here we can try to do something smart:
 
577
    detecting the root of the checkout and truncating /path/to/checkout from
 
578
    the name so that we get header guards that don't include things like
 
579
    "C:\Documents and Settings\..." or "/home/username/..." in them and thus
 
580
    people on different computers who have checked the source out to different
 
581
    locations won't see bogus errors.
 
582
    """
 
583
    fullname = self.FullName()
 
584
 
 
585
    if os.path.exists(fullname):
 
586
      project_dir = os.path.dirname(fullname)
 
587
 
 
588
      root_dir = os.path.dirname(fullname)
 
589
      while (root_dir != os.path.dirname(root_dir) and
 
590
             not (os.path.exists(os.path.join(root_dir, ".bzr"))
 
591
                  or
 
592
                  os.path.exists(os.path.join(root_dir, "_build")))):
 
593
        root_dir = os.path.dirname(root_dir)
 
594
        if (os.path.exists(os.path.join(root_dir, ".bzr")) or
 
595
            os.path.exists(os.path.join(root_dir, "_build"))):
 
596
          prefix = os.path.commonprefix([root_dir, project_dir])
 
597
          return fullname[len(prefix) + 1:]
 
598
 
 
599
    # Don't know what to do; header guard warnings may be wrong...
 
600
    return fullname
 
601
 
 
602
  def Split(self):
 
603
    """Splits the file into the directory, basename, and extension.
 
604
 
 
605
    For 'chrome/browser/browser.cc', Split() would
 
606
    return ('chrome/browser', 'browser', '.cc')
 
607
 
 
608
    Returns:
 
609
      A tuple of (directory, basename, extension).
 
610
    """
 
611
 
 
612
    googlename = self.RepositoryName()
 
613
    project, rest = os.path.split(googlename)
 
614
    return (project,) + os.path.splitext(rest)
 
615
 
 
616
  def BaseName(self):
 
617
    """File base name - text after the final slash, before the final period."""
 
618
    return self.Split()[1]
 
619
 
 
620
  def Extension(self):
 
621
    """File extension - text following the final period."""
 
622
    return self.Split()[2]
 
623
 
 
624
  def NoExtension(self):
 
625
    """File has no source file extension."""
 
626
    return '/'.join(self.Split()[0:2])
 
627
 
 
628
  def IsSource(self):
 
629
    """File has a source file extension."""
 
630
    return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
 
631
 
 
632
 
 
633
def _ShouldPrintError(category, confidence):
 
634
  """Returns true iff confidence >= verbose, and category passes filter."""
 
635
  # There are two ways we might decide not to print an error message:
 
636
  # the verbosity level isn't high enough, or the filters filter it out.
 
637
  if confidence < _cpplint_state.verbose_level:
 
638
    return False
 
639
 
 
640
  is_filtered = False
 
641
  for one_filter in _Filters():
 
642
    if one_filter.startswith('-'):
 
643
      if category.startswith(one_filter[1:]):
 
644
        is_filtered = True
 
645
    elif one_filter.startswith('+'):
 
646
      if category.startswith(one_filter[1:]):
 
647
        is_filtered = False
 
648
    else:
 
649
      assert False  # should have been checked for in SetFilter.
 
650
  if is_filtered:
 
651
    return False
 
652
 
 
653
  return True
 
654
 
 
655
 
 
656
def Error(filename, linenum, category, confidence, message):
 
657
  """Logs the fact we've found a lint error.
 
658
 
 
659
  We log where the error was found, and also our confidence in the error,
 
660
  that is, how certain we are this is a legitimate style regression, and
 
661
  not a misidentification or a use that's sometimes justified.
 
662
 
 
663
  Args:
 
664
    filename: The name of the file containing the error.
 
665
    linenum: The number of the line containing the error.
 
666
    category: A string used to describe the "category" this bug
 
667
      falls under: "whitespace", say, or "runtime".  Categories
 
668
      may have a hierarchy separated by slashes: "whitespace/indent".
 
669
    confidence: A number from 1-5 representing a confidence score for
 
670
      the error, with 5 meaning that we are certain of the problem,
 
671
      and 1 meaning that it could be a legitimate construct.
 
672
    message: The error message.
 
673
  """
 
674
  # There are two ways we might decide not to print an error message:
 
675
  # the verbosity level isn't high enough, or the filters filter it out.
 
676
  if _ShouldPrintError(category, confidence):
 
677
    _cpplint_state.IncrementErrorCount()
 
678
    if _cpplint_state.output_format == 'vs7':
 
679
      sys.stderr.write('%s(%s):  %s  [%s] [%d]\n' % (
 
680
          filename, linenum, message, category, confidence))
 
681
    else:
 
682
      sys.stderr.write('%s:%s:  %s  [%s] [%d]\n' % (
 
683
          filename, linenum, message, category, confidence))
 
684
 
 
685
 
 
686
# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
 
687
_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
 
688
    r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
 
689
# Matches strings.  Escape codes should already be removed by ESCAPES.
 
690
_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
 
691
# Matches characters.  Escape codes should already be removed by ESCAPES.
 
692
_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
 
693
# Matches multi-line C++ comments.
 
694
# This RE is a little bit more complicated than one might expect, because we
 
695
# have to take care of space removals tools so we can handle comments inside
 
696
# statements better.
 
697
# The current rule is: We only clear spaces from both sides when we're at the
 
698
# end of the line. Otherwise, we try to remove spaces from the right side,
 
699
# if this doesn't work we try on left side but only if there's a non-character
 
700
# on the right.
 
701
_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
 
702
    r"""(\s*/\*.*\*/\s*$|
 
703
            /\*.*\*/\s+|
 
704
         \s+/\*.*\*/(?=\W)|
 
705
            /\*.*\*/)""", re.VERBOSE)
 
706
 
 
707
 
 
708
def IsCppString(line):
 
709
  """Does line terminate so, that the next symbol is in string constant.
 
710
 
 
711
  This function does not consider single-line nor multi-line comments.
 
712
 
 
713
  Args:
 
714
    line: is a partial line of code starting from the 0..n.
 
715
 
 
716
  Returns:
 
717
    True, if next character appended to 'line' is inside a
 
718
    string constant.
 
719
  """
 
720
 
 
721
  line = line.replace(r'\\', 'XX')  # after this, \\" does not match to \"
 
722
  return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
 
723
 
 
724
 
 
725
def FindNextMultiLineCommentStart(lines, lineix):
 
726
  """Find the beginning marker for a multiline comment."""
 
727
  while lineix < len(lines):
 
728
    if lines[lineix].strip().startswith('/*'):
 
729
      # Only return this marker if the comment goes beyond this line
 
730
      if lines[lineix].strip().find('*/', 2) < 0:
 
731
        return lineix
 
732
    lineix += 1
 
733
  return len(lines)
 
734
 
 
735
 
 
736
def FindNextMultiLineCommentEnd(lines, lineix):
 
737
  """We are inside a comment, find the end marker."""
 
738
  while lineix < len(lines):
 
739
    if lines[lineix].strip().endswith('*/'):
 
740
      return lineix
 
741
    lineix += 1
 
742
  return len(lines)
 
743
 
 
744
 
 
745
def RemoveMultiLineCommentsFromRange(lines, begin, end):
 
746
  """Clears a range of lines for multi-line comments."""
 
747
  # Having // dummy comments makes the lines non-empty, so we will not get
 
748
  # unnecessary blank line warnings later in the code.
 
749
  for i in range(begin, end):
 
750
    lines[i] = '// dummy'
 
751
 
 
752
 
 
753
def RemoveMultiLineComments(filename, lines, error):
 
754
  """Removes multiline (c-style) comments from lines."""
 
755
  lineix = 0
 
756
  while lineix < len(lines):
 
757
    lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
 
758
    if lineix_begin >= len(lines):
 
759
      return
 
760
    lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
 
761
    if lineix_end >= len(lines):
 
762
      error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
 
763
            'Could not find end of multi-line comment')
 
764
      return
 
765
    RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
 
766
    lineix = lineix_end + 1
 
767
 
 
768
 
 
769
def CleanseComments(line):
 
770
  """Removes //-comments and single-line C-style /* */ comments.
 
771
 
 
772
  Args:
 
773
    line: A line of C++ source.
 
774
 
 
775
  Returns:
 
776
    The line with single-line comments removed.
 
777
  """
 
778
  commentpos = line.find('//')
 
779
  if commentpos != -1 and not IsCppString(line[:commentpos]):
 
780
    line = line[:commentpos]
 
781
  # get rid of /* ... */
 
782
  return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
 
783
 
 
784
 
 
785
class CleansedLines(object):
 
786
  """Holds 3 copies of all lines with different preprocessing applied to them.
 
787
 
 
788
  1) elided member contains lines without strings and comments,
 
789
  2) lines member contains lines without comments, and
 
790
  3) raw member contains all the lines without processing.
 
791
  All these three members are of <type 'list'>, and of the same length.
 
792
  """
 
793
 
 
794
  def __init__(self, lines):
 
795
    self.elided = []
 
796
    self.lines = []
 
797
    self.raw_lines = lines
 
798
    self.num_lines = len(lines)
 
799
    for linenum in range(len(lines)):
 
800
      self.lines.append(CleanseComments(lines[linenum]))
 
801
      elided = self._CollapseStrings(lines[linenum])
 
802
      self.elided.append(CleanseComments(elided))
 
803
 
 
804
  def NumLines(self):
 
805
    """Returns the number of lines represented."""
 
806
    return self.num_lines
 
807
 
 
808
  @staticmethod
 
809
  def _CollapseStrings(elided):
 
810
    """Collapses strings and chars on a line to simple "" or '' blocks.
 
811
 
 
812
    We nix strings first so we're not fooled by text like '"http://"'
 
813
 
 
814
    Args:
 
815
      elided: The line being processed.
 
816
 
 
817
    Returns:
 
818
      The line with collapsed strings.
 
819
    """
 
820
    if not _RE_PATTERN_INCLUDE.match(elided):
 
821
      # Remove escaped characters first to make quote/single quote collapsing
 
822
      # basic.  Things that look like escaped characters shouldn't occur
 
823
      # outside of strings and chars.
 
824
      elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
 
825
      elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
 
826
      elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
 
827
    return elided
 
828
 
 
829
 
 
830
def CloseExpression(clean_lines, linenum, pos):
 
831
  """If input points to ( or { or [, finds the position that closes it.
 
832
 
 
833
  If lines[linenum][pos] points to a '(' or '{' or '[', finds the the
 
834
  linenum/pos that correspond to the closing of the expression.
 
835
 
 
836
  Args:
 
837
    clean_lines: A CleansedLines instance containing the file.
 
838
    linenum: The number of the line to check.
 
839
    pos: A position on the line.
 
840
 
 
841
  Returns:
 
842
    A tuple (line, linenum, pos) pointer *past* the closing brace, or
 
843
    (line, len(lines), -1) if we never find a close.  Note we ignore
 
844
    strings and comments when matching; and the line we return is the
 
845
    'cleansed' line at linenum.
 
846
  """
 
847
 
 
848
  line = clean_lines.elided[linenum]
 
849
  startchar = line[pos]
 
850
  if startchar not in '({[':
 
851
    return (line, clean_lines.NumLines(), -1)
 
852
  if startchar == '(': endchar = ')'
 
853
  if startchar == '[': endchar = ']'
 
854
  if startchar == '{': endchar = '}'
 
855
 
 
856
  num_open = line.count(startchar) - line.count(endchar)
 
857
  while linenum < clean_lines.NumLines() and num_open > 0:
 
858
    linenum += 1
 
859
    line = clean_lines.elided[linenum]
 
860
    num_open += line.count(startchar) - line.count(endchar)
 
861
  # OK, now find the endchar that actually got us back to even
 
862
  endpos = len(line)
 
863
  while num_open >= 0:
 
864
    endpos = line.rfind(')', 0, endpos)
 
865
    num_open -= 1                 # chopped off another )
 
866
  return (line, linenum, endpos + 1)
 
867
 
 
868
 
 
869
def CheckForCopyright(filename, lines, error):
 
870
  """Logs an error if no Copyright message appears at the top of the file."""
 
871
 
 
872
  # We'll say it should occur by line 10. Don't forget there's a
 
873
  # dummy line at the front.
 
874
  for line in xrange(1, min(len(lines), 11)):
 
875
    if re.search(r'Copyright', lines[line], re.I): break
 
876
  else:                       # means no copyright line was found
 
877
    error(filename, 0, 'legal/copyright', 5,
 
878
          'No copyright message found.  '
 
879
          'You should have a line: "Copyright [year] <Copyright Owner>"')
 
880
 
 
881
 
 
882
def GetHeaderGuardCPPVariable(filename):
 
883
  """Returns the CPP variable that should be used as a header guard.
 
884
 
 
885
  Args:
 
886
    filename: The name of a C++ header file.
 
887
 
 
888
  Returns:
 
889
    The CPP variable that should be used as a header guard in the
 
890
    named file.
 
891
 
 
892
  """
 
893
 
 
894
  fileinfo = FileInfo(filename)
 
895
  return re.sub(r'[-./\s]', '_', fileinfo.RepositoryName()).upper()
 
896
 
 
897
 
 
898
def CheckForHeaderGuard(filename, lines, error):
 
899
  """Checks that the file contains a header guard.
 
900
 
 
901
  Logs an error if no #ifndef header guard is present.  For other
 
902
  headers, checks that the full pathname is used.
 
903
 
 
904
  Args:
 
905
    filename: The name of the C++ header file.
 
906
    lines: An array of strings, each representing a line of the file.
 
907
    error: The function to call with any errors found.
 
908
  """
 
909
 
 
910
  cppvar = GetHeaderGuardCPPVariable(filename)
 
911
 
 
912
  ifndef = None
 
913
  ifndef_linenum = 0
 
914
  define = None
 
915
  endif = None
 
916
  endif_linenum = 0
 
917
  for linenum, line in enumerate(lines):
 
918
    linesplit = line.split()
 
919
    if len(linesplit) >= 2:
 
920
      # find the first occurrence of #ifndef and #define, save arg
 
921
      if not ifndef and linesplit[0] == '#ifndef':
 
922
        # set ifndef to the header guard presented on the #ifndef line.
 
923
        ifndef = linesplit[1]
 
924
        ifndef_linenum = linenum
 
925
      if not define and linesplit[0] == '#define':
 
926
        define = linesplit[1]
 
927
    # find the last occurrence of #endif, save entire line
 
928
    if line.startswith('#endif'):
 
929
      endif = line
 
930
      endif_linenum = linenum
 
931
 
 
932
  if not ifndef or not define or ifndef != define:
 
933
    error(filename, 0, 'build/header_guard', 5,
 
934
          'No #ifndef header guard found, suggested CPP variable is: %s' %
 
935
          cppvar)
 
936
    return
 
937
 
 
938
  # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
 
939
  # for backward compatibility.
 
940
  if ifndef != cppvar:
 
941
    error_level = 0
 
942
    if ifndef != cppvar + '_':
 
943
      error_level = 5
 
944
 
 
945
    error(filename, ifndef_linenum, 'build/header_guard', error_level,
 
946
          '#ifndef header guard has wrong style, please use: %s' % cppvar)
 
947
 
 
948
  if endif != ('#endif /* %s */' % cppvar):
 
949
    error_level = 0
 
950
    if endif != ('#endif /* %s */' % (cppvar + '_')):
 
951
      error_level = 5
 
952
 
 
953
    error(filename, endif_linenum, 'build/header_guard', error_level,
 
954
          '#endif line should be "#endif /* %s */"' % cppvar)
 
955
 
 
956
 
 
957
def CheckForUnicodeReplacementCharacters(filename, lines, error):
 
958
  """Logs an error for each line containing Unicode replacement characters.
 
959
 
 
960
  These indicate that either the file contained invalid UTF-8 (likely)
 
961
  or Unicode replacement characters (which it shouldn't).  Note that
 
962
  it's possible for this to throw off line numbering if the invalid
 
963
  UTF-8 occurred adjacent to a newline.
 
964
 
 
965
  Args:
 
966
    filename: The name of the current file.
 
967
    lines: An array of strings, each representing a line of the file.
 
968
    error: The function to call with any errors found.
 
969
  """
 
970
  for linenum, line in enumerate(lines):
 
971
    if u'\ufffd' in line:
 
972
      error(filename, linenum, 'readability/utf8', 5,
 
973
            'Line contains invalid UTF-8 (or Unicode replacement character).')
 
974
 
 
975
 
 
976
def CheckForNewlineAtEOF(filename, lines, error):
 
977
  """Logs an error if there is no newline char at the end of the file.
 
978
 
 
979
  Args:
 
980
    filename: The name of the current file.
 
981
    lines: An array of strings, each representing a line of the file.
 
982
    error: The function to call with any errors found.
 
983
  """
 
984
 
 
985
  # The array lines() was created by adding two newlines to the
 
986
  # original file (go figure), then splitting on \n.
 
987
  # To verify that the file ends in \n, we just have to make sure the
 
988
  # last-but-two element of lines() exists and is empty.
 
989
  if len(lines) < 3 or lines[-2]:
 
990
    error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
 
991
          'Could not find a newline character at the end of the file.')
 
992
 
 
993
 
 
994
def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
 
995
  """Logs an error if we see /* ... */ or "..." that extend past one line.
 
996
 
 
997
  /* ... */ comments are legit inside macros, for one line.
 
998
  Otherwise, we prefer // comments, so it's ok to warn about the
 
999
  other.  Likewise, it's ok for strings to extend across multiple
 
1000
  lines, as long as a line continuation character (backslash)
 
1001
  terminates each line. Although not currently prohibited by the C++
 
1002
  style guide, it's ugly and unnecessary. We don't do well with either
 
1003
  in this lint program, so we warn about both.
 
1004
 
 
1005
  Args:
 
1006
    filename: The name of the current file.
 
1007
    clean_lines: A CleansedLines instance containing the file.
 
1008
    linenum: The number of the line to check.
 
1009
    error: The function to call with any errors found.
 
1010
  """
 
1011
  line = clean_lines.elided[linenum]
 
1012
 
 
1013
  # Remove all \\ (escaped backslashes) from the line. They are OK, and the
 
1014
  # second (escaped) slash may trigger later \" detection erroneously.
 
1015
  line = line.replace('\\\\', '')
 
1016
 
 
1017
  if line.count('/*') > line.count('*/'):
 
1018
    error(filename, linenum, 'readability/multiline_comment', 5,
 
1019
          'Complex multi-line /*...*/-style comment found. '
 
1020
          'Lint may give bogus warnings.  '
 
1021
          'Consider replacing these with //-style comments, '
 
1022
          'with #if 0...#endif, '
 
1023
          'or with more clearly structured multi-line comments.')
 
1024
 
 
1025
  if (line.count('"') - line.count('\\"')) % 2:
 
1026
    error(filename, linenum, 'readability/multiline_string', 5,
 
1027
          'Multi-line string ("...") found.  This lint script doesn\'t '
 
1028
          'do well with such strings, and may give bogus warnings.  They\'re '
 
1029
          'ugly and unnecessary, and you should use concatenation instead".')
 
1030
 
 
1031
 
 
1032
threading_list = (
 
1033
    ('asctime(', 'asctime_r('),
 
1034
    ('ctime(', 'ctime_r('),
 
1035
    ('getgrgid(', 'getgrgid_r('),
 
1036
    ('getgrnam(', 'getgrnam_r('),
 
1037
    ('getlogin(', 'getlogin_r('),
 
1038
    ('getpwnam(', 'getpwnam_r('),
 
1039
    ('getpwuid(', 'getpwuid_r('),
 
1040
    ('gmtime(', 'gmtime_r('),
 
1041
    ('localtime(', 'localtime_r('),
 
1042
    ('rand(', 'rand_r('),
 
1043
    ('readdir(', 'readdir_r('),
 
1044
    ('strtok(', 'strtok_r('),
 
1045
    ('ttyname(', 'ttyname_r('),
 
1046
    )
 
1047
 
 
1048
 
 
1049
def CheckPosixThreading(filename, clean_lines, linenum, error):
 
1050
  """Checks for calls to thread-unsafe functions.
 
1051
 
 
1052
  Much code has been originally written without consideration of
 
1053
  multi-threading. Also, engineers are relying on their old experience;
 
1054
  they have learned posix before threading extensions were added. These
 
1055
  tests guide the engineers to use thread-safe functions (when using
 
1056
  posix directly).
 
1057
 
 
1058
  Args:
 
1059
    filename: The name of the current file.
 
1060
    clean_lines: A CleansedLines instance containing the file.
 
1061
    linenum: The number of the line to check.
 
1062
    error: The function to call with any errors found.
 
1063
  """
 
1064
  line = clean_lines.elided[linenum]
 
1065
  for single_thread_function, multithread_safe_function in threading_list:
 
1066
    ix = line.find(single_thread_function)
 
1067
    # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
 
1068
    if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
 
1069
                                line[ix - 1] not in ('_', '.', '>'))):
 
1070
      error(filename, linenum, 'runtime/threadsafe_fn', 2,
 
1071
            'Consider using ' + multithread_safe_function +
 
1072
            '...) instead of ' + single_thread_function +
 
1073
            '...) for improved thread safety.')
 
1074
 
 
1075
 
 
1076
# Matches invalid increment: *count++, which moves pointer insead of
 
1077
# incrementing a value.
 
1078
_RE_PATTERN_IVALID_INCREMENT = re.compile(
 
1079
    r'^\s*\*\w+(\+\+|--);')
 
1080
 
 
1081
 
 
1082
def CheckInvalidIncrement(filename, clean_lines, linenum, error):
 
1083
  """Checks for invalud increment *count++.
 
1084
 
 
1085
  For example following function:
 
1086
  void increment_counter(int* count) {
 
1087
    *count++;
 
1088
  }
 
1089
  is invalid, because it effectively does count++, moving pointer, and should
 
1090
  be replaced with ++*count, (*count)++ or *count += 1.
 
1091
 
 
1092
  Args:
 
1093
    filename: The name of the current file.
 
1094
    clean_lines: A CleansedLines instance containing the file.
 
1095
    linenum: The number of the line to check.
 
1096
    error: The function to call with any errors found.
 
1097
  """
 
1098
  line = clean_lines.elided[linenum]
 
1099
  if _RE_PATTERN_IVALID_INCREMENT.match(line):
 
1100
    error(filename, linenum, 'runtime/invalid_increment', 5,
 
1101
          'Changing pointer instead of value (or unused value of operator*).')
 
1102
 
 
1103
 
 
1104
class _ClassInfo(object):
 
1105
  """Stores information about a class."""
 
1106
 
 
1107
  def __init__(self, name, linenum):
 
1108
    self.name = name
 
1109
    self.linenum = linenum
 
1110
    self.seen_open_brace = False
 
1111
    self.is_derived = False
 
1112
    self.virtual_method_linenumber = None
 
1113
    self.has_virtual_destructor = False
 
1114
    self.brace_depth = 0
 
1115
 
 
1116
 
 
1117
class _ClassState(object):
 
1118
  """Holds the current state of the parse relating to class declarations.
 
1119
 
 
1120
  It maintains a stack of _ClassInfos representing the parser's guess
 
1121
  as to the current nesting of class declarations. The innermost class
 
1122
  is at the top (back) of the stack. Typically, the stack will either
 
1123
  be empty or have exactly one entry.
 
1124
  """
 
1125
 
 
1126
  def __init__(self):
 
1127
    self.classinfo_stack = []
 
1128
 
 
1129
  def CheckFinished(self, filename, error):
 
1130
    """Checks that all classes have been completely parsed.
 
1131
 
 
1132
    Call this when all lines in a file have been processed.
 
1133
    Args:
 
1134
      filename: The name of the current file.
 
1135
      error: The function to call with any errors found.
 
1136
    """
 
1137
    if self.classinfo_stack:
 
1138
      # Note: This test can result in false positives if #ifdef constructs
 
1139
      # get in the way of brace matching. See the testBuildClass test in
 
1140
      # cpplint_unittest.py for an example of this.
 
1141
      error(filename, self.classinfo_stack[0].linenum, 'build/class', 5,
 
1142
            'Failed to find complete declaration of class %s' %
 
1143
            self.classinfo_stack[0].name)
 
1144
 
 
1145
 
 
1146
def CheckForNonStandardConstructs(filename, clean_lines, linenum,
 
1147
                                  class_state, error):
 
1148
  """Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
 
1149
 
 
1150
  Complain about several constructs which gcc-2 accepts, but which are
 
1151
  not standard C++.  Warning about these in lint is one way to ease the
 
1152
  transition to new compilers.
 
1153
  - put storage class first (e.g. "static const" instead of "const static").
 
1154
  - "%lld" instead of %qd" in printf-type functions.
 
1155
  - "%1$d" is non-standard in printf-type functions.
 
1156
  - "\%" is an undefined character escape sequence.
 
1157
  - text after #endif is not allowed.
 
1158
  - invalid inner-style forward declaration.
 
1159
  - >? and <? operators, and their >?= and <?= cousins.
 
1160
  - classes with virtual methods need virtual destructors (compiler warning
 
1161
    available, but not turned on yet.)
 
1162
 
 
1163
  Additionally, check for constructor/destructor style violations as it
 
1164
  is very convenient to do so while checking for gcc-2 compliance.
 
1165
 
 
1166
  Args:
 
1167
    filename: The name of the current file.
 
1168
    clean_lines: A CleansedLines instance containing the file.
 
1169
    linenum: The number of the line to check.
 
1170
    class_state: A _ClassState instance which maintains information about
 
1171
                 the current stack of nested class declarations being parsed.
 
1172
    error: A callable to which errors are reported, which takes 4 arguments:
 
1173
           filename, line number, error level, and message
 
1174
  """
 
1175
 
 
1176
  # Remove comments from the line, but leave in strings for now.
 
1177
  line = clean_lines.lines[linenum]
 
1178
 
 
1179
  if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
 
1180
    error(filename, linenum, 'runtime/printf_format', 3,
 
1181
          '%q in format strings is deprecated.  Use %ll instead.')
 
1182
 
 
1183
  if Search(r'printf\s*\(.*".*%\d+\$', line):
 
1184
    error(filename, linenum, 'runtime/printf_format', 2,
 
1185
          '%N$ formats are unconventional.  Try rewriting to avoid them.')
 
1186
 
 
1187
  # Remove escaped backslashes before looking for undefined escapes.
 
1188
  line = line.replace('\\\\', '')
 
1189
 
 
1190
  if Search(r'("|\').*\\(%|\[|\(|{)', line):
 
1191
    error(filename, linenum, 'build/printf_format', 3,
 
1192
          '%, [, (, and { are undefined character escapes.  Unescape them.')
 
1193
 
 
1194
  # For the rest, work with both comments and strings removed.
 
1195
  line = clean_lines.elided[linenum]
 
1196
 
 
1197
  if Search(r'\b(const|volatile|void|char|short|int|long'
 
1198
            r'|float|double|signed|unsigned'
 
1199
            r'|schar|u?int8|u?int16|u?int32|u?int64)'
 
1200
            r'\s+(auto|register|static|extern|typedef)\b',
 
1201
            line):
 
1202
    error(filename, linenum, 'build/storage_class', 5,
 
1203
          'Storage class (static, extern, typedef, etc) should be first.')
 
1204
 
 
1205
  if Match(r'\s*#\s*endif\s*[^/\s]+', line):
 
1206
    error(filename, linenum, 'build/endif_comment', 5,
 
1207
          'Uncommented text after #endif is non-standard.  Use a comment.')
 
1208
 
 
1209
  if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
 
1210
    error(filename, linenum, 'build/forward_decl', 5,
 
1211
          'Inner-style forward declarations are invalid.  Remove this line.')
 
1212
 
 
1213
  if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
 
1214
            line):
 
1215
    error(filename, linenum, 'build/deprecated', 3,
 
1216
          '>? and <? (max and min) operators are non-standard and deprecated.')
 
1217
 
 
1218
  # Track class entry and exit, and attempt to find cases within the
 
1219
  # class declaration that don't meet the C++ style
 
1220
  # guidelines. Tracking is very dependent on the code matching Google
 
1221
  # style guidelines, but it seems to perform well enough in testing
 
1222
  # to be a worthwhile addition to the checks.
 
1223
  classinfo_stack = class_state.classinfo_stack
 
1224
  # Look for a class declaration
 
1225
  class_decl_match = Match(
 
1226
      r'\s*(template\s*<[\w\s<>,:]*>\s*)?(class|struct)\s+(\w+(::\w+)*)', line)
 
1227
  if class_decl_match:
 
1228
    classinfo_stack.append(_ClassInfo(class_decl_match.group(3), linenum))
 
1229
 
 
1230
  # Everything else in this function uses the top of the stack if it's
 
1231
  # not empty.
 
1232
  if not classinfo_stack:
 
1233
    return
 
1234
 
 
1235
  classinfo = classinfo_stack[-1]
 
1236
 
 
1237
  # If the opening brace hasn't been seen look for it and also
 
1238
  # parent class declarations.
 
1239
  if not classinfo.seen_open_brace:
 
1240
    # If the line has a ';' in it, assume it's a forward declaration or
 
1241
    # a single-line class declaration, which we won't process.
 
1242
    if line.find(';') != -1:
 
1243
      classinfo_stack.pop()
 
1244
      return
 
1245
    classinfo.seen_open_brace = (line.find('{') != -1)
 
1246
    # Look for a bare ':'
 
1247
    if Search('(^|[^:]):($|[^:])', line):
 
1248
      classinfo.is_derived = True
 
1249
    if not classinfo.seen_open_brace:
 
1250
      return  # Everything else in this function is for after open brace
 
1251
 
 
1252
  # The class may have been declared with namespace or classname qualifiers.
 
1253
  # The constructor and destructor will not have those qualifiers.
 
1254
  base_classname = classinfo.name.split('::')[-1]
 
1255
 
 
1256
  # Look for single-argument constructors that aren't marked explicit.
 
1257
  # Technically a valid construct, but against style.
 
1258
  args = Match(r'(?<!explicit)\s+%s\s*\(([^,()]+)\)'
 
1259
               % re.escape(base_classname),
 
1260
               line)
 
1261
  if (args and
 
1262
      args.group(1) != 'void' and
 
1263
      not Match(r'(const\s+)?%s\s*&' % re.escape(base_classname),
 
1264
                args.group(1).strip())):
 
1265
    error(filename, linenum, 'runtime/explicit', 5,
 
1266
          'Single-argument constructors should be marked explicit.')
 
1267
 
 
1268
  # Look for methods declared virtual.
 
1269
  if Search(r'\bvirtual\b', line):
 
1270
    classinfo.virtual_method_linenumber = linenum
 
1271
    # Only look for a destructor declaration on the same line. It would
 
1272
    # be extremely unlikely for the destructor declaration to occupy
 
1273
    # more than one line.
 
1274
    if Search(r'~%s\s*\(' % base_classname, line):
 
1275
      classinfo.has_virtual_destructor = True
 
1276
 
 
1277
  # Look for class end.
 
1278
  brace_depth = classinfo.brace_depth
 
1279
  brace_depth = brace_depth + line.count('{') - line.count('}')
 
1280
  if brace_depth <= 0:
 
1281
    classinfo = classinfo_stack.pop()
 
1282
    # Try to detect missing virtual destructor declarations.
 
1283
    # For now, only warn if a non-derived class with virtual methods lacks
 
1284
    # a virtual destructor. This is to make it less likely that people will
 
1285
    # declare derived virtual destructors without declaring the base
 
1286
    # destructor virtual.
 
1287
    if ((classinfo.virtual_method_linenumber is not None) and
 
1288
        (not classinfo.has_virtual_destructor) and
 
1289
        (not classinfo.is_derived)):  # Only warn for base classes
 
1290
      error(filename, classinfo.linenum, 'runtime/virtual', 4,
 
1291
            'The class %s probably needs a virtual destructor due to '
 
1292
            'having virtual method(s), one declared at line %d.'
 
1293
            % (classinfo.name, classinfo.virtual_method_linenumber))
 
1294
  else:
 
1295
    classinfo.brace_depth = brace_depth
 
1296
 
 
1297
 
 
1298
def CheckSpacingForFunctionCall(filename, line, linenum, error):
 
1299
  """Checks for the correctness of various spacing around function calls.
 
1300
 
 
1301
  Args:
 
1302
    filename: The name of the current file.
 
1303
    line: The text of the line to check.
 
1304
    linenum: The number of the line to check.
 
1305
    error: The function to call with any errors found.
 
1306
  """
 
1307
 
 
1308
  # Since function calls often occur inside if/for/while/switch
 
1309
  # expressions - which have their own, more liberal conventions - we
 
1310
  # first see if we should be looking inside such an expression for a
 
1311
  # function call, to which we can apply more strict standards.
 
1312
  fncall = line    # if there's no control flow construct, look at whole line
 
1313
  for pattern in (r'\bif\s*\((.*)\)\s*{',
 
1314
                  r'\bfor\s*\((.*)\)\s*{',
 
1315
                  r'\bwhile\s*\((.*)\)\s*[{;]',
 
1316
                  r'\bswitch\s*\((.*)\)\s*{'):
 
1317
    match = Search(pattern, line)
 
1318
    if match:
 
1319
      fncall = match.group(1)    # look inside the parens for function calls
 
1320
      break
 
1321
 
 
1322
  # Except in if/for/while/switch, there should never be space
 
1323
  # immediately inside parens (eg "f( 3, 4 )").  We make an exception
 
1324
  # for nested parens ( (a+b) + c ).  Likewise, there should never be
 
1325
  # a space before a ( when it's a function argument.  I assume it's a
 
1326
  # function argument when the char before the whitespace is legal in
 
1327
  # a function name (alnum + _) and we're not starting a macro. Also ignore
 
1328
  # pointers and references to arrays and functions coz they're too tricky:
 
1329
  # we use a very simple way to recognize these:
 
1330
  # " (something)(maybe-something)" or
 
1331
  # " (something)(maybe-something," or
 
1332
  # " (something)[something]"
 
1333
  # Note that we assume the contents of [] to be short enough that
 
1334
  # they'll never need to wrap.
 
1335
  if (  # Ignore control structures.
 
1336
      not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and
 
1337
      # Ignore pointers/references to functions.
 
1338
      not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
 
1339
      # Ignore pointers/references to arrays.
 
1340
      not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
 
1341
    if Search(r'\w\s*\(\s(?!\s*\\$)', fncall):      # a ( used for a fn call
 
1342
      error(filename, linenum, 'whitespace/parens', 4,
 
1343
            'Extra space after ( in function call')
 
1344
    elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
 
1345
      error(filename, linenum, 'whitespace/parens', 2,
 
1346
            'Extra space after (')
 
1347
    if (Search(r'\w\s+\(', fncall) and
 
1348
        not Search(r'#\s*define|typedef', fncall)):
 
1349
      error(filename, linenum, 'whitespace/parens', 4,
 
1350
            'Extra space before ( in function call')
 
1351
    # If the ) is followed only by a newline or a { + newline, assume it's
 
1352
    # part of a control statement (if/while/etc), and don't complain
 
1353
    if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
 
1354
      error(filename, linenum, 'whitespace/parens', 2,
 
1355
            'Extra space before )')
 
1356
 
 
1357
 
 
1358
def IsBlankLine(line):
 
1359
  """Returns true if the given line is blank.
 
1360
 
 
1361
  We consider a line to be blank if the line is empty or consists of
 
1362
  only white spaces.
 
1363
 
 
1364
  Args:
 
1365
    line: A line of a string.
 
1366
 
 
1367
  Returns:
 
1368
    True, if the given line is blank.
 
1369
  """
 
1370
  return not line or line.isspace()
 
1371
 
 
1372
 
 
1373
def CheckForFunctionLengths(filename, clean_lines, linenum,
 
1374
                            function_state, error):
 
1375
  """Reports for long function bodies.
 
1376
 
 
1377
  For an overview why this is done, see:
 
1378
  http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
 
1379
 
 
1380
  Uses a simplistic algorithm assuming other style guidelines
 
1381
  (especially spacing) are followed.
 
1382
  Only checks unindented functions, so class members are unchecked.
 
1383
  Trivial bodies are unchecked, so constructors with huge initializer lists
 
1384
  may be missed.
 
1385
  Blank/comment lines are not counted so as to avoid encouraging the removal
 
1386
  of vertical space and commments just to get through a lint check.
 
1387
  NOLINT *on the last line of a function* disables this check.
 
1388
 
 
1389
  Args:
 
1390
    filename: The name of the current file.
 
1391
    clean_lines: A CleansedLines instance containing the file.
 
1392
    linenum: The number of the line to check.
 
1393
    function_state: Current function name and lines in body so far.
 
1394
    error: The function to call with any errors found.
 
1395
  """
 
1396
  lines = clean_lines.lines
 
1397
  line = lines[linenum]
 
1398
  raw = clean_lines.raw_lines
 
1399
  raw_line = raw[linenum]
 
1400
  joined_line = ''
 
1401
 
 
1402
  starting_func = False
 
1403
  regexp = r'(\w(\w|::|\*|\&|\s)*)\('  # decls * & space::name( ...
 
1404
  match_result = Match(regexp, line)
 
1405
  if match_result:
 
1406
    # If the name is all caps and underscores, figure it's a macro and
 
1407
    # ignore it, unless it's TEST or TEST_F.
 
1408
    function_name = match_result.group(1).split()[-1]
 
1409
    if function_name == 'TEST' or function_name == 'TEST_F' or (
 
1410
        not Match(r'[A-Z_]+$', function_name)):
 
1411
      starting_func = True
 
1412
 
 
1413
  if starting_func:
 
1414
    body_found = False
 
1415
    for start_linenum in xrange(linenum, clean_lines.NumLines()):
 
1416
      start_line = lines[start_linenum]
 
1417
      joined_line += ' ' + start_line.lstrip()
 
1418
      if Search(r'(;|})', start_line):  # Declarations and trivial functions
 
1419
        body_found = True
 
1420
        break                              # ... ignore
 
1421
      elif Search(r'{', start_line):
 
1422
        body_found = True
 
1423
        function = Search(r'((\w|:)*)\(', line).group(1)
 
1424
        if Match(r'TEST', function):    # Handle TEST... macros
 
1425
          parameter_regexp = Search(r'(\(.*\))', joined_line)
 
1426
          if parameter_regexp:             # Ignore bad syntax
 
1427
            function += parameter_regexp.group(1)
 
1428
        else:
 
1429
          function += '()'
 
1430
        function_state.Begin(function)
 
1431
        break
 
1432
    if not body_found:
 
1433
      # No body for the function (or evidence of a non-function) was found.
 
1434
      error(filename, linenum, 'readability/fn_size', 5,
 
1435
            'Lint failed to find start of function body.')
 
1436
  elif Match(r'^\}\s*$', line):  # function end
 
1437
    if not Search(r'\bNOLINT\b', raw_line):
 
1438
      function_state.Check(error, filename, linenum)
 
1439
    function_state.End()
 
1440
  elif not Match(r'^\s*$', line):
 
1441
    function_state.Count()  # Count non-blank/non-comment lines.
 
1442
 
 
1443
 
 
1444
_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
 
1445
 
 
1446
 
 
1447
def CheckComment(comment, filename, linenum, error):
 
1448
  """Checks for common mistakes in TODO comments.
 
1449
 
 
1450
  Args:
 
1451
    comment: The text of the comment from the line in question.
 
1452
    filename: The name of the current file.
 
1453
    linenum: The number of the line to check.
 
1454
    error: The function to call with any errors found.
 
1455
  """
 
1456
  match = _RE_PATTERN_TODO.match(comment)
 
1457
  if match:
 
1458
    # One whitespace is correct; zero whitespace is handled elsewhere.
 
1459
    leading_whitespace = match.group(1)
 
1460
    if len(leading_whitespace) > 1:
 
1461
      error(filename, linenum, 'whitespace/todo', 2,
 
1462
            'Too many spaces before TODO')
 
1463
 
 
1464
    username = match.group(2)
 
1465
    if not username:
 
1466
      error(filename, linenum, 'readability/todo', 2,
 
1467
            'Missing username in TODO; it should look like '
 
1468
            '"// TODO(my_username): Stuff."')
 
1469
 
 
1470
    middle_whitespace = match.group(3)
 
1471
    # Comparisons made explicit for correctness -- pylint: disable-msg=C6403
 
1472
    if middle_whitespace != ' ' and middle_whitespace != '':
 
1473
      error(filename, linenum, 'whitespace/todo', 2,
 
1474
            'TODO(my_username) should be followed by a space')
 
1475
 
 
1476
 
 
1477
def CheckSpacing(filename, clean_lines, linenum, error):
 
1478
  """Checks for the correctness of various spacing issues in the code.
 
1479
 
 
1480
  Things we check for: spaces around operators, spaces after
 
1481
  if/for/while/switch, no spaces around parens in function calls, two
 
1482
  spaces between code and comment, don't start a block with a blank
 
1483
  line, don't end a function with a blank line, don't have too many
 
1484
  blank lines in a row.
 
1485
 
 
1486
  Args:
 
1487
    filename: The name of the current file.
 
1488
    clean_lines: A CleansedLines instance containing the file.
 
1489
    linenum: The number of the line to check.
 
1490
    error: The function to call with any errors found.
 
1491
  """
 
1492
 
 
1493
  raw = clean_lines.raw_lines
 
1494
  line = raw[linenum]
 
1495
 
 
1496
  # Before nixing comments, check if the line is blank for no good
 
1497
  # reason.  This includes the first line after a block is opened, and
 
1498
  # blank lines at the end of a function (ie, right before a line like '}'
 
1499
  if IsBlankLine(line):
 
1500
    elided = clean_lines.elided
 
1501
    prev_line = elided[linenum - 1]
 
1502
    prevbrace = prev_line.rfind('{')
 
1503
    # TODO(unknown): Don't complain if line before blank line, and line after,
 
1504
    #                both start with alnums and are indented the same amount.
 
1505
    #                This ignores whitespace at the start of a namespace block
 
1506
    #                because those are not usually indented.
 
1507
    if (prevbrace != -1 and prev_line[prevbrace:].find('}') == -1
 
1508
        and prev_line[:prevbrace].find('namespace') == -1):
 
1509
      # OK, we have a blank line at the start of a code block.  Before we
 
1510
      # complain, we check if it is an exception to the rule: The previous
 
1511
      # non-empty line has the paramters of a function header that are indented
 
1512
      # 4 spaces (because they did not fit in a 80 column line when placed on
 
1513
      # the same line as the function name).  We also check for the case where
 
1514
      # the previous line is indented 6 spaces, which may happen when the
 
1515
      # initializers of a constructor do not fit into a 80 column line.
 
1516
      exception = False
 
1517
      if Match(r' {6}\w', prev_line):  # Initializer list?
 
1518
        # We are looking for the opening column of initializer list, which
 
1519
        # should be indented 4 spaces to cause 6 space indentation afterwards.
 
1520
        search_position = linenum-2
 
1521
        while (search_position >= 0
 
1522
               and Match(r' {6}\w', elided[search_position])):
 
1523
          search_position -= 1
 
1524
        exception = (search_position >= 0
 
1525
                     and elided[search_position][:5] == '    :')
 
1526
      else:
 
1527
        # Search for the function arguments or an initializer list.  We use a
 
1528
        # simple heuristic here: If the line is indented 4 spaces; and we have a
 
1529
        # closing paren, without the opening paren, followed by an opening brace
 
1530
        # or colon (for initializer lists) we assume that it is the last line of
 
1531
        # a function header.  If we have a colon indented 4 spaces, it is an
 
1532
        # initializer list.
 
1533
        exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
 
1534
                           prev_line)
 
1535
                     or Match(r' {4}:', prev_line))
 
1536
 
 
1537
      if not exception:
 
1538
        error(filename, linenum, 'whitespace/blank_line', 2,
 
1539
              'Blank line at the start of a code block.  Is this needed?')
 
1540
    # This doesn't ignore whitespace at the end of a namespace block
 
1541
    # because that is too hard without pairing open/close braces;
 
1542
    # however, a special exception is made for namespace closing
 
1543
    # brackets which have a comment containing "namespace".
 
1544
    #
 
1545
    # Also, ignore blank lines at the end of a block in a long if-else
 
1546
    # chain, like this:
 
1547
    #   if (condition1) {
 
1548
    #     // Something followed by a blank line
 
1549
    #
 
1550
    #   } else if (condition2) {
 
1551
    #     // Something else
 
1552
    #   }
 
1553
    if linenum + 1 < clean_lines.NumLines():
 
1554
      next_line = raw[linenum + 1]
 
1555
      if (next_line
 
1556
          and Match(r'\s*}', next_line)
 
1557
          and next_line.find('namespace') == -1
 
1558
          and next_line.find('} else ') == -1):
 
1559
        error(filename, linenum, 'whitespace/blank_line', 3,
 
1560
              'Blank line at the end of a code block.  Is this needed?')
 
1561
 
 
1562
  # Next, we complain if there's a comment too near the text
 
1563
  commentpos = line.find('//')
 
1564
  if commentpos != -1:
 
1565
    # Check if the // may be in quotes.  If so, ignore it
 
1566
    # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
 
1567
    if (line.count('"', 0, commentpos) -
 
1568
        line.count('\\"', 0, commentpos)) % 2 == 0:   # not in quotes
 
1569
      # Allow one space for new scopes, two spaces otherwise:
 
1570
      if (not Match(r'^\s*{ //', line) and
 
1571
          ((commentpos >= 1 and
 
1572
            line[commentpos-1] not in string.whitespace) or
 
1573
           (commentpos >= 2 and
 
1574
            line[commentpos-2] not in string.whitespace))):
 
1575
        error(filename, linenum, 'whitespace/comments', 2,
 
1576
              'At least two spaces is best between code and comments')
 
1577
      # There should always be a space between the // and the comment
 
1578
      commentend = commentpos + 2
 
1579
      if commentend < len(line) and not line[commentend] == ' ':
 
1580
        # but some lines are exceptions -- e.g. if they're big
 
1581
        # comment delimiters like:
 
1582
        # //----------------------------------------------------------
 
1583
        # or they begin with multiple slashes followed by a space:
 
1584
        # //////// Header comment
 
1585
        match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
 
1586
                 Search(r'^/+ ', line[commentend:]))
 
1587
        if not match:
 
1588
          error(filename, linenum, 'whitespace/comments', 4,
 
1589
                'Should have a space between // and comment')
 
1590
      CheckComment(line[commentpos:], filename, linenum, error)
 
1591
 
 
1592
  line = clean_lines.elided[linenum]  # get rid of comments and strings
 
1593
 
 
1594
  # Don't try to do spacing checks for operator methods
 
1595
  line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
 
1596
 
 
1597
  # = should have no space before and should always have a space after.
 
1598
  if Search(r'[\s.]=[^=]', line):
 
1599
    error(filename, linenum, 'whitespace/operators', 4,
 
1600
          'Space found before =')
 
1601
  if Search(r'=[\w.]', line):
 
1602
    error(filename, linenum, 'whitespace/operators', 4,
 
1603
          'Missing space after =')
 
1604
 
 
1605
  # It's ok not to have spaces around binary operators like + - * /, but if
 
1606
  # there's too little whitespace, we get concerned.  It's hard to tell,
 
1607
  # though, so we punt on this one for now.  TODO.
 
1608
 
 
1609
  # You should always have whitespace around binary operators.
 
1610
  # Alas, we can't test < or > because they're legitimately used sans spaces
 
1611
  # (a->b, vector<int> a).  The only time we can tell is a < with no >, and
 
1612
  # only if it's not template params list spilling into the next line.
 
1613
  match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
 
1614
  if not match:
 
1615
    # Note that while it seems that the '<[^<]*' term in the following
 
1616
    # regexp could be simplified to '<.*', which would indeed match
 
1617
    # the same class of strings, the [^<] means that searching for the
 
1618
    # regexp takes linear rather than quadratic time.
 
1619
    if not Search(r'<[^<]*,\s*$', line):  # template params spill
 
1620
      match = Search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line)
 
1621
  if match:
 
1622
    error(filename, linenum, 'whitespace/operators', 3,
 
1623
          'Missing spaces around %s' % match.group(1))
 
1624
  # We allow no-spaces around << and >> when used like this: 10<<20, but
 
1625
  # not otherwise (particularly, not when used as streams)
 
1626
  match = Search(r'[^0-9\s](<<|>>)[^0-9\s]', line)
 
1627
  if match:
 
1628
    error(filename, linenum, 'whitespace/operators', 3,
 
1629
          'Missing spaces around %s' % match.group(1))
 
1630
 
 
1631
  # There shouldn't be space around unary operators
 
1632
  match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
 
1633
  if match:
 
1634
    error(filename, linenum, 'whitespace/operators', 4,
 
1635
          'Extra space for operator %s' % match.group(1))
 
1636
 
 
1637
  # A pet peeve of mine: no spaces after an if, while, switch, or for
 
1638
  match = Search(r' (if\(|for\(|while\(|switch\()', line)
 
1639
  if match:
 
1640
    error(filename, linenum, 'whitespace/parens', 5,
 
1641
          'Missing space before ( in %s' % match.group(1))
 
1642
 
 
1643
  # For if/for/while/switch, the left and right parens should be
 
1644
  # consistent about how many spaces are inside the parens, and
 
1645
  # there should either be zero or one spaces inside the parens.
 
1646
  # We don't want: "if ( foo)" or "if ( foo   )".
 
1647
  # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
 
1648
  match = Search(r'\b(if|for|while|switch)\s*'
 
1649
                 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
 
1650
                 line)
 
1651
  if match:
 
1652
    if len(match.group(2)) != len(match.group(4)):
 
1653
      if not (match.group(3) == ';' and
 
1654
              len(match.group(2)) == 1 + len(match.group(4)) or
 
1655
              not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
 
1656
        error(filename, linenum, 'whitespace/parens', 5,
 
1657
              'Mismatching spaces inside () in %s' % match.group(1))
 
1658
    if not len(match.group(2)) in [0, 1]:
 
1659
      error(filename, linenum, 'whitespace/parens', 5,
 
1660
            'Should have zero or one spaces inside ( and ) in %s' %
 
1661
            match.group(1))
 
1662
 
 
1663
  # You should always have a space after a comma (either as fn arg or operator)
 
1664
  if Search(r',[^\s]', line):
 
1665
    error(filename, linenum, 'whitespace/comma', 3,
 
1666
          'Missing space after ,')
 
1667
 
 
1668
  # Next we will look for issues with function calls.
 
1669
  CheckSpacingForFunctionCall(filename, line, linenum, error)
 
1670
 
 
1671
  # Except after an opening paren, you should have spaces before your braces.
 
1672
  # And since you should never have braces at the beginning of a line, this is
 
1673
  # an easy test.
 
1674
  if Search(r'[^ (]{', line):
 
1675
    error(filename, linenum, 'whitespace/braces', 5,
 
1676
          'Missing space before {')
 
1677
 
 
1678
  # Make sure '} else {' has spaces.
 
1679
  if Search(r'}else', line):
 
1680
    error(filename, linenum, 'whitespace/braces', 5,
 
1681
          'Missing space before else')
 
1682
 
 
1683
  # You shouldn't have spaces before your brackets, except maybe after
 
1684
  # 'delete []' or 'new char * []'.
 
1685
  if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
 
1686
    error(filename, linenum, 'whitespace/braces', 5,
 
1687
          'Extra space before [')
 
1688
 
 
1689
  # You shouldn't have a space before a semicolon at the end of the line.
 
1690
  # There's a special case for "for" since the style guide allows space before
 
1691
  # the semicolon there.
 
1692
  if Search(r':\s*;\s*$', line):
 
1693
    error(filename, linenum, 'whitespace/semicolon', 5,
 
1694
          'Semicolon defining empty statement. Use { } instead.')
 
1695
  elif Search(r'^\s*;\s*$', line):
 
1696
    error(filename, linenum, 'whitespace/semicolon', 5,
 
1697
          'Line contains only semicolon. If this should be an empty statement, '
 
1698
          'use { } instead.')
 
1699
  elif (Search(r'\s+;\s*$', line) and
 
1700
        not Search(r'\bfor\b', line)):
 
1701
    error(filename, linenum, 'whitespace/semicolon', 5,
 
1702
          'Extra space before last semicolon. If this should be an empty '
 
1703
          'statement, use { } instead.')
 
1704
 
 
1705
 
 
1706
def GetPreviousNonBlankLine(clean_lines, linenum):
 
1707
  """Return the most recent non-blank line and its line number.
 
1708
 
 
1709
  Args:
 
1710
    clean_lines: A CleansedLines instance containing the file contents.
 
1711
    linenum: The number of the line to check.
 
1712
 
 
1713
  Returns:
 
1714
    A tuple with two elements.  The first element is the contents of the last
 
1715
    non-blank line before the current line, or the empty string if this is the
 
1716
    first non-blank line.  The second is the line number of that line, or -1
 
1717
    if this is the first non-blank line.
 
1718
  """
 
1719
 
 
1720
  prevlinenum = linenum - 1
 
1721
  while prevlinenum >= 0:
 
1722
    prevline = clean_lines.elided[prevlinenum]
 
1723
    if not IsBlankLine(prevline):     # if not a blank line...
 
1724
      return (prevline, prevlinenum)
 
1725
    prevlinenum -= 1
 
1726
  return ('', -1)
 
1727
 
 
1728
 
 
1729
def CheckBraces(filename, clean_lines, linenum, error):
 
1730
  """Looks for misplaced braces (e.g. at the end of line).
 
1731
 
 
1732
  Args:
 
1733
    filename: The name of the current file.
 
1734
    clean_lines: A CleansedLines instance containing the file.
 
1735
    linenum: The number of the line to check.
 
1736
    error: The function to call with any errors found.
 
1737
  """
 
1738
 
 
1739
  line = clean_lines.elided[linenum]        # get rid of comments and strings
 
1740
 
 
1741
  if Match(r'\s*{\s*$', line):
 
1742
    # We allow an open brace to start a line in the case where someone
 
1743
    # is using braces in a block to explicitly create a new scope,
 
1744
    # which is commonly used to control the lifetime of
 
1745
    # stack-allocated variables.  We don't detect this perfectly: we
 
1746
    # just don't complain if the last non-whitespace character on the
 
1747
    # previous non-blank line is ';', ':', '{', or '}'.
 
1748
    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
 
1749
    if not Search(r'[;:}{]\s*$', prevline):
 
1750
      error(filename, linenum, 'whitespace/braces', 4,
 
1751
            '{ should almost always be at the end of the previous line')
 
1752
 
 
1753
  # An else clause should be on the same line as the preceding closing brace.
 
1754
  if Match(r'\s*else\s*', line):
 
1755
    prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
 
1756
    if Match(r'\s*}\s*$', prevline):
 
1757
      error(filename, linenum, 'whitespace/newline', 4,
 
1758
            'An else should appear on the same line as the preceding }')
 
1759
 
 
1760
  # If braces come on one side of an else, they should be on both.
 
1761
  # However, we have to worry about "else if" that spans multiple lines!
 
1762
  if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
 
1763
    if Search(r'}\s*else if([^{]*)$', line):       # could be multi-line if
 
1764
      # find the ( after the if
 
1765
      pos = line.find('else if')
 
1766
      pos = line.find('(', pos)
 
1767
      if pos > 0:
 
1768
        (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
 
1769
        if endline[endpos:].find('{') == -1:    # must be brace after if
 
1770
          error(filename, linenum, 'readability/braces', 5,
 
1771
                'If an else has a brace on one side, it should have it on both')
 
1772
    else:            # common case: else not followed by a multi-line if
 
1773
      error(filename, linenum, 'readability/braces', 5,
 
1774
            'If an else has a brace on one side, it should have it on both')
 
1775
 
 
1776
  # Likewise, an else should never have the else clause on the same line
 
1777
  if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
 
1778
    error(filename, linenum, 'whitespace/newline', 4,
 
1779
          'Else clause should never be on same line as else (use 2 lines)')
 
1780
 
 
1781
  # In the same way, a do/while should never be on one line
 
1782
  if Match(r'\s*do [^\s{]', line):
 
1783
    error(filename, linenum, 'whitespace/newline', 4,
 
1784
          'do/while clauses should not be on a single line')
 
1785
 
 
1786
  # Braces shouldn't be followed by a ; unless they're defining a struct
 
1787
  # or initializing an array.
 
1788
  # We can't tell in general, but we can for some common cases.
 
1789
  prevlinenum = linenum
 
1790
  while True:
 
1791
    (prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum)
 
1792
    if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'):
 
1793
      line = prevline + line
 
1794
    else:
 
1795
      break
 
1796
  if (Search(r'{.*}\s*;', line) and
 
1797
      line.count('{') == line.count('}') and
 
1798
      not Search(r'struct|class|enum|\s*=\s*{', line)):
 
1799
    error(filename, linenum, 'readability/braces', 4,
 
1800
          "You don't need a ; after a }")
 
1801
 
 
1802
 
 
1803
def ReplaceableCheck(operator, macro, line):
 
1804
  """Determine whether a basic CHECK can be replaced with a more specific one.
 
1805
 
 
1806
  For example suggest using CHECK_EQ instead of CHECK(a == b) and
 
1807
  similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
 
1808
 
 
1809
  Args:
 
1810
    operator: The C++ operator used in the CHECK.
 
1811
    macro: The CHECK or EXPECT macro being called.
 
1812
    line: The current source line.
 
1813
 
 
1814
  Returns:
 
1815
    True if the CHECK can be replaced with a more specific one.
 
1816
  """
 
1817
 
 
1818
  # This matches decimal and hex integers, strings, and chars (in that order).
 
1819
  match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
 
1820
 
 
1821
  # Expression to match two sides of the operator with something that
 
1822
  # looks like a literal, since CHECK(x == iterator) won't compile.
 
1823
  # This means we can't catch all the cases where a more specific
 
1824
  # CHECK is possible, but it's less annoying than dealing with
 
1825
  # extraneous warnings.
 
1826
  match_this = (r'\s*' + macro + r'\((\s*' +
 
1827
                match_constant + r'\s*' + operator + r'[^<>].*|'
 
1828
                r'.*[^<>]' + operator + r'\s*' + match_constant +
 
1829
                r'\s*\))')
 
1830
 
 
1831
  # Don't complain about CHECK(x == NULL) or similar because
 
1832
  # CHECK_EQ(x, NULL) won't compile (requires a cast).
 
1833
  # Also, don't complain about more complex boolean expressions
 
1834
  # involving && or || such as CHECK(a == b || c == d).
 
1835
  return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line)
 
1836
 
 
1837
 
 
1838
def CheckCheck(filename, clean_lines, linenum, error):
 
1839
  """Checks the use of CHECK and EXPECT macros.
 
1840
 
 
1841
  Args:
 
1842
    filename: The name of the current file.
 
1843
    clean_lines: A CleansedLines instance containing the file.
 
1844
    linenum: The number of the line to check.
 
1845
    error: The function to call with any errors found.
 
1846
  """
 
1847
 
 
1848
  # Decide the set of replacement macros that should be suggested
 
1849
  raw_lines = clean_lines.raw_lines
 
1850
  current_macro = ''
 
1851
  for macro in _CHECK_MACROS:
 
1852
    if raw_lines[linenum].find(macro) >= 0:
 
1853
      current_macro = macro
 
1854
      break
 
1855
  if not current_macro:
 
1856
    # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
 
1857
    return
 
1858
 
 
1859
  line = clean_lines.elided[linenum]        # get rid of comments and strings
 
1860
 
 
1861
  # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.
 
1862
  for operator in ['==', '!=', '>=', '>', '<=', '<']:
 
1863
    if ReplaceableCheck(operator, current_macro, line):
 
1864
      error(filename, linenum, 'readability/check', 2,
 
1865
            'Consider using %s instead of %s(a %s b)' % (
 
1866
                _CHECK_REPLACEMENT[current_macro][operator],
 
1867
                current_macro, operator))
 
1868
      break
 
1869
 
 
1870
 
 
1871
def GetLineWidth(line):
 
1872
  """Determines the width of the line in column positions.
 
1873
 
 
1874
  Args:
 
1875
    line: A string, which may be a Unicode string.
 
1876
 
 
1877
  Returns:
 
1878
    The width of the line in column positions, accounting for Unicode
 
1879
    combining characters and wide characters.
 
1880
  """
 
1881
  if isinstance(line, unicode):
 
1882
    width = 0
 
1883
    for c in unicodedata.normalize('NFC', line):
 
1884
      if unicodedata.east_asian_width(c) in ('W', 'F'):
 
1885
        width += 2
 
1886
      elif not unicodedata.combining(c):
 
1887
        width += 1
 
1888
    return width
 
1889
  else:
 
1890
    return len(line)
 
1891
 
 
1892
 
 
1893
def CheckStyle(filename, clean_lines, linenum, file_extension, error):
 
1894
  """Checks rules from the 'C++ style rules' section of cppguide.html.
 
1895
 
 
1896
  Most of these rules are hard to test (naming, comment style), but we
 
1897
  do what we can.  In particular we check for 2-space indents, line lengths,
 
1898
  tab usage, spaces inside code, etc.
 
1899
 
 
1900
  Args:
 
1901
    filename: The name of the current file.
 
1902
    clean_lines: A CleansedLines instance containing the file.
 
1903
    linenum: The number of the line to check.
 
1904
    file_extension: The extension (without the dot) of the filename.
 
1905
    error: The function to call with any errors found.
 
1906
  """
 
1907
 
 
1908
  raw_lines = clean_lines.raw_lines
 
1909
  line = raw_lines[linenum]
 
1910
 
 
1911
  if line.find('\t') != -1:
 
1912
    error(filename, linenum, 'whitespace/tab', 1,
 
1913
          'Tab found; better to use spaces')
 
1914
 
 
1915
  # One or three blank spaces at the beginning of the line is weird; it's
 
1916
  # hard to reconcile that with 2-space indents.
 
1917
  # NOTE: here are the conditions rob pike used for his tests.  Mine aren't
 
1918
  # as sophisticated, but it may be worth becoming so:  RLENGTH==initial_spaces
 
1919
  # if(RLENGTH > 20) complain = 0;
 
1920
  # if(match($0, " +(error|private|public|protected):")) complain = 0;
 
1921
  # if(match(prev, "&& *$")) complain = 0;
 
1922
  # if(match(prev, "\\|\\| *$")) complain = 0;
 
1923
  # if(match(prev, "[\",=><] *$")) complain = 0;
 
1924
  # if(match($0, " <<")) complain = 0;
 
1925
  # if(match(prev, " +for \\(")) complain = 0;
 
1926
  # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
 
1927
  initial_spaces = 0
 
1928
  cleansed_line = clean_lines.elided[linenum]
 
1929
  while initial_spaces < len(line) and line[initial_spaces] == ' ':
 
1930
    initial_spaces += 1
 
1931
  if line and line[-1].isspace():
 
1932
    error(filename, linenum, 'whitespace/end_of_line', 4,
 
1933
          'Line ends in whitespace.  Consider deleting these extra spaces.')
 
1934
  # There are certain situations we allow one space, notably for labels
 
1935
  elif ((initial_spaces == 1 or initial_spaces == 3) and
 
1936
        not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
 
1937
    error(filename, linenum, 'whitespace/indent', 3,
 
1938
          'Weird number of spaces at line-start.  '
 
1939
          'Are you using a 2-space indent?')
 
1940
  # Labels should always be indented at least one space.
 
1941
  elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
 
1942
                                                          line):
 
1943
    error(filename, linenum, 'whitespace/labels', 4,
 
1944
          'Labels should always be indented at least one space.  '
 
1945
          'If this is a member-initializer list in a constructor, '
 
1946
          'the colon should be on the line after the definition header.')
 
1947
 
 
1948
  # Check if the line is a header guard.
 
1949
  is_header_guard = False
 
1950
  if file_extension == 'h':
 
1951
    cppvar = GetHeaderGuardCPPVariable(filename)
 
1952
    if (line.startswith('#ifndef %s' % cppvar) or
 
1953
        line.startswith('#define %s' % cppvar) or
 
1954
        line.startswith('#endif  // %s' % cppvar)):
 
1955
      is_header_guard = True
 
1956
  # #include lines and header guards can be long, since there's no clean way to
 
1957
  # split them.
 
1958
  #
 
1959
  # URLs can be long too.  It's possible to split these, but it makes them
 
1960
  # harder to cut&paste.
 
1961
  if (not line.startswith('#include') and not is_header_guard and
 
1962
      not Match(r'^\s*//.*http(s?)://\S*$', line)):
 
1963
    line_width = GetLineWidth(line)
 
1964
    if line_width > 100:
 
1965
      error(filename, linenum, 'whitespace/line_length', 4,
 
1966
            'Lines should very rarely be longer than 100 characters')
 
1967
    elif line_width > 80:
 
1968
      error(filename, linenum, 'whitespace/line_length', 2,
 
1969
            'Lines should be <= 80 characters long')
 
1970
 
 
1971
  if (cleansed_line.count(';') > 1 and
 
1972
      # for loops are allowed two ;'s (and may run over two lines).
 
1973
      cleansed_line.find('for') == -1 and
 
1974
      (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
 
1975
       GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
 
1976
      # It's ok to have many commands in a switch case that fits in 1 line
 
1977
      not ((cleansed_line.find('case ') != -1 or
 
1978
            cleansed_line.find('default:') != -1) and
 
1979
           cleansed_line.find('break;') != -1)):
 
1980
    error(filename, linenum, 'whitespace/newline', 4,
 
1981
          'More than one command on the same line')
 
1982
 
 
1983
  # Some more style checks
 
1984
  CheckBraces(filename, clean_lines, linenum, error)
 
1985
  CheckSpacing(filename, clean_lines, linenum, error)
 
1986
  CheckCheck(filename, clean_lines, linenum, error)
 
1987
 
 
1988
 
 
1989
_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
 
1990
_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
 
1991
# Matches the first component of a filename delimited by -s and _s. That is:
 
1992
#  _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
 
1993
#  _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
 
1994
#  _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
 
1995
#  _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
 
1996
_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
 
1997
 
 
1998
 
 
1999
def _DropCommonSuffixes(filename):
 
2000
  """Drops common suffixes like _test.cc or -inl.h from filename.
 
2001
 
 
2002
  For example:
 
2003
    >>> _DropCommonSuffixes('foo/foo-inl.h')
 
2004
    'foo/foo'
 
2005
    >>> _DropCommonSuffixes('foo/bar/foo.cc')
 
2006
    'foo/bar/foo'
 
2007
    >>> _DropCommonSuffixes('foo/foo_internal.h')
 
2008
    'foo/foo'
 
2009
    >>> _DropCommonSuffixes('foo/foo_unusualinternal.h')
 
2010
    'foo/foo_unusualinternal'
 
2011
 
 
2012
  Args:
 
2013
    filename: The input filename.
 
2014
 
 
2015
  Returns:
 
2016
    The filename with the common suffix removed.
 
2017
  """
 
2018
  for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
 
2019
                 'inl.h', 'impl.h', 'internal.h'):
 
2020
    if (filename.endswith(suffix) and len(filename) > len(suffix) and
 
2021
        filename[-len(suffix) - 1] in ('-', '_')):
 
2022
      return filename[:-len(suffix) - 1]
 
2023
  return os.path.splitext(filename)[0]
 
2024
 
 
2025
 
 
2026
def _IsTestFilename(filename):
 
2027
  """Determines if the given filename has a suffix that identifies it as a test.
 
2028
 
 
2029
  Args:
 
2030
    filename: The input filename.
 
2031
 
 
2032
  Returns:
 
2033
    True if 'filename' looks like a test, False otherwise.
 
2034
  """
 
2035
  if (filename.endswith('_test.cc') or
 
2036
      filename.endswith('_unittest.cc') or
 
2037
      filename.endswith('_regtest.cc')):
 
2038
    return True
 
2039
  else:
 
2040
    return False
 
2041
 
 
2042
 
 
2043
def _ClassifyInclude(fileinfo, include, is_system):
 
2044
  """Figures out what kind of header 'include' is.
 
2045
 
 
2046
  Args:
 
2047
    fileinfo: The current file cpplint is running over. A FileInfo instance.
 
2048
    include: The path to a #included file.
 
2049
    is_system: True if the #include used <> rather than "".
 
2050
 
 
2051
  Returns:
 
2052
    One of the _XXX_HEADER constants.
 
2053
 
 
2054
  For example:
 
2055
    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
 
2056
    _C_SYS_HEADER
 
2057
    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
 
2058
    _CPP_SYS_HEADER
 
2059
    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
 
2060
    _LIKELY_MY_HEADER
 
2061
    >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
 
2062
    ...                  'bar/foo_other_ext.h', False)
 
2063
    _POSSIBLE_MY_HEADER
 
2064
    >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
 
2065
    _OTHER_HEADER
 
2066
  """
 
2067
  # This is a list of all standard c++ header files, except
 
2068
  # those already checked for above.
 
2069
  is_stl_h = include in _STL_HEADERS
 
2070
  is_cpp_h = is_stl_h or include in _CPP_HEADERS
 
2071
 
 
2072
  if is_system:
 
2073
    if is_cpp_h:
 
2074
      return _CPP_SYS_HEADER
 
2075
    else:
 
2076
      return _C_SYS_HEADER
 
2077
 
 
2078
  # If the target file and the include we're checking share a
 
2079
  # basename when we drop common extensions, and the include
 
2080
  # lives in . , then it's likely to be owned by the target file.
 
2081
  target_dir, target_base = (
 
2082
      os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
 
2083
  include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
 
2084
  if target_base == include_base and (
 
2085
      include_dir == target_dir or
 
2086
      include_dir == os.path.normpath(target_dir + '/../public')):
 
2087
    return _LIKELY_MY_HEADER
 
2088
 
 
2089
  # If the target and include share some initial basename
 
2090
  # component, it's possible the target is implementing the
 
2091
  # include, so it's allowed to be first, but we'll never
 
2092
  # complain if it's not there.
 
2093
  target_first_component = _RE_FIRST_COMPONENT.match(target_base)
 
2094
  include_first_component = _RE_FIRST_COMPONENT.match(include_base)
 
2095
  if (target_first_component and include_first_component and
 
2096
      target_first_component.group(0) ==
 
2097
      include_first_component.group(0)):
 
2098
    return _POSSIBLE_MY_HEADER
 
2099
 
 
2100
  return _OTHER_HEADER
 
2101
 
 
2102
 
 
2103
 
 
2104
def CheckGlobalInclude(filename, clean_lines, linenum, include_state, error):
 
2105
  """Check rules that are applicable to #include lines.
 
2106
 
 
2107
  config.h should NEVER be included in headers
 
2108
  unless those headers end in _priv and therefore are private headers.
 
2109
 
 
2110
  Args:
 
2111
    filename: The name of the current file.
 
2112
    clean_lines: A CleansedLines instance containing the file.
 
2113
    linenum: The number of the line to check.
 
2114
    include_state: An _IncludeState instance in which the headers are inserted.
 
2115
    error: The function to call with any errors found.
 
2116
  """
 
2117
  if filename.endswith("config.h") or filename.endswith("_priv.h") or not filename.endswith(".h"):
 
2118
    return
 
2119
 
 
2120
  fileinfo = FileInfo(filename)
 
2121
 
 
2122
  line = clean_lines.lines[linenum]
 
2123
 
 
2124
  match = _RE_PATTERN_INCLUDE.search(line)
 
2125
  if match:
 
2126
    include = match.group(2)
 
2127
    if Match(r'(config|global|server_includes|_priv)\.h$', include):
 
2128
      error(filename, linenum, 'build/include_config', 4,
 
2129
            'Do not include config.h or files that include config.h in .h files')
 
2130
      
 
2131
def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
 
2132
  """Check rules that are applicable to #include lines.
 
2133
 
 
2134
  Strings on #include lines are NOT removed from elided line, to make
 
2135
  certain tasks easier. However, to prevent false positives, checks
 
2136
  applicable to #include lines in CheckLanguage must be put here.
 
2137
 
 
2138
  Args:
 
2139
    filename: The name of the current file.
 
2140
    clean_lines: A CleansedLines instance containing the file.
 
2141
    linenum: The number of the line to check.
 
2142
    include_state: An _IncludeState instance in which the headers are inserted.
 
2143
    error: The function to call with any errors found.
 
2144
  """
 
2145
  fileinfo = FileInfo(filename)
 
2146
 
 
2147
  line = clean_lines.lines[linenum]
 
2148
 
 
2149
  # "include" should use the new style "foo/bar.h" instead of just "bar.h"
 
2150
  if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
 
2151
    error(filename, linenum, 'build/include', 4,
 
2152
          'Include the directory when naming .h files')
 
2153
 
 
2154
  # we shouldn't include a file more than once. actually, there are a
 
2155
  # handful of instances where doing so is okay, but in general it's
 
2156
  # not.
 
2157
  match = _RE_PATTERN_INCLUDE.search(line)
 
2158
  if match:
 
2159
    include = match.group(2)
 
2160
    is_system = (match.group(1) == '<')
 
2161
    if include in include_state:
 
2162
      error(filename, linenum, 'build/include', 4,
 
2163
            '"%s" already included at %s:%s' %
 
2164
            (include, filename, include_state[include]))
 
2165
    else:
 
2166
      include_state[include] = linenum
 
2167
 
 
2168
      # We want to ensure that headers appear in the right order:
 
2169
      # 1) for foo.cc, foo.h  (preferred location)
 
2170
      # 2) c system files
 
2171
      # 3) cpp system files
 
2172
      # 4) for foo.cc, foo.h  (deprecated location)
 
2173
      # 5) other google headers
 
2174
      #
 
2175
      # We classify each include statement as one of those 5 types
 
2176
      # using a number of techniques. The include_state object keeps
 
2177
      # track of the highest type seen, and complains if we see a
 
2178
      # lower type after that.
 
2179
      error_message = include_state.CheckNextIncludeOrder(
 
2180
          _ClassifyInclude(fileinfo, include, is_system))
 
2181
      if error_message:
 
2182
        error(filename, linenum, 'build/include_order', 4,
 
2183
              '%s. Should be: %s.h, c system, c++ system, other.' %
 
2184
              (error_message, fileinfo.BaseName()))
 
2185
 
 
2186
  # Look for any of the stream classes that are part of standard C++.
 
2187
  match = _RE_PATTERN_INCLUDE.match(line)
 
2188
  if match:
 
2189
    include = match.group(2)
 
2190
    if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
 
2191
      # Many unit tests use cout, so we exempt them.
 
2192
      if not _IsTestFilename(filename):
 
2193
        error(filename, linenum, 'readability/streams', 3,
 
2194
              'Streams are highly discouraged.')
 
2195
 
 
2196
def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state,
 
2197
                  error):
 
2198
  """Checks rules from the 'C++ language rules' section of cppguide.html.
 
2199
 
 
2200
  Some of these rules are hard to test (function overloading, using
 
2201
  uint32 inappropriately), but we do the best we can.
 
2202
 
 
2203
  Args:
 
2204
    filename: The name of the current file.
 
2205
    clean_lines: A CleansedLines instance containing the file.
 
2206
    linenum: The number of the line to check.
 
2207
    file_extension: The extension (without the dot) of the filename.
 
2208
    include_state: An _IncludeState instance in which the headers are inserted.
 
2209
    error: The function to call with any errors found.
 
2210
  """
 
2211
  # If the line is empty or consists of entirely a comment, no need to
 
2212
  # check it.
 
2213
  line = clean_lines.elided[linenum]
 
2214
  if not line:
 
2215
    return
 
2216
 
 
2217
  match = _RE_PATTERN_INCLUDE.search(line)
 
2218
  if match:
 
2219
    CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
 
2220
    CheckGlobalInclude(filename, clean_lines, linenum, include_state, error)
 
2221
    return
 
2222
 
 
2223
  # Create an extended_line, which is the concatenation of the current and
 
2224
  # next lines, for more effective checking of code that may span more than one
 
2225
  # line.
 
2226
  if linenum + 1 < clean_lines.NumLines():
 
2227
    extended_line = line + clean_lines.elided[linenum + 1]
 
2228
  else:
 
2229
    extended_line = line
 
2230
 
 
2231
  # Make Windows paths like Unix.
 
2232
  fullname = os.path.abspath(filename).replace('\\', '/')
 
2233
 
 
2234
  # TODO(unknown): figure out if they're using default arguments in fn proto.
 
2235
 
 
2236
  # Check to see if they're using an conversion function cast.
 
2237
  # I just try to capture the most common basic types, though there are more.
 
2238
  # Parameterless conversion functions, such as bool(), are allowed as they are
 
2239
  # probably a member operator declaration or default constructor.
 
2240
  match = Search(
 
2241
      r'\b(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
 
2242
  if match:
 
2243
    # gMock methods are defined using some variant of MOCK_METHODx(name, type)
 
2244
    # where type may be float(), int(string), etc.  Without context they are
 
2245
    # virtually indistinguishable from int(x) casts.
 
2246
    if not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line):
 
2247
      error(filename, linenum, 'readability/casting', 4,
 
2248
            'Using deprecated casting style.  '
 
2249
            'Use static_cast<%s>(...) instead' %
 
2250
            match.group(1))
 
2251
 
 
2252
  CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
 
2253
                  'static_cast',
 
2254
                  r'\((int|float|double|bool|char|u?int(16|32|64))\)',
 
2255
                  error)
 
2256
  # This doesn't catch all cases.  Consider (const char * const)"hello".
 
2257
  CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
 
2258
                  'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
 
2259
 
 
2260
  # In addition, we look for people taking the address of a cast.  This
 
2261
  # is dangerous -- casts can assign to temporaries, so the pointer doesn't
 
2262
  # point where you think.
 
2263
  if Search(
 
2264
      r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
 
2265
    error(filename, linenum, 'runtime/casting', 4,
 
2266
          ('Are you taking an address of a cast?  '
 
2267
           'This is dangerous: could be a temp var.  '
 
2268
           'Take the address before doing the cast, rather than after'))
 
2269
 
 
2270
  # Check for people declaring static/global STL strings at the top level.
 
2271
  # This is dangerous because the C++ language does not guarantee that
 
2272
  # globals with constructors are initialized before the first access.
 
2273
  match = Match(
 
2274
      r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
 
2275
      line)
 
2276
  # Make sure it's not a function.
 
2277
  # Function template specialization looks like: "string foo<Type>(...".
 
2278
  # Class template definitions look like: "string Foo<Type>::Method(...".
 
2279
  if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)',
 
2280
                         match.group(3)):
 
2281
    error(filename, linenum, 'runtime/string', 4,
 
2282
          'For a static/global string constant, use a C style string instead: '
 
2283
          '"%schar %s[]".' %
 
2284
          (match.group(1), match.group(2)))
 
2285
 
 
2286
  # Check that we're not using RTTI outside of testing code.
 
2287
  if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename):
 
2288
    error(filename, linenum, 'runtime/rtti', 5,
 
2289
          'Do not use dynamic_cast<>.  If you need to cast within a class '
 
2290
          "hierarchy, use static_cast<> to upcast.  Google doesn't support "
 
2291
          'RTTI.')
 
2292
 
 
2293
  if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
 
2294
    error(filename, linenum, 'runtime/init', 4,
 
2295
          'You seem to be initializing a member variable with itself.')
 
2296
 
 
2297
  if file_extension == 'h':
 
2298
    # TODO(unknown): check that 1-arg constructors are explicit.
 
2299
    #                How to tell it's a constructor?
 
2300
    #                (handled in CheckForNonStandardConstructs for now)
 
2301
    # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
 
2302
    #                (level 1 error)
 
2303
    pass
 
2304
 
 
2305
  # Check if people are using the verboten C basic types.  The only exception
 
2306
  # we regularly allow is "unsigned short port" for port.
 
2307
  if Search(r'\bshort port\b', line):
 
2308
    if not Search(r'\bunsigned short port\b', line):
 
2309
      error(filename, linenum, 'runtime/int', 4,
 
2310
            'Use "unsigned short" for ports, not "short"')
 
2311
  else:
 
2312
    match = Search(r'\b(short|long(?! +double)|long long)\b', line)
 
2313
    if match:
 
2314
      error(filename, linenum, 'runtime/int', 4,
 
2315
            'Use int16/int64/etc, rather than the C type %s' % match.group(1))
 
2316
 
 
2317
  # When snprintf is used, the second argument shouldn't be a literal.
 
2318
  match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
 
2319
  if match:
 
2320
    error(filename, linenum, 'runtime/printf', 3,
 
2321
          'If you can, use sizeof(%s) instead of %s as the 2nd arg '
 
2322
          'to snprintf.' % (match.group(1), match.group(2)))
 
2323
 
 
2324
  # Check if some verboten C functions are being used.
 
2325
  if Search(r'\bsprintf\b', line):
 
2326
    error(filename, linenum, 'runtime/printf', 5,
 
2327
          'Never use sprintf.  Use snprintf instead.')
 
2328
  match = Search(r'\b(strcpy|strcat)\b', line)
 
2329
  if match:
 
2330
    error(filename, linenum, 'runtime/printf', 4,
 
2331
          'Almost always, snprintf is better than %s' % match.group(1))
 
2332
 
 
2333
  if Search(r'\bsscanf\b', line):
 
2334
    error(filename, linenum, 'runtime/printf', 1,
 
2335
          'sscanf can be ok, but is slow and can overflow buffers.')
 
2336
 
 
2337
  # Check for suspicious usage of "if" like
 
2338
  # } if (a == b) {
 
2339
  if Search(r'\}\s*if\s*\(', line):
 
2340
    error(filename, linenum, 'readability/braces', 4,
 
2341
          'Did you mean "else if"? If not, start a new line for "if".')
 
2342
 
 
2343
  # Check for potential format string bugs like printf(foo).
 
2344
  # We constrain the pattern not to pick things like DocidForPrintf(foo).
 
2345
  # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
 
2346
  match = re.search(r'\b((?:string)?printf)\s*\(([\w.\->()]+)\)', line, re.I)
 
2347
  if match:
 
2348
    error(filename, linenum, 'runtime/printf', 4,
 
2349
          'Potential format string bug. Do %s("%%s", %s) instead.'
 
2350
          % (match.group(1), match.group(2)))
 
2351
 
 
2352
  # Check for potential memset bugs like memset(buf, sizeof(buf), 0).
 
2353
  match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
 
2354
  if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
 
2355
    error(filename, linenum, 'runtime/memset', 4,
 
2356
          'Did you mean "memset(%s, 0, %s)"?'
 
2357
          % (match.group(1), match.group(2)))
 
2358
 
 
2359
  if Search(r'\busing namespace\b', line) and filename.endswith(".h"):
 
2360
    error(filename, linenum, 'build/namespaces', 5,
 
2361
          'Do not use namespace using-directives in headers.  ')
 
2362
 
 
2363
  # Detect variable-length arrays.
 
2364
  match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
 
2365
  if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
 
2366
      match.group(3).find(']') == -1):
 
2367
    # Split the size using space and arithmetic operators as delimiters.
 
2368
    # If any of the resulting tokens are not compile time constants then
 
2369
    # report the error.
 
2370
    tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
 
2371
    is_const = True
 
2372
    skip_next = False
 
2373
    for tok in tokens:
 
2374
      if skip_next:
 
2375
        skip_next = False
 
2376
        continue
 
2377
 
 
2378
      if Search(r'sizeof\(.+\)', tok): continue
 
2379
      if Search(r'arraysize\(\w+\)', tok): continue
 
2380
 
 
2381
      tok = tok.lstrip('(')
 
2382
      tok = tok.rstrip(')')
 
2383
      if not tok: continue
 
2384
      if Match(r'\d+', tok): continue
 
2385
      if Match(r'0[xX][0-9a-fA-F]+', tok): continue
 
2386
      if Match(r'k[A-Z0-9]\w*', tok): continue
 
2387
      if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
 
2388
      if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
 
2389
      # A catch all for tricky sizeof cases, including 'sizeof expression',
 
2390
      # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
 
2391
      # requires skipping the next token becasue we split on ' ' and '*'.
 
2392
      if tok.startswith('sizeof'):
 
2393
        skip_next = True
 
2394
        continue
 
2395
      is_const = False
 
2396
      break
 
2397
    if not is_const:
 
2398
      error(filename, linenum, 'runtime/arrays', 1,
 
2399
            'Do not use variable-length arrays.  Use an appropriately named '
 
2400
            "('k' followed by CamelCase) compile-time constant for the size.")
 
2401
 
 
2402
  # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or
 
2403
  # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing
 
2404
  # in the class declaration.
 
2405
  match = Match(
 
2406
      (r'\s*'
 
2407
       r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'
 
2408
       r'\(.*\);$'),
 
2409
      line)
 
2410
  if match and linenum + 1 < clean_lines.NumLines():
 
2411
    next_line = clean_lines.elided[linenum + 1]
 
2412
    if not Search(r'^\s*};', next_line):
 
2413
      error(filename, linenum, 'readability/constructors', 3,
 
2414
            match.group(1) + ' should be the last thing in the class')
 
2415
 
 
2416
  # Check for use of unnamed namespaces in header files.  Registration
 
2417
  # macros are typically OK, so we allow use of "namespace {" on lines
 
2418
  # that end with backslashes.
 
2419
  if (file_extension == 'h'
 
2420
      and Search(r'\bnamespace\s*{', line)
 
2421
      and line[-1] != '\\'):
 
2422
    error(filename, linenum, 'build/namespaces', 4,
 
2423
          'Do not use unnamed namespaces in header files.  See '
 
2424
          'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
 
2425
          ' for more information.')
 
2426
 
 
2427
 
 
2428
def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
 
2429
                    error):
 
2430
  """Checks for a C-style cast by looking for the pattern.
 
2431
 
 
2432
  This also handles sizeof(type) warnings, due to similarity of content.
 
2433
 
 
2434
  Args:
 
2435
    filename: The name of the current file.
 
2436
    linenum: The number of the line to check.
 
2437
    line: The line of code to check.
 
2438
    raw_line: The raw line of code to check, with comments.
 
2439
    cast_type: The string for the C++ cast to recommend.  This is either
 
2440
      reinterpret_cast or static_cast, depending.
 
2441
    pattern: The regular expression used to find C-style casts.
 
2442
    error: The function to call with any errors found.
 
2443
  """
 
2444
  match = Search(pattern, line)
 
2445
  if not match:
 
2446
    return
 
2447
 
 
2448
  # e.g., sizeof(int)
 
2449
  sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
 
2450
  if sizeof_match:
 
2451
    error(filename, linenum, 'runtime/sizeof', 1,
 
2452
          'Using sizeof(type).  Use sizeof(varname) instead if possible')
 
2453
    return
 
2454
 
 
2455
  remainder = line[match.end(0):]
 
2456
 
 
2457
  # The close paren is for function pointers as arguments to a function.
 
2458
  # eg, void foo(void (*bar)(int));
 
2459
  # The semicolon check is a more basic function check; also possibly a
 
2460
  # function pointer typedef.
 
2461
  # eg, void foo(int); or void foo(int) const;
 
2462
  # The equals check is for function pointer assignment.
 
2463
  # eg, void *(*foo)(int) = ...
 
2464
  #
 
2465
  # Right now, this will only catch cases where there's a single argument, and
 
2466
  # it's unnamed.  It should probably be expanded to check for multiple
 
2467
  # arguments with some unnamed.
 
2468
  function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)))', remainder)
 
2469
  if function_match:
 
2470
    if (not function_match.group(3) or
 
2471
        function_match.group(3) == ';' or
 
2472
        raw_line.find('/*') < 0):
 
2473
      error(filename, linenum, 'readability/function', 3,
 
2474
            'All parameters should be named in a function')
 
2475
    return
 
2476
 
 
2477
  # At this point, all that should be left is actual casts.
 
2478
  error(filename, linenum, 'readability/casting', 4,
 
2479
        'Using C-style cast.  Use %s<%s>(...) instead' %
 
2480
        (cast_type, match.group(1)))
 
2481
 
 
2482
 
 
2483
_HEADERS_CONTAINING_TEMPLATES = (
 
2484
    ('<deque>', ('deque',)),
 
2485
    ('<functional>', ('unary_function', 'binary_function',
 
2486
                      'plus', 'minus', 'multiplies', 'divides', 'modulus',
 
2487
                      'negate',
 
2488
                      'equal_to', 'not_equal_to', 'greater', 'less',
 
2489
                      'greater_equal', 'less_equal',
 
2490
                      'logical_and', 'logical_or', 'logical_not',
 
2491
                      'unary_negate', 'not1', 'binary_negate', 'not2',
 
2492
                      'bind1st', 'bind2nd',
 
2493
                      'pointer_to_unary_function',
 
2494
                      'pointer_to_binary_function',
 
2495
                      'ptr_fun',
 
2496
                      'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
 
2497
                      'mem_fun_ref_t',
 
2498
                      'const_mem_fun_t', 'const_mem_fun1_t',
 
2499
                      'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
 
2500
                      'mem_fun_ref',
 
2501
                     )),
 
2502
    ('<limits>', ('numeric_limits',)),
 
2503
    ('<list>', ('list',)),
 
2504
    ('<map>', ('map', 'multimap',)),
 
2505
    ('<memory>', ('allocator',)),
 
2506
    ('<queue>', ('queue', 'priority_queue',)),
 
2507
    ('<set>', ('set', 'multiset',)),
 
2508
    ('<stack>', ('stack',)),
 
2509
    ('<string>', ('char_traits', 'basic_string',)),
 
2510
    ('<utility>', ('pair',)),
 
2511
    ('<vector>', ('vector',)),
 
2512
 
 
2513
    # gcc extensions.
 
2514
    # Note: std::hash is their hash, ::hash is our hash
 
2515
    ('<hash_map>', ('hash_map', 'hash_multimap',)),
 
2516
    ('<hash_set>', ('hash_set', 'hash_multiset',)),
 
2517
    ('<slist>', ('slist',)),
 
2518
    )
 
2519
 
 
2520
_HEADERS_ACCEPTED_BUT_NOT_PROMOTED = {
 
2521
    # We can trust with reasonable confidence that map gives us pair<>, too.
 
2522
    'pair<>': ('map', 'multimap', 'hash_map', 'hash_multimap')
 
2523
}
 
2524
 
 
2525
_RE_PATTERN_STRING = re.compile(r'\bstring\b')
 
2526
 
 
2527
_re_pattern_algorithm_header = []
 
2528
for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
 
2529
                  'transform'):
 
2530
  # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
 
2531
  # type::max().
 
2532
  _re_pattern_algorithm_header.append(
 
2533
      (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
 
2534
       _template,
 
2535
       '<algorithm>'))
 
2536
 
 
2537
_re_pattern_templates = []
 
2538
for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
 
2539
  for _template in _templates:
 
2540
    _re_pattern_templates.append(
 
2541
        (re.compile(r'(\<|\b)' + _template + r'\s*\<'),
 
2542
         _template + '<>',
 
2543
         _header))
 
2544
 
 
2545
 
 
2546
def FilesBelongToSameModule(filename_cc, filename_h):
 
2547
  """Check if these two filenames belong to the same module.
 
2548
 
 
2549
  The concept of a 'module' here is a as follows:
 
2550
  foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the
 
2551
  same 'module' if they are in the same directory.
 
2552
  some/path/public/xyzzy and some/path/internal/xyzzy are also considered
 
2553
  to belong to the same module here.
 
2554
 
 
2555
  If the filename_cc contains a longer path than the filename_h, for example,
 
2556
  '/absolute/path/to/base/sysinfo.cc', and this file would include
 
2557
  'base/sysinfo.h', this function also produces the prefix needed to open the
 
2558
  header. This is used by the caller of this function to more robustly open the
 
2559
  header file. We don't have access to the real include paths in this context,
 
2560
  so we need this guesswork here.
 
2561
 
 
2562
  Known bugs: tools/base/bar.cc and base/bar.h belong to the same module
 
2563
  according to this implementation. Because of this, this function gives
 
2564
  some false positives. This should be sufficiently rare in practice.
 
2565
 
 
2566
  Args:
 
2567
    filename_cc: is the path for the .cc file
 
2568
    filename_h: is the path for the header path
 
2569
 
 
2570
  Returns:
 
2571
    Tuple with a bool and a string:
 
2572
    bool: True if filename_cc and filename_h belong to the same module.
 
2573
    string: the additional prefix needed to open the header file.
 
2574
  """
 
2575
 
 
2576
  if not filename_cc.endswith('.cc'):
 
2577
    return (False, '')
 
2578
  filename_cc = filename_cc[:-len('.cc')]
 
2579
  if filename_cc.endswith('_unittest'):
 
2580
    filename_cc = filename_cc[:-len('_unittest')]
 
2581
  elif filename_cc.endswith('_test'):
 
2582
    filename_cc = filename_cc[:-len('_test')]
 
2583
  filename_cc = filename_cc.replace('/public/', '/')
 
2584
  filename_cc = filename_cc.replace('/internal/', '/')
 
2585
 
 
2586
  if not filename_h.endswith('.h'):
 
2587
    return (False, '')
 
2588
  filename_h = filename_h[:-len('.h')]
 
2589
  if filename_h.endswith('-inl'):
 
2590
    filename_h = filename_h[:-len('-inl')]
 
2591
  filename_h = filename_h.replace('/public/', '/')
 
2592
  filename_h = filename_h.replace('/internal/', '/')
 
2593
 
 
2594
  files_belong_to_same_module = filename_cc.endswith(filename_h)
 
2595
  common_path = ''
 
2596
  if files_belong_to_same_module:
 
2597
    common_path = filename_cc[:-len(filename_h)]
 
2598
  return files_belong_to_same_module, common_path
 
2599
 
 
2600
 
 
2601
def UpdateIncludeState(filename, include_state, io=codecs):
 
2602
  """Fill up the include_state with new includes found from the file.
 
2603
 
 
2604
  Args:
 
2605
    filename: the name of the header to read.
 
2606
    include_state: an _IncludeState instance in which the headers are inserted.
 
2607
    io: The io factory to use to read the file. Provided for testability.
 
2608
 
 
2609
  Returns:
 
2610
    True if a header was succesfully added. False otherwise.
 
2611
  """
 
2612
  headerfile = None
 
2613
  try:
 
2614
    headerfile = io.open(filename, 'r', 'utf8', 'replace')
 
2615
  except IOError:
 
2616
    return False
 
2617
  _cpplint_state.seen_file(filename)
 
2618
  linenum = 0
 
2619
  for line in headerfile:
 
2620
    linenum += 1
 
2621
    clean_line = CleanseComments(line)
 
2622
    match = _RE_PATTERN_INCLUDE.search(clean_line)
 
2623
    if match:
 
2624
      include = match.group(2)
 
2625
      # The value formatting is cute, but not really used right now.
 
2626
      # What matters here is that the key is in include_state.
 
2627
      include_state.setdefault(include, '%s:%d' % (filename, linenum))
 
2628
  return True
 
2629
 
 
2630
 
 
2631
def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
 
2632
                              io=codecs):
 
2633
  """Reports for missing stl includes.
 
2634
 
 
2635
  This function will output warnings to make sure you are including the headers
 
2636
  necessary for the stl containers and functions that you use. We only give one
 
2637
  reason to include a header. For example, if you use both equal_to<> and
 
2638
  less<> in a .h file, only one (the latter in the file) of these will be
 
2639
  reported as a reason to include the <functional>.
 
2640
 
 
2641
  Args:
 
2642
    filename: The name of the current file.
 
2643
    clean_lines: A CleansedLines instance containing the file.
 
2644
    include_state: An _IncludeState instance.
 
2645
    error: The function to call with any errors found.
 
2646
    io: The IO factory to use to read the header file. Provided for unittest
 
2647
        injection.
 
2648
  """
 
2649
  required = {}  # A map of header name to linenumber and the template entity.
 
2650
                 # Example of required: { '<functional>': (1219, 'less<>') }
 
2651
 
 
2652
  for linenum in xrange(clean_lines.NumLines()):
 
2653
    line = clean_lines.elided[linenum]
 
2654
    if not line or line[0] == '#':
 
2655
      continue
 
2656
 
 
2657
    # String is special -- it is a non-templatized type in STL.
 
2658
    if _RE_PATTERN_STRING.search(line):
 
2659
      required['<string>'] = (linenum, 'string')
 
2660
 
 
2661
    for pattern, template, header in _re_pattern_algorithm_header:
 
2662
      if pattern.search(line):
 
2663
        required[header] = (linenum, template)
 
2664
 
 
2665
    # The following function is just a speed up, no semantics are changed.
 
2666
    if not '<' in line:  # Reduces the cpu time usage by skipping lines.
 
2667
      continue
 
2668
 
 
2669
    for pattern, template, header in _re_pattern_templates:
 
2670
      if pattern.search(line):
 
2671
        required[header] = (linenum, template)
 
2672
 
 
2673
  # The policy is that if you #include something in foo.h you don't need to
 
2674
  # include it again in foo.cc. Here, we will look at possible includes.
 
2675
  # Let's copy the include_state so it is only messed up within this function.
 
2676
  include_state = include_state.copy()
 
2677
 
 
2678
  # Did we find the header for this file (if any) and succesfully load it?
 
2679
  header_found = False
 
2680
 
 
2681
  # Use the absolute path so that matching works properly.
 
2682
  abs_filename = os.path.abspath(filename)
 
2683
 
 
2684
  # For Emacs's flymake.
 
2685
  # If cpplint is invoked from Emacs's flymake, a temporary file is generated
 
2686
  # by flymake and that file name might end with '_flymake.cc'. In that case,
 
2687
  # restore original file name here so that the corresponding header file can be
 
2688
  # found.
 
2689
  # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
 
2690
  # instead of 'foo_flymake.h'
 
2691
  emacs_flymake_suffix = '_flymake.cc'
 
2692
  if abs_filename.endswith(emacs_flymake_suffix):
 
2693
    abs_filename = abs_filename[:-len(emacs_flymake_suffix)] + '.cc'
 
2694
 
 
2695
  # include_state is modified during iteration, so we iterate over a copy of
 
2696
  # the keys.
 
2697
  for header in include_state.keys():  #NOLINT
 
2698
    (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
 
2699
    fullpath = common_path + header
 
2700
    if same_module and UpdateIncludeState(fullpath, include_state, io):
 
2701
      header_found = True
 
2702
 
 
2703
  # If we can't find the header file for a .cc, assume it's because we don't
 
2704
  # know where to look. In that case we'll give up as we're not sure they
 
2705
  # didn't include it in the .h file.
 
2706
  # TODO(unknown): Do a better job of finding .h files so we are confident that
 
2707
  # not having the .h file means there isn't one.
 
2708
  if filename.endswith('.cc') and not header_found:
 
2709
    return
 
2710
 
 
2711
  # All the lines have been processed, report the errors found.
 
2712
  for required_header_unstripped in required:
 
2713
    template = required[required_header_unstripped][1]
 
2714
    if template in _HEADERS_ACCEPTED_BUT_NOT_PROMOTED:
 
2715
      headers = _HEADERS_ACCEPTED_BUT_NOT_PROMOTED[template]
 
2716
      if [True for header in headers if header in include_state]:
 
2717
        continue
 
2718
    if required_header_unstripped.strip('<>"') not in include_state:
 
2719
      error(filename, required[required_header_unstripped][0],
 
2720
            'build/include_what_you_use', 4,
 
2721
            'Add #include ' + required_header_unstripped + ' for ' + template)
 
2722
 
 
2723
 
 
2724
def ProcessLine(filename, file_extension,
 
2725
                clean_lines, line, include_state, function_state,
 
2726
                class_state, error):
 
2727
  """Processes a single line in the file.
 
2728
 
 
2729
  Args:
 
2730
    filename: Filename of the file that is being processed.
 
2731
    file_extension: The extension (dot not included) of the file.
 
2732
    clean_lines: An array of strings, each representing a line of the file,
 
2733
                 with comments stripped.
 
2734
    line: Number of line being processed.
 
2735
    include_state: An _IncludeState instance in which the headers are inserted.
 
2736
    function_state: A _FunctionState instance which counts function lines, etc.
 
2737
    class_state: A _ClassState instance which maintains information about
 
2738
                 the current stack of nested class declarations being parsed.
 
2739
    error: A callable to which errors are reported, which takes 4 arguments:
 
2740
           filename, line number, error level, and message
 
2741
 
 
2742
  """
 
2743
  raw_lines = clean_lines.raw_lines
 
2744
  CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
 
2745
  if Search(r'\bNOLINT\b', raw_lines[line]):  # ignore nolint lines
 
2746
    return
 
2747
  CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
 
2748
  CheckStyle(filename, clean_lines, line, file_extension, error)
 
2749
  CheckLanguage(filename, clean_lines, line, file_extension, include_state,
 
2750
                error)
 
2751
  CheckForNonStandardConstructs(filename, clean_lines, line,
 
2752
                                class_state, error)
 
2753
  CheckPosixThreading(filename, clean_lines, line, error)
 
2754
  CheckInvalidIncrement(filename, clean_lines, line, error)
 
2755
 
 
2756
 
 
2757
def ProcessFileData(filename, file_extension, lines, error):
 
2758
  """Performs lint checks and reports any errors to the given error function.
 
2759
 
 
2760
  Args:
 
2761
    filename: Filename of the file that is being processed.
 
2762
    file_extension: The extension (dot not included) of the file.
 
2763
    lines: An array of strings, each representing a line of the file, with the
 
2764
           last element being empty if the file is termined with a newline.
 
2765
    error: A callable to which errors are reported, which takes 4 arguments:
 
2766
  """
 
2767
  lines = (['// marker so line numbers and indices both start at 1'] + lines +
 
2768
           ['// marker so line numbers end in a known way'])
 
2769
 
 
2770
  include_state = _IncludeState()
 
2771
  function_state = _FunctionState()
 
2772
  class_state = _ClassState()
 
2773
 
 
2774
  CheckForCopyright(filename, lines, error)
 
2775
 
 
2776
  if file_extension == 'h':
 
2777
    CheckForHeaderGuard(filename, lines, error)
 
2778
 
 
2779
  RemoveMultiLineComments(filename, lines, error)
 
2780
  clean_lines = CleansedLines(lines)
 
2781
  for line in xrange(clean_lines.NumLines()):
 
2782
    ProcessLine(filename, file_extension, clean_lines, line,
 
2783
                include_state, function_state, class_state, error)
 
2784
  class_state.CheckFinished(filename, error)
 
2785
 
 
2786
  CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
 
2787
 
 
2788
  # We check here rather than inside ProcessLine so that we see raw
 
2789
  # lines rather than "cleaned" lines.
 
2790
  CheckForUnicodeReplacementCharacters(filename, lines, error)
 
2791
 
 
2792
  CheckForNewlineAtEOF(filename, lines, error)
 
2793
 
 
2794
 
 
2795
def ProcessFile(filename, vlevel):
 
2796
  """Does google-lint on a single file.
 
2797
 
 
2798
  Args:
 
2799
    filename: The name of the file to parse.
 
2800
 
 
2801
    vlevel: The level of errors to report.  Every error of confidence
 
2802
    >= verbose_level will be reported.  0 is a good default.
 
2803
  """
 
2804
 
 
2805
  _SetVerboseLevel(vlevel)
 
2806
 
 
2807
  try:
 
2808
    # Support the UNIX convention of using "-" for stdin.  Note that
 
2809
    # we are not opening the file with universal newline support
 
2810
    # (which codecs doesn't support anyway), so the resulting lines do
 
2811
    # contain trailing '\r' characters if we are reading a file that
 
2812
    # has CRLF endings.
 
2813
    # If after the split a trailing '\r' is present, it is removed
 
2814
    # below. If it is not expected to be present (i.e. os.linesep !=
 
2815
    # '\r\n' as in Windows), a warning is issued below if this file
 
2816
    # is processed.
 
2817
 
 
2818
    if filename == '-':
 
2819
      lines = codecs.StreamReaderWriter(sys.stdin,
 
2820
                                        codecs.getreader('utf8'),
 
2821
                                        codecs.getwriter('utf8'),
 
2822
                                        'replace').read().split('\n')
 
2823
    else:
 
2824
      _cpplint_state.seen_file(filename)
 
2825
      lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
 
2826
 
 
2827
    carriage_return_found = False
 
2828
    # Remove trailing '\r'.
 
2829
    for linenum in range(len(lines)):
 
2830
      if lines[linenum].endswith('\r'):
 
2831
        lines[linenum] = lines[linenum].rstrip('\r')
 
2832
        carriage_return_found = True
 
2833
 
 
2834
  except IOError:
 
2835
    sys.stderr.write(
 
2836
        "Skipping input '%s': Can't open for reading\n" % filename)
 
2837
    return
 
2838
 
 
2839
  # Note, if no dot is found, this will give the entire filename as the ext.
 
2840
  file_extension = filename[filename.rfind('.') + 1:]
 
2841
 
 
2842
  # When reading from stdin, the extension is unknown, so no cpplint tests
 
2843
  # should rely on the extension.
 
2844
  if (filename != '-' and file_extension != 'cc' and file_extension != 'h'
 
2845
      and file_extension != 'cpp'):
 
2846
    sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename)
 
2847
  else:
 
2848
    ProcessFileData(filename, file_extension, lines, Error)
 
2849
    if carriage_return_found and os.linesep != '\r\n':
 
2850
      # Use 0 for linenum since outputing only one error for potentially
 
2851
      # several lines.
 
2852
      Error(filename, 0, 'whitespace/newline', 1,
 
2853
            'One or more unexpected \\r (^M) found;'
 
2854
            'better to use only a \\n')
 
2855
 
 
2856
  sys.stderr.write('Done processing %s\n' % filename)
 
2857
 
 
2858
 
 
2859
def PrintUsage(message):
 
2860
  """Prints a brief usage string and exits, optionally with an error message.
 
2861
 
 
2862
  Args:
 
2863
    message: The optional error message.
 
2864
  """
 
2865
  sys.stderr.write(_USAGE)
 
2866
  if message:
 
2867
    sys.exit('\nFATAL ERROR: ' + message)
 
2868
  else:
 
2869
    sys.exit(1)
 
2870
 
 
2871
 
 
2872
def PrintCategories():
 
2873
  """Prints a list of all the error-categories used by error messages.
 
2874
 
 
2875
  These are the categories used to filter messages via --filter.
 
2876
  """
 
2877
  sys.stderr.write(_ERROR_CATEGORIES)
 
2878
  sys.exit(0)
 
2879
 
 
2880
 
 
2881
def ParseArguments(args):
 
2882
  """Parses the command line arguments.
 
2883
 
 
2884
  This may set the output format and verbosity level as side-effects.
 
2885
 
 
2886
  Args:
 
2887
    args: The command line arguments:
 
2888
 
 
2889
  Returns:
 
2890
    The list of filenames to lint.
 
2891
  """
 
2892
  try:
 
2893
    (opts, filenames) = getopt.getopt(args, '',
 
2894
        ['help', 'output=', 'verbose=', 'deps=', 'filter='])
 
2895
  except getopt.GetoptError:
 
2896
    PrintUsage('Invalid arguments.')
 
2897
 
 
2898
  verbosity = _VerboseLevel()
 
2899
  output_format = _OutputFormat()
 
2900
  filters = ''
 
2901
 
 
2902
  for (opt, val) in opts:
 
2903
    if opt == '--help':
 
2904
      PrintUsage(None)
 
2905
    elif opt == '--output':
 
2906
      if not val in ('emacs', 'vs7'):
 
2907
        PrintUsage('The only allowed output formats are emacs and vs7.')
 
2908
      output_format = val
 
2909
    elif opt == '--verbose':
 
2910
      verbosity = int(val)
 
2911
    elif opt == '--filter':
 
2912
      filters = val
 
2913
      if not filters:
 
2914
        PrintCategories()
 
2915
    elif opt == '--deps':
 
2916
        _cpplint_state.depfilename = val
 
2917
 
 
2918
  if not filenames:
 
2919
    PrintUsage('No files were specified.')
 
2920
 
 
2921
  _SetOutputFormat(output_format)
 
2922
  _SetVerboseLevel(verbosity)
 
2923
  _SetFilters(filters)
 
2924
 
 
2925
  return filenames
 
2926
 
 
2927
 
 
2928
def main():
 
2929
  filenames = ParseArguments(sys.argv[1:])
 
2930
 
 
2931
  # Change stderr to write with replacement characters so we don't die
 
2932
  # if we try to print something containing non-ASCII characters.
 
2933
  sys.stderr = codecs.StreamReaderWriter(sys.stderr,
 
2934
                                         codecs.getreader('utf8'),
 
2935
                                         codecs.getwriter('utf8'),
 
2936
                                         'replace')
 
2937
 
 
2938
  _cpplint_state.ResetErrorCount()
 
2939
  for filename in filenames:
 
2940
    ProcessFile(filename, _cpplint_state.verbose_level)
 
2941
  _cpplint_state.finished()
 
2942
  sys.stderr.write('Total errors found: %d\n' % _cpplint_state.error_count)
 
2943
  sys.exit(_cpplint_state.error_count > 0)
 
2944
 
 
2945
 
 
2946
if __name__ == '__main__':
 
2947
  main()