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

Side by Side Diff: cpplint.py

Issue 317053002: Update cpplint.py to r133. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright (c) 2009 Google Inc. All rights reserved. 3 # Copyright (c) 2009 Google Inc. All rights reserved.
4 # 4 #
5 # Redistribution and use in source and binary forms, with or without 5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are 6 # modification, are permitted provided that the following conditions are
7 # met: 7 # met:
8 # 8 #
9 # * Redistributions of source code must retain the above copyright 9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer. 10 # notice, this list of conditions and the following disclaimer.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 107
108 root=subdir 108 root=subdir
109 The root directory used for deriving header guard CPP variable. 109 The root directory used for deriving header guard CPP variable.
110 By default, the header guard CPP variable is calculated as the relative 110 By default, the header guard CPP variable is calculated as the relative
111 path to the directory that contains .git, .hg, or .svn. When this flag 111 path to the directory that contains .git, .hg, or .svn. When this flag
112 is specified, the relative path is calculated from the specified 112 is specified, the relative path is calculated from the specified
113 directory. If the specified directory does not exist, this flag is 113 directory. If the specified directory does not exist, this flag is
114 ignored. 114 ignored.
115 115
116 Examples: 116 Examples:
117 Assuing that src/.git exists, the header guard CPP variables for 117 Assuming that src/.git exists, the header guard CPP variables for
118 src/chrome/browser/ui/browser.h are: 118 src/chrome/browser/ui/browser.h are:
119 119
120 No flag => CHROME_BROWSER_UI_BROWSER_H_ 120 No flag => CHROME_BROWSER_UI_BROWSER_H_
121 --root=chrome => BROWSER_UI_BROWSER_H_ 121 --root=chrome => BROWSER_UI_BROWSER_H_
122 --root=chrome/browser => UI_BROWSER_H_ 122 --root=chrome/browser => UI_BROWSER_H_
123 123
124 linelength=digits 124 linelength=digits
125 This is the allowed line length for the project. The default value is 125 This is the allowed line length for the project. The default value is
126 80 characters. 126 80 characters.
127 127
128 Examples: 128 Examples:
129 --linelength=120 129 --linelength=120
130 130
131 extensions=extension,extension,... 131 extensions=extension,extension,...
132 The allowed file extensions that cpplint will check 132 The allowed file extensions that cpplint will check
133 133
134 Examples: 134 Examples:
135 --extensions=hpp,cpp 135 --extensions=hpp,cpp
136 """ 136 """
137 137
138 # We categorize each error message we print. Here are the categories. 138 # We categorize each error message we print. Here are the categories.
139 # We want an explicit list so we can list them all in cpplint --filter=. 139 # We want an explicit list so we can list them all in cpplint --filter=.
140 # If you add a new error message with a new category, add it to the list 140 # If you add a new error message with a new category, add it to the list
141 # here! cpplint_unittest.py should tell you if you forget to do this. 141 # here! cpplint_unittest.py should tell you if you forget to do this.
142 _ERROR_CATEGORIES = [ 142 _ERROR_CATEGORIES = [
143 'build/class', 143 'build/class',
144 'build/c++11',
144 'build/deprecated', 145 'build/deprecated',
145 'build/endif_comment', 146 'build/endif_comment',
146 'build/explicit_make_pair', 147 'build/explicit_make_pair',
147 'build/forward_decl', 148 'build/forward_decl',
148 'build/header_guard', 149 'build/header_guard',
149 'build/include', 150 'build/include',
150 'build/include_alpha', 151 'build/include_alpha',
151 'build/include_order', 152 'build/include_order',
152 'build/include_what_you_use', 153 'build/include_what_you_use',
153 'build/namespaces', 154 'build/namespaces',
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 'whitespace/indent', 197 'whitespace/indent',
197 'whitespace/line_length', 198 'whitespace/line_length',
198 'whitespace/newline', 199 'whitespace/newline',
199 'whitespace/operators', 200 'whitespace/operators',
200 'whitespace/parens', 201 'whitespace/parens',
201 'whitespace/semicolon', 202 'whitespace/semicolon',
202 'whitespace/tab', 203 'whitespace/tab',
203 'whitespace/todo' 204 'whitespace/todo'
204 ] 205 ]
205 206
206 # The default state of the category filter. This is overrided by the --filter= 207 # The default state of the category filter. This is overridden by the --filter=
207 # flag. By default all errors are on, so only add here categories that should be 208 # flag. By default all errors are on, so only add here categories that should be
208 # off by default (i.e., categories that must be enabled by the --filter= flags). 209 # off by default (i.e., categories that must be enabled by the --filter= flags).
209 # All entries here should start with a '-' or '+', as in the --filter= flag. 210 # All entries here should start with a '-' or '+', as in the --filter= flag.
210 _DEFAULT_FILTERS = ['-build/include_alpha'] 211 _DEFAULT_FILTERS = ['-build/include_alpha']
211 212
212 # We used to check for high-bit characters, but after much discussion we 213 # We used to check for high-bit characters, but after much discussion we
213 # decided those were OK, as long as they were in UTF-8 and didn't represent 214 # decided those were OK, as long as they were in UTF-8 and didn't represent
214 # hard-coded international strings, which belong in a separate i18n file. 215 # hard-coded international strings, which belong in a separate i18n file.
215 216
216
217 # C++ headers 217 # C++ headers
218 _CPP_HEADERS = frozenset([ 218 _CPP_HEADERS = frozenset([
219 # Legacy 219 # Legacy
220 'algobase.h', 220 'algobase.h',
221 'algo.h', 221 'algo.h',
222 'alloc.h', 222 'alloc.h',
223 'builtinbuf.h', 223 'builtinbuf.h',
224 'bvector.h', 224 'bvector.h',
225 'complex.h', 225 'complex.h',
226 'defalloc.h', 226 'defalloc.h',
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 'cstdio', 343 'cstdio',
344 'cstdlib', 344 'cstdlib',
345 'cstring', 345 'cstring',
346 'ctgmath', 346 'ctgmath',
347 'ctime', 347 'ctime',
348 'cuchar', 348 'cuchar',
349 'cwchar', 349 'cwchar',
350 'cwctype', 350 'cwctype',
351 ]) 351 ])
352 352
353
353 # Assertion macros. These are defined in base/logging.h and 354 # Assertion macros. These are defined in base/logging.h and
354 # testing/base/gunit.h. Note that the _M versions need to come first 355 # testing/base/gunit.h. Note that the _M versions need to come first
355 # for substring matching to work. 356 # for substring matching to work.
356 _CHECK_MACROS = [ 357 _CHECK_MACROS = [
357 'DCHECK', 'CHECK', 358 'DCHECK', 'CHECK',
358 'EXPECT_TRUE_M', 'EXPECT_TRUE', 359 'EXPECT_TRUE_M', 'EXPECT_TRUE',
359 'ASSERT_TRUE_M', 'ASSERT_TRUE', 360 'ASSERT_TRUE_M', 'ASSERT_TRUE',
360 'EXPECT_FALSE_M', 'EXPECT_FALSE', 361 'EXPECT_FALSE_M', 'EXPECT_FALSE',
361 'ASSERT_FALSE_M', 'ASSERT_FALSE', 362 'ASSERT_FALSE_M', 'ASSERT_FALSE',
362 ] 363 ]
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 494
494 Args: 495 Args:
495 category: str, the category of the error. 496 category: str, the category of the error.
496 linenum: int, the current line number. 497 linenum: int, the current line number.
497 Returns: 498 Returns:
498 bool, True iff the error should be suppressed due to a NOLINT comment. 499 bool, True iff the error should be suppressed due to a NOLINT comment.
499 """ 500 """
500 return (linenum in _error_suppressions.get(category, set()) or 501 return (linenum in _error_suppressions.get(category, set()) or
501 linenum in _error_suppressions.get(None, set())) 502 linenum in _error_suppressions.get(None, set()))
502 503
504
503 def Match(pattern, s): 505 def Match(pattern, s):
504 """Matches the string with the pattern, caching the compiled regexp.""" 506 """Matches the string with the pattern, caching the compiled regexp."""
505 # The regexp compilation caching is inlined in both Match and Search for 507 # The regexp compilation caching is inlined in both Match and Search for
506 # performance reasons; factoring it out into a separate function turns out 508 # performance reasons; factoring it out into a separate function turns out
507 # to be noticeably expensive. 509 # to be noticeably expensive.
508 if pattern not in _regexp_compile_cache: 510 if pattern not in _regexp_compile_cache:
509 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) 511 _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
510 return _regexp_compile_cache[pattern].match(s) 512 return _regexp_compile_cache[pattern].match(s)
511 513
512 514
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 949
948 950
949 def _ShouldPrintError(category, confidence, linenum): 951 def _ShouldPrintError(category, confidence, linenum):
950 """If confidence >= verbose, category passes filter and is not suppressed.""" 952 """If confidence >= verbose, category passes filter and is not suppressed."""
951 953
952 # There are three ways we might decide not to print an error message: 954 # There are three ways we might decide not to print an error message:
953 # a "NOLINT(category)" comment appears in the source, 955 # a "NOLINT(category)" comment appears in the source,
954 # the verbosity level isn't high enough, or the filters filter it out. 956 # the verbosity level isn't high enough, or the filters filter it out.
955 if IsErrorSuppressedByNolint(category, linenum): 957 if IsErrorSuppressedByNolint(category, linenum):
956 return False 958 return False
959
957 if confidence < _cpplint_state.verbose_level: 960 if confidence < _cpplint_state.verbose_level:
958 return False 961 return False
959 962
960 is_filtered = False 963 is_filtered = False
961 for one_filter in _Filters(): 964 for one_filter in _Filters():
962 if one_filter.startswith('-'): 965 if one_filter.startswith('-'):
963 if category.startswith(one_filter[1:]): 966 if category.startswith(one_filter[1:]):
964 is_filtered = True 967 is_filtered = True
965 elif one_filter.startswith('+'): 968 elif one_filter.startswith('+'):
966 if category.startswith(one_filter[1:]): 969 if category.startswith(one_filter[1:]):
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( 1007 sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
1005 filename, linenum, message, category, confidence)) 1008 filename, linenum, message, category, confidence))
1006 else: 1009 else:
1007 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( 1010 sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
1008 filename, linenum, message, category, confidence)) 1011 filename, linenum, message, category, confidence))
1009 1012
1010 1013
1011 # Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard. 1014 # Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard.
1012 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( 1015 _RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
1013 r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') 1016 r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
1014 # Matches strings. Escape codes should already be removed by ESCAPES. 1017 # Match a single C style comment on the same line.
1015 _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"') 1018 _RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/'
1016 # Matches characters. Escape codes should already be removed by ESCAPES. 1019 # Matches multi-line C style comments.
1017 _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
1018 # Matches multi-line C++ comments.
1019 # This RE is a little bit more complicated than one might expect, because we 1020 # This RE is a little bit more complicated than one might expect, because we
1020 # have to take care of space removals tools so we can handle comments inside 1021 # have to take care of space removals tools so we can handle comments inside
1021 # statements better. 1022 # statements better.
1022 # The current rule is: We only clear spaces from both sides when we're at the 1023 # The current rule is: We only clear spaces from both sides when we're at the
1023 # end of the line. Otherwise, we try to remove spaces from the right side, 1024 # end of the line. Otherwise, we try to remove spaces from the right side,
1024 # if this doesn't work we try on left side but only if there's a non-character 1025 # if this doesn't work we try on left side but only if there's a non-character
1025 # on the right. 1026 # on the right.
1026 _RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( 1027 _RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
1027 r"""(\s*/\*.*\*/\s*$| 1028 r'(\s*' + _RE_PATTERN_C_COMMENTS + r'\s*$|' +
1028 /\*.*\*/\s+| 1029 _RE_PATTERN_C_COMMENTS + r'\s+|' +
1029 \s+/\*.*\*/(?=\W)| 1030 r'\s+' + _RE_PATTERN_C_COMMENTS + r'(?=\W)|' +
1030 /\*.*\*/)""", re.VERBOSE) 1031 _RE_PATTERN_C_COMMENTS + r')')
1031 1032
1032 1033
1033 def IsCppString(line): 1034 def IsCppString(line):
1034 """Does line terminate so, that the next symbol is in string constant. 1035 """Does line terminate so, that the next symbol is in string constant.
1035 1036
1036 This function does not consider single-line nor multi-line comments. 1037 This function does not consider single-line nor multi-line comments.
1037 1038
1038 Args: 1039 Args:
1039 line: is a partial line of code starting from the 0..n. 1040 line: is a partial line of code starting from the 0..n.
1040 1041
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 end = line.find(delimiter) 1076 end = line.find(delimiter)
1076 if end >= 0: 1077 if end >= 0:
1077 # Found the end of the string, match leading space for this 1078 # Found the end of the string, match leading space for this
1078 # line and resume copying the original lines, and also insert 1079 # line and resume copying the original lines, and also insert
1079 # a "" on the last line. 1080 # a "" on the last line.
1080 leading_space = Match(r'^(\s*)\S', line) 1081 leading_space = Match(r'^(\s*)\S', line)
1081 line = leading_space.group(1) + '""' + line[end + len(delimiter):] 1082 line = leading_space.group(1) + '""' + line[end + len(delimiter):]
1082 delimiter = None 1083 delimiter = None
1083 else: 1084 else:
1084 # Haven't found the end yet, append a blank line. 1085 # Haven't found the end yet, append a blank line.
1085 line = '' 1086 line = '""'
1086 1087
1087 else: 1088 # Look for beginning of a raw string, and replace them with
1089 # empty strings. This is done in a loop to handle multiple raw
1090 # strings on the same line.
1091 while delimiter is None:
1088 # Look for beginning of a raw string. 1092 # Look for beginning of a raw string.
1089 # See 2.14.15 [lex.string] for syntax. 1093 # See 2.14.15 [lex.string] for syntax.
1090 matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) 1094 matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line)
1091 if matched: 1095 if matched:
1092 delimiter = ')' + matched.group(2) + '"' 1096 delimiter = ')' + matched.group(2) + '"'
1093 1097
1094 end = matched.group(3).find(delimiter) 1098 end = matched.group(3).find(delimiter)
1095 if end >= 0: 1099 if end >= 0:
1096 # Raw string ended on same line 1100 # Raw string ended on same line
1097 line = (matched.group(1) + '""' + 1101 line = (matched.group(1) + '""' +
1098 matched.group(3)[end + len(delimiter):]) 1102 matched.group(3)[end + len(delimiter):])
1099 delimiter = None 1103 delimiter = None
1100 else: 1104 else:
1101 # Start of a multi-line raw string 1105 # Start of a multi-line raw string
1102 line = matched.group(1) + '""' 1106 line = matched.group(1) + '""'
1107 else:
1108 break
1103 1109
1104 lines_without_raw_strings.append(line) 1110 lines_without_raw_strings.append(line)
1105 1111
1106 # TODO(unknown): if delimiter is not None here, we might want to 1112 # TODO(unknown): if delimiter is not None here, we might want to
1107 # emit a warning for unterminated string. 1113 # emit a warning for unterminated string.
1108 return lines_without_raw_strings 1114 return lines_without_raw_strings
1109 1115
1110 1116
1111 def FindNextMultiLineCommentStart(lines, lineix): 1117 def FindNextMultiLineCommentStart(lines, lineix):
1112 """Find the beginning marker for a multiline comment.""" 1118 """Find the beginning marker for a multiline comment."""
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 """Collapses strings and chars on a line to simple "" or '' blocks. 1204 """Collapses strings and chars on a line to simple "" or '' blocks.
1199 1205
1200 We nix strings first so we're not fooled by text like '"http://"' 1206 We nix strings first so we're not fooled by text like '"http://"'
1201 1207
1202 Args: 1208 Args:
1203 elided: The line being processed. 1209 elided: The line being processed.
1204 1210
1205 Returns: 1211 Returns:
1206 The line with collapsed strings. 1212 The line with collapsed strings.
1207 """ 1213 """
1208 if not _RE_PATTERN_INCLUDE.match(elided): 1214 if _RE_PATTERN_INCLUDE.match(elided):
1209 # Remove escaped characters first to make quote/single quote collapsing 1215 return elided
1210 # basic. Things that look like escaped characters shouldn't occur 1216
1211 # outside of strings and chars. 1217 # Remove escaped characters first to make quote/single quote collapsing
1212 elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) 1218 # basic. Things that look like escaped characters shouldn't occur
1213 elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided) 1219 # outside of strings and chars.
1214 elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided) 1220 elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
1215 return elided 1221
1222 # Replace quoted strings and digit separators. Both single quotes
1223 # and double quotes are processed in the same loop, otherwise
1224 # nested quotes wouldn't work.
1225 collapsed = ''
1226 while True:
1227 # Find the first quote character
1228 match = Match(r'^([^\'"]*)([\'"])(.*)$', elided)
1229 if not match:
1230 collapsed += elided
1231 break
1232 head, quote, tail = match.groups()
1233
1234 if quote == '"':
1235 # Collapse double quoted strings
1236 second_quote = tail.find('"')
1237 if second_quote >= 0:
1238 collapsed += head + '""'
1239 elided = tail[second_quote + 1:]
1240 else:
1241 # Unmatched double quote, don't bother processing the rest
1242 # of the line since this is probably a multiline string.
1243 collapsed += elided
1244 break
1245 else:
1246 # Found single quote, check nearby text to eliminate digit separators.
1247 #
1248 # There is no special handling for floating point here, because
1249 # the integer/fractional/exponent parts would all be parsed
1250 # correctly as long as there are digits on both sides of the
1251 # separator. So we are fine as long as we don't see something
1252 # like "0.'3" (gcc 4.9.0 will not allow this literal).
1253 if Search(r'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$', head):
1254 match_literal = Match(r'^((?:\'?[0-9a-zA-Z_])*)(.*)$', "'" + tail)
1255 collapsed += head + match_literal.group(1).replace("'", '')
1256 elided = match_literal.group(2)
1257 else:
1258 second_quote = tail.find('\'')
1259 if second_quote >= 0:
1260 collapsed += head + "''"
1261 elided = tail[second_quote + 1:]
1262 else:
1263 # Unmatched single quote
1264 collapsed += elided
1265 break
1266
1267 return collapsed
1216 1268
1217 1269
1218 def FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar): 1270 def FindEndOfExpressionInLine(line, startpos, stack):
1219 """Find the position just after the matching endchar. 1271 """Find the position just after the end of current parenthesized expression.
1220 1272
1221 Args: 1273 Args:
1222 line: a CleansedLines line. 1274 line: a CleansedLines line.
1223 startpos: start searching at this position. 1275 startpos: start searching at this position.
1224 depth: nesting level at startpos. 1276 stack: nesting stack at startpos.
1225 startchar: expression opening character.
1226 endchar: expression closing character.
1227 1277
1228 Returns: 1278 Returns:
1229 On finding matching endchar: (index just after matching endchar, 0) 1279 On finding matching end: (index just after matching end, None)
1230 Otherwise: (-1, new depth at end of this line) 1280 On finding an unclosed expression: (-1, None)
1281 Otherwise: (-1, new stack at end of this line)
1231 """ 1282 """
1232 for i in xrange(startpos, len(line)): 1283 for i in xrange(startpos, len(line)):
1233 if line[i] == startchar: 1284 char = line[i]
1234 depth += 1 1285 if char in '([{':
1235 elif line[i] == endchar: 1286 # Found start of parenthesized expression, push to expression stack
1236 depth -= 1 1287 stack.append(char)
1237 if depth == 0: 1288 elif char == '<':
1238 return (i + 1, 0) 1289 # Found potential start of template argument list
1239 return (-1, depth) 1290 if i > 0 and line[i - 1] == '<':
1291 # Left shift operator
1292 if stack and stack[-1] == '<':
1293 stack.pop()
1294 if not stack:
1295 return (-1, None)
1296 elif i > 0 and Search(r'\boperator\s*$', line[0:i]):
1297 # operator<, don't add to stack
1298 continue
1299 else:
1300 # Tentative start of template argument list
1301 stack.append('<')
1302 elif char in ')]}':
1303 # Found end of parenthesized expression.
1304 #
1305 # If we are currently expecting a matching '>', the pending '<'
1306 # must have been an operator. Remove them from expression stack.
1307 while stack and stack[-1] == '<':
1308 stack.pop()
1309 if not stack:
1310 return (-1, None)
1311 if ((stack[-1] == '(' and char == ')') or
1312 (stack[-1] == '[' and char == ']') or
1313 (stack[-1] == '{' and char == '}')):
1314 stack.pop()
1315 if not stack:
1316 return (i + 1, None)
1317 else:
1318 # Mismatched parentheses
1319 return (-1, None)
1320 elif char == '>':
1321 # Found potential end of template argument list.
1322
1323 # Ignore "->" and operator functions
1324 if (i > 0 and
1325 (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))):
1326 continue
1327
1328 # Pop the stack if there is a matching '<'. Otherwise, ignore
1329 # this '>' since it must be an operator.
1330 if stack:
1331 if stack[-1] == '<':
1332 stack.pop()
1333 if not stack:
1334 return (i + 1, None)
1335 elif char == ';':
1336 # Found something that look like end of statements. If we are currently
1337 # expecting a '>', the matching '<' must have been an operator, since
1338 # template argument list should not contain statements.
1339 while stack and stack[-1] == '<':
1340 stack.pop()
1341 if not stack:
1342 return (-1, None)
1343
1344 # Did not find end of expression or unbalanced parentheses on this line
1345 return (-1, stack)
1240 1346
1241 1347
1242 def CloseExpression(clean_lines, linenum, pos): 1348 def CloseExpression(clean_lines, linenum, pos):
1243 """If input points to ( or { or [ or <, finds the position that closes it. 1349 """If input points to ( or { or [ or <, finds the position that closes it.
1244 1350
1245 If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the 1351 If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the
1246 linenum/pos that correspond to the closing of the expression. 1352 linenum/pos that correspond to the closing of the expression.
1247 1353
1354 TODO(unknown): cpplint spends a fair bit of time matching parentheses.
1355 Ideally we would want to index all opening and closing parentheses once
1356 and have CloseExpression be just a simple lookup, but due to preprocessor
1357 tricks, this is not so easy.
1358
1248 Args: 1359 Args:
1249 clean_lines: A CleansedLines instance containing the file. 1360 clean_lines: A CleansedLines instance containing the file.
1250 linenum: The number of the line to check. 1361 linenum: The number of the line to check.
1251 pos: A position on the line. 1362 pos: A position on the line.
1252 1363
1253 Returns: 1364 Returns:
1254 A tuple (line, linenum, pos) pointer *past* the closing brace, or 1365 A tuple (line, linenum, pos) pointer *past* the closing brace, or
1255 (line, len(lines), -1) if we never find a close. Note we ignore 1366 (line, len(lines), -1) if we never find a close. Note we ignore
1256 strings and comments when matching; and the line we return is the 1367 strings and comments when matching; and the line we return is the
1257 'cleansed' line at linenum. 1368 'cleansed' line at linenum.
1258 """ 1369 """
1259 1370
1260 line = clean_lines.elided[linenum] 1371 line = clean_lines.elided[linenum]
1261 startchar = line[pos] 1372 if (line[pos] not in '({[<') or Match(r'<[<=]', line[pos:]):
1262 if startchar not in '({[<':
1263 return (line, clean_lines.NumLines(), -1) 1373 return (line, clean_lines.NumLines(), -1)
1264 if startchar == '(': endchar = ')'
1265 if startchar == '[': endchar = ']'
1266 if startchar == '{': endchar = '}'
1267 if startchar == '<': endchar = '>'
1268 1374
1269 # Check first line 1375 # Check first line
1270 (end_pos, num_open) = FindEndOfExpressionInLine( 1376 (end_pos, stack) = FindEndOfExpressionInLine(line, pos, [])
1271 line, pos, 0, startchar, endchar)
1272 if end_pos > -1: 1377 if end_pos > -1:
1273 return (line, linenum, end_pos) 1378 return (line, linenum, end_pos)
1274 1379
1275 # Continue scanning forward 1380 # Continue scanning forward
1276 while linenum < clean_lines.NumLines() - 1: 1381 while stack and linenum < clean_lines.NumLines() - 1:
1277 linenum += 1 1382 linenum += 1
1278 line = clean_lines.elided[linenum] 1383 line = clean_lines.elided[linenum]
1279 (end_pos, num_open) = FindEndOfExpressionInLine( 1384 (end_pos, stack) = FindEndOfExpressionInLine(line, 0, stack)
1280 line, 0, num_open, startchar, endchar)
1281 if end_pos > -1: 1385 if end_pos > -1:
1282 return (line, linenum, end_pos) 1386 return (line, linenum, end_pos)
1283 1387
1284 # Did not find endchar before end of file, give up 1388 # Did not find end of expression before end of file, give up
1285 return (line, clean_lines.NumLines(), -1) 1389 return (line, clean_lines.NumLines(), -1)
1286 1390
1287 1391
1288 def FindStartOfExpressionInLine(line, endpos, depth, startchar, endchar): 1392 def FindStartOfExpressionInLine(line, endpos, stack):
1289 """Find position at the matching startchar. 1393 """Find position at the matching start of current expression.
1290 1394
1291 This is almost the reverse of FindEndOfExpressionInLine, but note 1395 This is almost the reverse of FindEndOfExpressionInLine, but note
1292 that the input position and returned position differs by 1. 1396 that the input position and returned position differs by 1.
1293 1397
1294 Args: 1398 Args:
1295 line: a CleansedLines line. 1399 line: a CleansedLines line.
1296 endpos: start searching at this position. 1400 endpos: start searching at this position.
1297 depth: nesting level at endpos. 1401 stack: nesting stack at endpos.
1298 startchar: expression opening character.
1299 endchar: expression closing character.
1300 1402
1301 Returns: 1403 Returns:
1302 On finding matching startchar: (index at matching startchar, 0) 1404 On finding matching start: (index at matching start, None)
1303 Otherwise: (-1, new depth at beginning of this line) 1405 On finding an unclosed expression: (-1, None)
1406 Otherwise: (-1, new stack at beginning of this line)
1304 """ 1407 """
1305 for i in xrange(endpos, -1, -1): 1408 i = endpos
1306 if line[i] == endchar: 1409 while i >= 0:
1307 depth += 1 1410 char = line[i]
1308 elif line[i] == startchar: 1411 if char in ')]}':
1309 depth -= 1 1412 # Found end of expression, push to expression stack
1310 if depth == 0: 1413 stack.append(char)
1311 return (i, 0) 1414 elif char == '>':
1312 return (-1, depth) 1415 # Found potential end of template argument list.
1416 #
1417 # Ignore it if it's a "->" or ">=" or "operator>"
1418 if (i > 0 and
1419 (line[i - 1] == '-' or
1420 Match(r'\s>=\s', line[i - 1:]) or
1421 Search(r'\boperator\s*$', line[0:i]))):
1422 i -= 1
1423 else:
1424 stack.append('>')
1425 elif char == '<':
1426 # Found potential start of template argument list
1427 if i > 0 and line[i - 1] == '<':
1428 # Left shift operator
1429 i -= 1
1430 else:
1431 # If there is a matching '>', we can pop the expression stack.
1432 # Otherwise, ignore this '<' since it must be an operator.
1433 if stack and stack[-1] == '>':
1434 stack.pop()
1435 if not stack:
1436 return (i, None)
1437 elif char in '([{':
1438 # Found start of expression.
1439 #
1440 # If there are any unmatched '>' on the stack, they must be
1441 # operators. Remove those.
1442 while stack and stack[-1] == '>':
1443 stack.pop()
1444 if not stack:
1445 return (-1, None)
1446 if ((char == '(' and stack[-1] == ')') or
1447 (char == '[' and stack[-1] == ']') or
1448 (char == '{' and stack[-1] == '}')):
1449 stack.pop()
1450 if not stack:
1451 return (i, None)
1452 else:
1453 # Mismatched parentheses
1454 return (-1, None)
1455 elif char == ';':
1456 # Found something that look like end of statements. If we are currently
1457 # expecting a '<', the matching '>' must have been an operator, since
1458 # template argument list should not contain statements.
1459 while stack and stack[-1] == '>':
1460 stack.pop()
1461 if not stack:
1462 return (-1, None)
1463
1464 i -= 1
1465
1466 return (-1, stack)
1313 1467
1314 1468
1315 def ReverseCloseExpression(clean_lines, linenum, pos): 1469 def ReverseCloseExpression(clean_lines, linenum, pos):
1316 """If input points to ) or } or ] or >, finds the position that opens it. 1470 """If input points to ) or } or ] or >, finds the position that opens it.
1317 1471
1318 If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the 1472 If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the
1319 linenum/pos that correspond to the opening of the expression. 1473 linenum/pos that correspond to the opening of the expression.
1320 1474
1321 Args: 1475 Args:
1322 clean_lines: A CleansedLines instance containing the file. 1476 clean_lines: A CleansedLines instance containing the file.
1323 linenum: The number of the line to check. 1477 linenum: The number of the line to check.
1324 pos: A position on the line. 1478 pos: A position on the line.
1325 1479
1326 Returns: 1480 Returns:
1327 A tuple (line, linenum, pos) pointer *at* the opening brace, or 1481 A tuple (line, linenum, pos) pointer *at* the opening brace, or
1328 (line, 0, -1) if we never find the matching opening brace. Note 1482 (line, 0, -1) if we never find the matching opening brace. Note
1329 we ignore strings and comments when matching; and the line we 1483 we ignore strings and comments when matching; and the line we
1330 return is the 'cleansed' line at linenum. 1484 return is the 'cleansed' line at linenum.
1331 """ 1485 """
1332 line = clean_lines.elided[linenum] 1486 line = clean_lines.elided[linenum]
1333 endchar = line[pos] 1487 if line[pos] not in ')}]>':
1334 if endchar not in ')}]>':
1335 return (line, 0, -1) 1488 return (line, 0, -1)
1336 if endchar == ')': startchar = '('
1337 if endchar == ']': startchar = '['
1338 if endchar == '}': startchar = '{'
1339 if endchar == '>': startchar = '<'
1340 1489
1341 # Check last line 1490 # Check last line
1342 (start_pos, num_open) = FindStartOfExpressionInLine( 1491 (start_pos, stack) = FindStartOfExpressionInLine(line, pos, [])
1343 line, pos, 0, startchar, endchar)
1344 if start_pos > -1: 1492 if start_pos > -1:
1345 return (line, linenum, start_pos) 1493 return (line, linenum, start_pos)
1346 1494
1347 # Continue scanning backward 1495 # Continue scanning backward
1348 while linenum > 0: 1496 while stack and linenum > 0:
1349 linenum -= 1 1497 linenum -= 1
1350 line = clean_lines.elided[linenum] 1498 line = clean_lines.elided[linenum]
1351 (start_pos, num_open) = FindStartOfExpressionInLine( 1499 (start_pos, stack) = FindStartOfExpressionInLine(line, len(line) - 1, stack)
1352 line, len(line) - 1, num_open, startchar, endchar)
1353 if start_pos > -1: 1500 if start_pos > -1:
1354 return (line, linenum, start_pos) 1501 return (line, linenum, start_pos)
1355 1502
1356 # Did not find startchar before beginning of file, give up 1503 # Did not find start of expression before beginning of file, give up
1357 return (line, 0, -1) 1504 return (line, 0, -1)
1358 1505
1359 1506
1360 def CheckForCopyright(filename, lines, error): 1507 def CheckForCopyright(filename, lines, error):
1361 """Logs an error if no Copyright message appears at the top of the file.""" 1508 """Logs an error if no Copyright message appears at the top of the file."""
1362 1509
1363 # We'll say it should occur by line 10. Don't forget there's a 1510 # We'll say it should occur by line 10. Don't forget there's a
1364 # dummy line at the front. 1511 # dummy line at the front.
1365 for line in xrange(1, min(len(lines), 11)): 1512 for line in xrange(1, min(len(lines), 11)):
1366 if re.search(r'Copyright', lines[line], re.I): break 1513 if re.search(r'Copyright', lines[line], re.I): break
1367 else: # means no copyright line was found 1514 else: # means no copyright line was found
1368 error(filename, 0, 'legal/copyright', 5, 1515 error(filename, 0, 'legal/copyright', 5,
1369 'No copyright message found. ' 1516 'No copyright message found. '
1370 'You should have a line: "Copyright [year] <Copyright Owner>"') 1517 'You should have a line: "Copyright [year] <Copyright Owner>"')
1371 1518
1372 1519
1520 def GetIndentLevel(line):
1521 """Return the number of leading spaces in line.
1522
1523 Args:
1524 line: A string to check.
1525
1526 Returns:
1527 An integer count of leading spaces, possibly zero.
1528 """
1529 indent = Match(r'^( *)\S', line)
1530 if indent:
1531 return len(indent.group(1))
1532 else:
1533 return 0
1534
1535
1373 def GetHeaderGuardCPPVariable(filename): 1536 def GetHeaderGuardCPPVariable(filename):
1374 """Returns the CPP variable that should be used as a header guard. 1537 """Returns the CPP variable that should be used as a header guard.
1375 1538
1376 Args: 1539 Args:
1377 filename: The name of a C++ header file. 1540 filename: The name of a C++ header file.
1378 1541
1379 Returns: 1542 Returns:
1380 The CPP variable that should be used as a header guard in the 1543 The CPP variable that should be used as a header guard in the
1381 named file. 1544 named file.
1382 1545
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 'with #if 0...#endif, ' 1706 'with #if 0...#endif, '
1544 'or with more clearly structured multi-line comments.') 1707 'or with more clearly structured multi-line comments.')
1545 1708
1546 if (line.count('"') - line.count('\\"')) % 2: 1709 if (line.count('"') - line.count('\\"')) % 2:
1547 error(filename, linenum, 'readability/multiline_string', 5, 1710 error(filename, linenum, 'readability/multiline_string', 5,
1548 'Multi-line string ("...") found. This lint script doesn\'t ' 1711 'Multi-line string ("...") found. This lint script doesn\'t '
1549 'do well with such strings, and may give bogus warnings. ' 1712 'do well with such strings, and may give bogus warnings. '
1550 'Use C++11 raw strings or concatenation instead.') 1713 'Use C++11 raw strings or concatenation instead.')
1551 1714
1552 1715
1553 threading_list = ( 1716 # (non-threadsafe name, thread-safe alternative, validation pattern)
1554 ('asctime(', 'asctime_r('), 1717 #
1555 ('ctime(', 'ctime_r('), 1718 # The validation pattern is used to eliminate false positives such as:
1556 ('getgrgid(', 'getgrgid_r('), 1719 # _rand(); // false positive due to substring match.
1557 ('getgrnam(', 'getgrnam_r('), 1720 # ->rand(); // some member function rand().
1558 ('getlogin(', 'getlogin_r('), 1721 # ACMRandom rand(seed); // some variable named rand.
1559 ('getpwnam(', 'getpwnam_r('), 1722 # ISAACRandom rand(); // another variable named rand.
1560 ('getpwuid(', 'getpwuid_r('), 1723 #
1561 ('gmtime(', 'gmtime_r('), 1724 # Basically we require the return value of these functions to be used
1562 ('localtime(', 'localtime_r('), 1725 # in some expression context on the same line by matching on some
1563 ('rand(', 'rand_r('), 1726 # operator before the function name. This eliminates constructors and
1564 ('strtok(', 'strtok_r('), 1727 # member function calls.
1565 ('ttyname(', 'ttyname_r('), 1728 _UNSAFE_FUNC_PREFIX = r'(?:[-+*/=%^&|(<]\s*|>\s+)'
1729 _THREADING_LIST = (
1730 ('asctime(', 'asctime_r(', _UNSAFE_FUNC_PREFIX + r'asctime\([^)]+\)'),
1731 ('ctime(', 'ctime_r(', _UNSAFE_FUNC_PREFIX + r'ctime\([^)]+\)'),
1732 ('getgrgid(', 'getgrgid_r(', _UNSAFE_FUNC_PREFIX + r'getgrgid\([^)]+\)'),
1733 ('getgrnam(', 'getgrnam_r(', _UNSAFE_FUNC_PREFIX + r'getgrnam\([^)]+\)'),
1734 ('getlogin(', 'getlogin_r(', _UNSAFE_FUNC_PREFIX + r'getlogin\(\)'),
1735 ('getpwnam(', 'getpwnam_r(', _UNSAFE_FUNC_PREFIX + r'getpwnam\([^)]+\)'),
1736 ('getpwuid(', 'getpwuid_r(', _UNSAFE_FUNC_PREFIX + r'getpwuid\([^)]+\)'),
1737 ('gmtime(', 'gmtime_r(', _UNSAFE_FUNC_PREFIX + r'gmtime\([^)]+\)'),
1738 ('localtime(', 'localtime_r(', _UNSAFE_FUNC_PREFIX + r'localtime\([^)]+\)'),
1739 ('rand(', 'rand_r(', _UNSAFE_FUNC_PREFIX + r'rand\(\)'),
1740 ('strtok(', 'strtok_r(',
1741 _UNSAFE_FUNC_PREFIX + r'strtok\([^)]+\)'),
1742 ('ttyname(', 'ttyname_r(', _UNSAFE_FUNC_PREFIX + r'ttyname\([^)]+\)'),
1566 ) 1743 )
1567 1744
1568 1745
1569 def CheckPosixThreading(filename, clean_lines, linenum, error): 1746 def CheckPosixThreading(filename, clean_lines, linenum, error):
1570 """Checks for calls to thread-unsafe functions. 1747 """Checks for calls to thread-unsafe functions.
1571 1748
1572 Much code has been originally written without consideration of 1749 Much code has been originally written without consideration of
1573 multi-threading. Also, engineers are relying on their old experience; 1750 multi-threading. Also, engineers are relying on their old experience;
1574 they have learned posix before threading extensions were added. These 1751 they have learned posix before threading extensions were added. These
1575 tests guide the engineers to use thread-safe functions (when using 1752 tests guide the engineers to use thread-safe functions (when using
1576 posix directly). 1753 posix directly).
1577 1754
1578 Args: 1755 Args:
1579 filename: The name of the current file. 1756 filename: The name of the current file.
1580 clean_lines: A CleansedLines instance containing the file. 1757 clean_lines: A CleansedLines instance containing the file.
1581 linenum: The number of the line to check. 1758 linenum: The number of the line to check.
1582 error: The function to call with any errors found. 1759 error: The function to call with any errors found.
1583 """ 1760 """
1584 line = clean_lines.elided[linenum] 1761 line = clean_lines.elided[linenum]
1585 for single_thread_function, multithread_safe_function in threading_list: 1762 for single_thread_func, multithread_safe_func, pattern in _THREADING_LIST:
1586 ix = line.find(single_thread_function) 1763 # Additional pattern matching check to confirm that this is the
1587 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-c omparison 1764 # function we are looking for
1588 if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and 1765 if Search(pattern, line):
1589 line[ix - 1] not in ('_', '.', '>'))):
1590 error(filename, linenum, 'runtime/threadsafe_fn', 2, 1766 error(filename, linenum, 'runtime/threadsafe_fn', 2,
1591 'Consider using ' + multithread_safe_function + 1767 'Consider using ' + multithread_safe_func +
1592 '...) instead of ' + single_thread_function + 1768 '...) instead of ' + single_thread_func +
1593 '...) for improved thread safety.') 1769 '...) for improved thread safety.')
1594 1770
1595 1771
1596 def CheckVlogArguments(filename, clean_lines, linenum, error): 1772 def CheckVlogArguments(filename, clean_lines, linenum, error):
1597 """Checks that VLOG() is only used for defining a logging level. 1773 """Checks that VLOG() is only used for defining a logging level.
1598 1774
1599 For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and 1775 For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and
1600 VLOG(FATAL) are not. 1776 VLOG(FATAL) are not.
1601 1777
1602 Args: 1778 Args:
1603 filename: The name of the current file. 1779 filename: The name of the current file.
1604 clean_lines: A CleansedLines instance containing the file. 1780 clean_lines: A CleansedLines instance containing the file.
1605 linenum: The number of the line to check. 1781 linenum: The number of the line to check.
1606 error: The function to call with any errors found. 1782 error: The function to call with any errors found.
1607 """ 1783 """
1608 line = clean_lines.elided[linenum] 1784 line = clean_lines.elided[linenum]
1609 if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line): 1785 if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line):
1610 error(filename, linenum, 'runtime/vlog', 5, 1786 error(filename, linenum, 'runtime/vlog', 5,
1611 'VLOG() should be used with numeric verbosity level. ' 1787 'VLOG() should be used with numeric verbosity level. '
1612 'Use LOG() if you want symbolic severity levels.') 1788 'Use LOG() if you want symbolic severity levels.')
1613 1789
1614
1615 # Matches invalid increment: *count++, which moves pointer instead of 1790 # Matches invalid increment: *count++, which moves pointer instead of
1616 # incrementing a value. 1791 # incrementing a value.
1617 _RE_PATTERN_INVALID_INCREMENT = re.compile( 1792 _RE_PATTERN_INVALID_INCREMENT = re.compile(
1618 r'^\s*\*\w+(\+\+|--);') 1793 r'^\s*\*\w+(\+\+|--);')
1619 1794
1620 1795
1621 def CheckInvalidIncrement(filename, clean_lines, linenum, error): 1796 def CheckInvalidIncrement(filename, clean_lines, linenum, error):
1622 """Checks for invalid increment *count++. 1797 """Checks for invalid increment *count++.
1623 1798
1624 For example following function: 1799 For example following function:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 This is mostly used for checking end of namespace comments. 1844 This is mostly used for checking end of namespace comments.
1670 1845
1671 Args: 1846 Args:
1672 filename: The name of the current file. 1847 filename: The name of the current file.
1673 clean_lines: A CleansedLines instance containing the file. 1848 clean_lines: A CleansedLines instance containing the file.
1674 linenum: The number of the line to check. 1849 linenum: The number of the line to check.
1675 error: The function to call with any errors found. 1850 error: The function to call with any errors found.
1676 """ 1851 """
1677 pass 1852 pass
1678 1853
1854 def IsBlockInfo(self):
1855 """Returns true if this block is a _BlockInfo.
1856
1857 This is convenient for verifying that an object is an instance of
1858 a _BlockInfo, but not an instance of any of the derived classes.
1859
1860 Returns:
1861 True for this class, False for derived classes.
1862 """
1863 return self.__class__ == _BlockInfo
1864
1865
1866 class _ExternCInfo(_BlockInfo):
1867 """Stores information about an 'extern "C"' block."""
1868
1869 def __init__(self):
1870 _BlockInfo.__init__(self, True)
1871
1679 1872
1680 class _ClassInfo(_BlockInfo): 1873 class _ClassInfo(_BlockInfo):
1681 """Stores information about a class.""" 1874 """Stores information about a class."""
1682 1875
1683 def __init__(self, name, class_or_struct, clean_lines, linenum): 1876 def __init__(self, name, class_or_struct, clean_lines, linenum):
1684 _BlockInfo.__init__(self, False) 1877 _BlockInfo.__init__(self, False)
1685 self.name = name 1878 self.name = name
1686 self.starting_linenum = linenum 1879 self.starting_linenum = linenum
1687 self.is_derived = False 1880 self.is_derived = False
1688 if class_or_struct == 'struct': 1881 if class_or_struct == 'struct':
1689 self.access = 'public' 1882 self.access = 'public'
1690 self.is_struct = True 1883 self.is_struct = True
1691 else: 1884 else:
1692 self.access = 'private' 1885 self.access = 'private'
1693 self.is_struct = False 1886 self.is_struct = False
1694 1887
1695 # Remember initial indentation level for this class. Using raw_lines here 1888 # Remember initial indentation level for this class. Using raw_lines here
1696 # instead of elided to account for leading comments. 1889 # instead of elided to account for leading comments.
1697 initial_indent = Match(r'^( *)\S', clean_lines.raw_lines[linenum]) 1890 self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum])
1698 if initial_indent:
1699 self.class_indent = len(initial_indent.group(1))
1700 else:
1701 self.class_indent = 0
1702 1891
1703 # Try to find the end of the class. This will be confused by things like: 1892 # Try to find the end of the class. This will be confused by things like:
1704 # class A { 1893 # class A {
1705 # } *x = { ... 1894 # } *x = { ...
1706 # 1895 #
1707 # But it's still good enough for CheckSectionSpacing. 1896 # But it's still good enough for CheckSectionSpacing.
1708 self.last_line = 0 1897 self.last_line = 0
1709 depth = 0 1898 depth = 0
1710 for i in range(linenum, clean_lines.NumLines()): 1899 for i in range(linenum, clean_lines.NumLines()):
1711 line = clean_lines.elided[i] 1900 line = clean_lines.elided[i]
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1776 # Named namespace 1965 # Named namespace
1777 if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) + 1966 if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) +
1778 r'[\*/\.\\\s]*$'), 1967 r'[\*/\.\\\s]*$'),
1779 line): 1968 line):
1780 error(filename, linenum, 'readability/namespace', 5, 1969 error(filename, linenum, 'readability/namespace', 5,
1781 'Namespace should be terminated with "// namespace %s"' % 1970 'Namespace should be terminated with "// namespace %s"' %
1782 self.name) 1971 self.name)
1783 else: 1972 else:
1784 # Anonymous namespace 1973 # Anonymous namespace
1785 if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): 1974 if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line):
1786 error(filename, linenum, 'readability/namespace', 5, 1975 # If "// namespace anonymous" or "// anonymous namespace (more text)",
1787 'Namespace should be terminated with "// namespace"') 1976 # mention "// anonymous namespace" as an acceptable form
1977 if Match(r'}.*\b(namespace anonymous|anonymous namespace)\b', line):
1978 error(filename, linenum, 'readability/namespace', 5,
1979 'Anonymous namespace should be terminated with "// namespace"'
1980 ' or "// anonymous namespace"')
1981 else:
1982 error(filename, linenum, 'readability/namespace', 5,
1983 'Anonymous namespace should be terminated with "// namespace"')
1788 1984
1789 1985
1790 class _PreprocessorInfo(object): 1986 class _PreprocessorInfo(object):
1791 """Stores checkpoints of nesting stacks when #if/#else is seen.""" 1987 """Stores checkpoints of nesting stacks when #if/#else is seen."""
1792 1988
1793 def __init__(self, stack_before_if): 1989 def __init__(self, stack_before_if):
1794 # The entire nesting stack before #if 1990 # The entire nesting stack before #if
1795 self.stack_before_if = stack_before_if 1991 self.stack_before_if = stack_before_if
1796 1992
1797 # The entire nesting stack up to #else 1993 # The entire nesting stack up to #else
1798 self.stack_before_else = [] 1994 self.stack_before_else = []
1799 1995
1800 # Whether we have already seen #else or #elif 1996 # Whether we have already seen #else or #elif
1801 self.seen_else = False 1997 self.seen_else = False
1802 1998
1803 1999
1804 class _NestingState(object): 2000 class NestingState(object):
1805 """Holds states related to parsing braces.""" 2001 """Holds states related to parsing braces."""
1806 2002
1807 def __init__(self): 2003 def __init__(self):
1808 # Stack for tracking all braces. An object is pushed whenever we 2004 # Stack for tracking all braces. An object is pushed whenever we
1809 # see a "{", and popped when we see a "}". Only 3 types of 2005 # see a "{", and popped when we see a "}". Only 3 types of
1810 # objects are possible: 2006 # objects are possible:
1811 # - _ClassInfo: a class or struct. 2007 # - _ClassInfo: a class or struct.
1812 # - _NamespaceInfo: a namespace. 2008 # - _NamespaceInfo: a namespace.
1813 # - _BlockInfo: some other type of block. 2009 # - _BlockInfo: some other type of block.
1814 self.stack = [] 2010 self.stack = []
1815 2011
2012 # Top of the previous stack before each Update().
2013 #
2014 # Because the nesting_stack is updated at the end of each line, we
2015 # had to do some convoluted checks to find out what is the current
2016 # scope at the beginning of the line. This check is simplified by
2017 # saving the previous top of nesting stack.
2018 #
2019 # We could save the full stack, but we only need the top. Copying
2020 # the full nesting stack would slow down cpplint by ~10%.
2021 self.previous_stack_top = []
2022
1816 # Stack of _PreprocessorInfo objects. 2023 # Stack of _PreprocessorInfo objects.
1817 self.pp_stack = [] 2024 self.pp_stack = []
1818 2025
1819 def SeenOpenBrace(self): 2026 def SeenOpenBrace(self):
1820 """Check if we have seen the opening brace for the innermost block. 2027 """Check if we have seen the opening brace for the innermost block.
1821 2028
1822 Returns: 2029 Returns:
1823 True if we have seen the opening brace, False if the innermost 2030 True if we have seen the opening brace, False if the innermost
1824 block is still expecting an opening brace. 2031 block is still expecting an opening brace.
1825 """ 2032 """
1826 return (not self.stack) or self.stack[-1].seen_open_brace 2033 return (not self.stack) or self.stack[-1].seen_open_brace
1827 2034
1828 def InNamespaceBody(self): 2035 def InNamespaceBody(self):
1829 """Check if we are currently one level inside a namespace body. 2036 """Check if we are currently one level inside a namespace body.
1830 2037
1831 Returns: 2038 Returns:
1832 True if top of the stack is a namespace block, False otherwise. 2039 True if top of the stack is a namespace block, False otherwise.
1833 """ 2040 """
1834 return self.stack and isinstance(self.stack[-1], _NamespaceInfo) 2041 return self.stack and isinstance(self.stack[-1], _NamespaceInfo)
1835 2042
2043 def InExternC(self):
2044 """Check if we are currently one level inside an 'extern "C"' block.
2045
2046 Returns:
2047 True if top of the stack is an extern block, False otherwise.
2048 """
2049 return self.stack and isinstance(self.stack[-1], _ExternCInfo)
2050
2051 def InClassDeclaration(self):
2052 """Check if we are currently one level inside a class or struct declaration.
2053
2054 Returns:
2055 True if top of the stack is a class/struct, False otherwise.
2056 """
2057 return self.stack and isinstance(self.stack[-1], _ClassInfo)
2058
2059 def InAsmBlock(self):
2060 """Check if we are currently one level inside an inline ASM block.
2061
2062 Returns:
2063 True if the top of the stack is a block containing inline ASM.
2064 """
2065 return self.stack and self.stack[-1].inline_asm != _NO_ASM
2066
2067 def InTemplateArgumentList(self, clean_lines, linenum, pos):
2068 """Check if current position is inside template argument list.
2069
2070 Args:
2071 clean_lines: A CleansedLines instance containing the file.
2072 linenum: The number of the line to check.
2073 pos: position just after the suspected template argument.
2074 Returns:
2075 True if (linenum, pos) is inside template arguments.
2076 """
2077 while linenum < clean_lines.NumLines():
2078 # Find the earliest character that might indicate a template argument
2079 line = clean_lines.elided[linenum]
2080 match = Match(r'^[^{};=\[\]\.<>]*(.)', line[pos:])
2081 if not match:
2082 linenum += 1
2083 pos = 0
2084 continue
2085 token = match.group(1)
2086 pos += len(match.group(0))
2087
2088 # These things do not look like template argument list:
2089 # class Suspect {
2090 # class Suspect x; }
2091 if token in ('{', '}', ';'): return False
2092
2093 # These things look like template argument list:
2094 # template <class Suspect>
2095 # template <class Suspect = default_value>
2096 # template <class Suspect[]>
2097 # template <class Suspect...>
2098 if token in ('>', '=', '[', ']', '.'): return True
2099
2100 # Check if token is an unmatched '<'.
2101 # If not, move on to the next character.
2102 if token != '<':
2103 pos += 1
2104 if pos >= len(line):
2105 linenum += 1
2106 pos = 0
2107 continue
2108
2109 # We can't be sure if we just find a single '<', and need to
2110 # find the matching '>'.
2111 (_, end_line, end_pos) = CloseExpression(clean_lines, linenum, pos - 1)
2112 if end_pos < 0:
2113 # Not sure if template argument list or syntax error in file
2114 return False
2115 linenum = end_line
2116 pos = end_pos
2117 return False
2118
1836 def UpdatePreprocessor(self, line): 2119 def UpdatePreprocessor(self, line):
1837 """Update preprocessor stack. 2120 """Update preprocessor stack.
1838 2121
1839 We need to handle preprocessors due to classes like this: 2122 We need to handle preprocessors due to classes like this:
1840 #ifdef SWIG 2123 #ifdef SWIG
1841 struct ResultDetailsPageElementExtensionPoint { 2124 struct ResultDetailsPageElementExtensionPoint {
1842 #else 2125 #else
1843 struct ResultDetailsPageElementExtensionPoint : public Extension { 2126 struct ResultDetailsPageElementExtensionPoint : public Extension {
1844 #endif 2127 #endif
1845 2128
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 if self.pp_stack[-1].seen_else: 2165 if self.pp_stack[-1].seen_else:
1883 # Here we can just use a shallow copy since we are the last 2166 # Here we can just use a shallow copy since we are the last
1884 # reference to it. 2167 # reference to it.
1885 self.stack = self.pp_stack[-1].stack_before_else 2168 self.stack = self.pp_stack[-1].stack_before_else
1886 # Drop the corresponding #if 2169 # Drop the corresponding #if
1887 self.pp_stack.pop() 2170 self.pp_stack.pop()
1888 else: 2171 else:
1889 # TODO(unknown): unexpected #endif, issue warning? 2172 # TODO(unknown): unexpected #endif, issue warning?
1890 pass 2173 pass
1891 2174
2175 # TODO(unknown): Update() is too long, but we will refactor later.
1892 def Update(self, filename, clean_lines, linenum, error): 2176 def Update(self, filename, clean_lines, linenum, error):
1893 """Update nesting state with current line. 2177 """Update nesting state with current line.
1894 2178
1895 Args: 2179 Args:
1896 filename: The name of the current file. 2180 filename: The name of the current file.
1897 clean_lines: A CleansedLines instance containing the file. 2181 clean_lines: A CleansedLines instance containing the file.
1898 linenum: The number of the line to check. 2182 linenum: The number of the line to check.
1899 error: The function to call with any errors found. 2183 error: The function to call with any errors found.
1900 """ 2184 """
1901 line = clean_lines.elided[linenum] 2185 line = clean_lines.elided[linenum]
1902 2186
1903 # Update pp_stack first 2187 # Remember top of the previous nesting stack.
2188 #
2189 # The stack is always pushed/popped and not modified in place, so
2190 # we can just do a shallow copy instead of copy.deepcopy. Using
2191 # deepcopy would slow down cpplint by ~28%.
2192 if self.stack:
2193 self.previous_stack_top = self.stack[-1]
2194 else:
2195 self.previous_stack_top = None
2196
2197 # Update pp_stack
1904 self.UpdatePreprocessor(line) 2198 self.UpdatePreprocessor(line)
1905 2199
1906 # Count parentheses. This is to avoid adding struct arguments to 2200 # Count parentheses. This is to avoid adding struct arguments to
1907 # the nesting stack. 2201 # the nesting stack.
1908 if self.stack: 2202 if self.stack:
1909 inner_block = self.stack[-1] 2203 inner_block = self.stack[-1]
1910 depth_change = line.count('(') - line.count(')') 2204 depth_change = line.count('(') - line.count(')')
1911 inner_block.open_parentheses += depth_change 2205 inner_block.open_parentheses += depth_change
1912 2206
1913 # Also check if we are starting or ending an inline assembly block. 2207 # Also check if we are starting or ending an inline assembly block.
(...skipping 30 matching lines...) Expand all
1944 line = namespace_decl_match.group(2) 2238 line = namespace_decl_match.group(2)
1945 if line.find('{') != -1: 2239 if line.find('{') != -1:
1946 new_namespace.seen_open_brace = True 2240 new_namespace.seen_open_brace = True
1947 line = line[line.find('{') + 1:] 2241 line = line[line.find('{') + 1:]
1948 2242
1949 # Look for a class declaration in whatever is left of the line 2243 # Look for a class declaration in whatever is left of the line
1950 # after parsing namespaces. The regexp accounts for decorated classes 2244 # after parsing namespaces. The regexp accounts for decorated classes
1951 # such as in: 2245 # such as in:
1952 # class LOCKABLE API Object { 2246 # class LOCKABLE API Object {
1953 # }; 2247 # };
1954 #
1955 # Templates with class arguments may confuse the parser, for example:
1956 # template <class T
1957 # class Comparator = less<T>,
1958 # class Vector = vector<T> >
1959 # class HeapQueue {
1960 #
1961 # Because this parser has no nesting state about templates, by the
1962 # time it saw "class Comparator", it may think that it's a new class.
1963 # Nested templates have a similar problem:
1964 # template <
1965 # typename ExportedType,
1966 # typename TupleType,
1967 # template <typename, typename> class ImplTemplate>
1968 #
1969 # To avoid these cases, we ignore classes that are followed by '=' or '>'
1970 class_decl_match = Match( 2248 class_decl_match = Match(
1971 r'\s*(template\s*<[\w\s<>,:]*>\s*)?' 2249 r'^(\s*(?:template\s*<[\w\s<>,:]*>\s*)?'
1972 r'(class|struct)\s+([A-Z_]+\s+)*(\w+(?:::\w+)*)' 2250 r'(class|struct)\s+(?:[A-Z_]+\s+)*(\w+(?:::\w+)*))'
1973 r'(([^=>]|<[^<>]*>|<[^<>]*<[^<>]*>\s*>)*)$', line) 2251 r'(.*)$', line)
1974 if (class_decl_match and 2252 if (class_decl_match and
1975 (not self.stack or self.stack[-1].open_parentheses == 0)): 2253 (not self.stack or self.stack[-1].open_parentheses == 0)):
1976 self.stack.append(_ClassInfo( 2254 # We do not want to accept classes that are actually template arguments:
1977 class_decl_match.group(4), class_decl_match.group(2), 2255 # template <class Ignore1,
1978 clean_lines, linenum)) 2256 # class Ignore2 = Default<Args>,
1979 line = class_decl_match.group(5) 2257 # template <Args> class Ignore3>
2258 # void Function() {};
2259 #
2260 # To avoid template argument cases, we scan forward and look for
2261 # an unmatched '>'. If we see one, assume we are inside a
2262 # template argument list.
2263 end_declaration = len(class_decl_match.group(1))
2264 if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration):
2265 self.stack.append(_ClassInfo(
2266 class_decl_match.group(3), class_decl_match.group(2),
2267 clean_lines, linenum))
2268 line = class_decl_match.group(4)
1980 2269
1981 # If we have not yet seen the opening brace for the innermost block, 2270 # If we have not yet seen the opening brace for the innermost block,
1982 # run checks here. 2271 # run checks here.
1983 if not self.SeenOpenBrace(): 2272 if not self.SeenOpenBrace():
1984 self.stack[-1].CheckBegin(filename, clean_lines, linenum, error) 2273 self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)
1985 2274
1986 # Update access control if we are inside a class/struct 2275 # Update access control if we are inside a class/struct
1987 if self.stack and isinstance(self.stack[-1], _ClassInfo): 2276 if self.stack and isinstance(self.stack[-1], _ClassInfo):
1988 classinfo = self.stack[-1] 2277 classinfo = self.stack[-1]
1989 access_match = Match( 2278 access_match = Match(
(...skipping 26 matching lines...) Expand all
2016 if not matched: 2305 if not matched:
2017 break 2306 break
2018 2307
2019 token = matched.group(1) 2308 token = matched.group(1)
2020 if token == '{': 2309 if token == '{':
2021 # If namespace or class hasn't seen a opening brace yet, mark 2310 # If namespace or class hasn't seen a opening brace yet, mark
2022 # namespace/class head as complete. Push a new block onto the 2311 # namespace/class head as complete. Push a new block onto the
2023 # stack otherwise. 2312 # stack otherwise.
2024 if not self.SeenOpenBrace(): 2313 if not self.SeenOpenBrace():
2025 self.stack[-1].seen_open_brace = True 2314 self.stack[-1].seen_open_brace = True
2315 elif Match(r'^extern\s*"[^"]*"\s*\{', line):
2316 self.stack.append(_ExternCInfo())
2026 else: 2317 else:
2027 self.stack.append(_BlockInfo(True)) 2318 self.stack.append(_BlockInfo(True))
2028 if _MATCH_ASM.match(line): 2319 if _MATCH_ASM.match(line):
2029 self.stack[-1].inline_asm = _BLOCK_ASM 2320 self.stack[-1].inline_asm = _BLOCK_ASM
2321
2030 elif token == ';' or token == ')': 2322 elif token == ';' or token == ')':
2031 # If we haven't seen an opening brace yet, but we already saw 2323 # If we haven't seen an opening brace yet, but we already saw
2032 # a semicolon, this is probably a forward declaration. Pop 2324 # a semicolon, this is probably a forward declaration. Pop
2033 # the stack for these. 2325 # the stack for these.
2034 # 2326 #
2035 # Similarly, if we haven't seen an opening brace yet, but we 2327 # Similarly, if we haven't seen an opening brace yet, but we
2036 # already saw a closing parenthesis, then these are probably 2328 # already saw a closing parenthesis, then these are probably
2037 # function arguments with extra "class" or "struct" keywords. 2329 # function arguments with extra "class" or "struct" keywords.
2038 # Also pop these stack for these. 2330 # Also pop these stack for these.
2039 if not self.SeenOpenBrace(): 2331 if not self.SeenOpenBrace():
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2095 - >? and <? operators, and their >?= and <?= cousins. 2387 - >? and <? operators, and their >?= and <?= cousins.
2096 2388
2097 Additionally, check for constructor/destructor style violations and reference 2389 Additionally, check for constructor/destructor style violations and reference
2098 members, as it is very convenient to do so while checking for 2390 members, as it is very convenient to do so while checking for
2099 gcc-2 compliance. 2391 gcc-2 compliance.
2100 2392
2101 Args: 2393 Args:
2102 filename: The name of the current file. 2394 filename: The name of the current file.
2103 clean_lines: A CleansedLines instance containing the file. 2395 clean_lines: A CleansedLines instance containing the file.
2104 linenum: The number of the line to check. 2396 linenum: The number of the line to check.
2105 nesting_state: A _NestingState instance which maintains information about 2397 nesting_state: A NestingState instance which maintains information about
2106 the current stack of nested blocks being parsed. 2398 the current stack of nested blocks being parsed.
2107 error: A callable to which errors are reported, which takes 4 arguments: 2399 error: A callable to which errors are reported, which takes 4 arguments:
2108 filename, line number, error level, and message 2400 filename, line number, error level, and message
2109 """ 2401 """
2110 2402
2111 # Remove comments from the line, but leave in strings for now. 2403 # Remove comments from the line, but leave in strings for now.
2112 line = clean_lines.lines[linenum] 2404 line = clean_lines.lines[linenum]
2113 2405
2114 if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line): 2406 if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
2115 error(filename, linenum, 'runtime/printf_format', 3, 2407 error(filename, linenum, 'runtime/printf_format', 3,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 # The constructor and destructor will not have those qualifiers. 2465 # The constructor and destructor will not have those qualifiers.
2174 base_classname = classinfo.name.split('::')[-1] 2466 base_classname = classinfo.name.split('::')[-1]
2175 2467
2176 # Look for single-argument constructors that aren't marked explicit. 2468 # Look for single-argument constructors that aren't marked explicit.
2177 # Technically a valid construct, but against style. 2469 # Technically a valid construct, but against style.
2178 args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)' 2470 args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)'
2179 % re.escape(base_classname), 2471 % re.escape(base_classname),
2180 line) 2472 line)
2181 if (args and 2473 if (args and
2182 args.group(1) != 'void' and 2474 args.group(1) != 'void' and
2475 not Search(r'\bstd::initializer_list\b', args.group(1)) and
2183 not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&' 2476 not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&'
2184 % re.escape(base_classname), args.group(1).strip())): 2477 % re.escape(base_classname), args.group(1).strip())):
2185 error(filename, linenum, 'runtime/explicit', 5, 2478 error(filename, linenum, 'runtime/explicit', 5,
2186 'Single-argument constructors should be marked explicit.') 2479 'Single-argument constructors should be marked explicit.')
2187 2480
2188 2481
2189 def CheckSpacingForFunctionCall(filename, line, linenum, error): 2482 def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error):
2190 """Checks for the correctness of various spacing around function calls. 2483 """Checks for the correctness of various spacing around function calls.
2191 2484
2192 Args: 2485 Args:
2193 filename: The name of the current file. 2486 filename: The name of the current file.
2194 line: The text of the line to check. 2487 clean_lines: A CleansedLines instance containing the file.
2195 linenum: The number of the line to check. 2488 linenum: The number of the line to check.
2196 error: The function to call with any errors found. 2489 error: The function to call with any errors found.
2197 """ 2490 """
2491 line = clean_lines.elided[linenum]
2198 2492
2199 # Since function calls often occur inside if/for/while/switch 2493 # Since function calls often occur inside if/for/while/switch
2200 # expressions - which have their own, more liberal conventions - we 2494 # expressions - which have their own, more liberal conventions - we
2201 # first see if we should be looking inside such an expression for a 2495 # first see if we should be looking inside such an expression for a
2202 # function call, to which we can apply more strict standards. 2496 # function call, to which we can apply more strict standards.
2203 fncall = line # if there's no control flow construct, look at whole line 2497 fncall = line # if there's no control flow construct, look at whole line
2204 for pattern in (r'\bif\s*\((.*)\)\s*{', 2498 for pattern in (r'\bif\s*\((.*)\)\s*{',
2205 r'\bfor\s*\((.*)\)\s*{', 2499 r'\bfor\s*\((.*)\)\s*{',
2206 r'\bwhile\s*\((.*)\)\s*[{;]', 2500 r'\bwhile\s*\((.*)\)\s*[{;]',
2207 r'\bswitch\s*\((.*)\)\s*{'): 2501 r'\bswitch\s*\((.*)\)\s*{'):
(...skipping 22 matching lines...) Expand all
2230 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and 2524 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
2231 # Ignore pointers/references to arrays. 2525 # Ignore pointers/references to arrays.
2232 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): 2526 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
2233 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call 2527 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
2234 error(filename, linenum, 'whitespace/parens', 4, 2528 error(filename, linenum, 'whitespace/parens', 4,
2235 'Extra space after ( in function call') 2529 'Extra space after ( in function call')
2236 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): 2530 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
2237 error(filename, linenum, 'whitespace/parens', 2, 2531 error(filename, linenum, 'whitespace/parens', 2,
2238 'Extra space after (') 2532 'Extra space after (')
2239 if (Search(r'\w\s+\(', fncall) and 2533 if (Search(r'\w\s+\(', fncall) and
2240 not Search(r'#\s*define|typedef', fncall) and 2534 not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and
2241 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)): 2535 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)):
2242 error(filename, linenum, 'whitespace/parens', 4, 2536 # TODO(unknown): Space after an operator function seem to be a common
2243 'Extra space before ( in function call') 2537 # error, silence those for now by restricting them to highest verbosity.
2538 if Search(r'\boperator_*\b', line):
2539 error(filename, linenum, 'whitespace/parens', 0,
2540 'Extra space before ( in function call')
2541 else:
2542 error(filename, linenum, 'whitespace/parens', 4,
2543 'Extra space before ( in function call')
2244 # If the ) is followed only by a newline or a { + newline, assume it's 2544 # If the ) is followed only by a newline or a { + newline, assume it's
2245 # part of a control statement (if/while/etc), and don't complain 2545 # part of a control statement (if/while/etc), and don't complain
2246 if Search(r'[^)]\s+\)\s*[^{\s]', fncall): 2546 if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
2247 # If the closing parenthesis is preceded by only whitespaces, 2547 # If the closing parenthesis is preceded by only whitespaces,
2248 # try to give a more descriptive error message. 2548 # try to give a more descriptive error message.
2249 if Search(r'^\s+\)', fncall): 2549 if Search(r'^\s+\)', fncall):
2250 error(filename, linenum, 'whitespace/parens', 2, 2550 error(filename, linenum, 'whitespace/parens', 2,
2251 'Closing ) should be moved to the previous line') 2551 'Closing ) should be moved to the previous line')
2252 else: 2552 else:
2253 error(filename, linenum, 'whitespace/parens', 2, 2553 error(filename, linenum, 'whitespace/parens', 2,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 2587
2288 Args: 2588 Args:
2289 filename: The name of the current file. 2589 filename: The name of the current file.
2290 clean_lines: A CleansedLines instance containing the file. 2590 clean_lines: A CleansedLines instance containing the file.
2291 linenum: The number of the line to check. 2591 linenum: The number of the line to check.
2292 function_state: Current function name and lines in body so far. 2592 function_state: Current function name and lines in body so far.
2293 error: The function to call with any errors found. 2593 error: The function to call with any errors found.
2294 """ 2594 """
2295 lines = clean_lines.lines 2595 lines = clean_lines.lines
2296 line = lines[linenum] 2596 line = lines[linenum]
2297 raw = clean_lines.raw_lines
2298 raw_line = raw[linenum]
2299 joined_line = '' 2597 joined_line = ''
2300 2598
2301 starting_func = False 2599 starting_func = False
2302 regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... 2600 regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ...
2303 match_result = Match(regexp, line) 2601 match_result = Match(regexp, line)
2304 if match_result: 2602 if match_result:
2305 # If the name is all caps and underscores, figure it's a macro and 2603 # If the name is all caps and underscores, figure it's a macro and
2306 # ignore it, unless it's TEST or TEST_F. 2604 # ignore it, unless it's TEST or TEST_F.
2307 function_name = match_result.group(1).split()[-1] 2605 function_name = match_result.group(1).split()[-1]
2308 if function_name == 'TEST' or function_name == 'TEST_F' or ( 2606 if function_name == 'TEST' or function_name == 'TEST_F' or (
(...skipping 26 matching lines...) Expand all
2335 elif Match(r'^\}\s*$', line): # function end 2633 elif Match(r'^\}\s*$', line): # function end
2336 function_state.Check(error, filename, linenum) 2634 function_state.Check(error, filename, linenum)
2337 function_state.End() 2635 function_state.End()
2338 elif not Match(r'^\s*$', line): 2636 elif not Match(r'^\s*$', line):
2339 function_state.Count() # Count non-blank/non-comment lines. 2637 function_state.Count() # Count non-blank/non-comment lines.
2340 2638
2341 2639
2342 _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') 2640 _RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
2343 2641
2344 2642
2345 def CheckComment(comment, filename, linenum, error): 2643 def CheckComment(line, filename, linenum, next_line_start, error):
2346 """Checks for common mistakes in TODO comments. 2644 """Checks for common mistakes in comments.
2347 2645
2348 Args: 2646 Args:
2349 comment: The text of the comment from the line in question. 2647 line: The line in question.
2350 filename: The name of the current file. 2648 filename: The name of the current file.
2351 linenum: The number of the line to check. 2649 linenum: The number of the line to check.
2650 next_line_start: The first non-whitespace column of the next line.
2352 error: The function to call with any errors found. 2651 error: The function to call with any errors found.
2353 """ 2652 """
2354 match = _RE_PATTERN_TODO.match(comment) 2653 commentpos = line.find('//')
2355 if match: 2654 if commentpos != -1:
2356 # One whitespace is correct; zero whitespace is handled elsewhere. 2655 # Check if the // may be in quotes. If so, ignore it
2357 leading_whitespace = match.group(1) 2656 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-c omparison
2358 if len(leading_whitespace) > 1: 2657 if (line.count('"', 0, commentpos) -
2359 error(filename, linenum, 'whitespace/todo', 2, 2658 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
2360 'Too many spaces before TODO') 2659 # Allow one space for new scopes, two spaces otherwise:
2660 if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and
2661 ((commentpos >= 1 and
2662 line[commentpos-1] not in string.whitespace) or
2663 (commentpos >= 2 and
2664 line[commentpos-2] not in string.whitespace))):
2665 error(filename, linenum, 'whitespace/comments', 2,
2666 'At least two spaces is best between code and comments')
2361 2667
2362 username = match.group(2) 2668 # Checks for common mistakes in TODO comments.
2363 if not username: 2669 comment = line[commentpos:]
2364 error(filename, linenum, 'readability/todo', 2, 2670 match = _RE_PATTERN_TODO.match(comment)
2365 'Missing username in TODO; it should look like ' 2671 if match:
2366 '"// TODO(my_username): Stuff."') 2672 # One whitespace is correct; zero whitespace is handled elsewhere.
2673 leading_whitespace = match.group(1)
2674 if len(leading_whitespace) > 1:
2675 error(filename, linenum, 'whitespace/todo', 2,
2676 'Too many spaces before TODO')
2367 2677
2368 middle_whitespace = match.group(3) 2678 username = match.group(2)
2369 # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bo ol-comparison 2679 if not username:
2370 if middle_whitespace != ' ' and middle_whitespace != '': 2680 error(filename, linenum, 'readability/todo', 2,
2371 error(filename, linenum, 'whitespace/todo', 2, 2681 'Missing username in TODO; it should look like '
2372 'TODO(my_username) should be followed by a space') 2682 '"// TODO(my_username): Stuff."')
2683
2684 middle_whitespace = match.group(3)
2685 # Comparisons made explicit for correctness -- pylint: disable=g-explici t-bool-comparison
2686 if middle_whitespace != ' ' and middle_whitespace != '':
2687 error(filename, linenum, 'whitespace/todo', 2,
2688 'TODO(my_username) should be followed by a space')
2689
2690 # If the comment contains an alphanumeric character, there
2691 # should be a space somewhere between it and the //.
2692 if Match(r'//[^ ]*\w', comment):
2693 error(filename, linenum, 'whitespace/comments', 4,
2694 'Should have a space between // and comment')
2373 2695
2374 def CheckAccess(filename, clean_lines, linenum, nesting_state, error): 2696 def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
2375 """Checks for improper use of DISALLOW* macros. 2697 """Checks for improper use of DISALLOW* macros.
2376 2698
2377 Args: 2699 Args:
2378 filename: The name of the current file. 2700 filename: The name of the current file.
2379 clean_lines: A CleansedLines instance containing the file. 2701 clean_lines: A CleansedLines instance containing the file.
2380 linenum: The number of the line to check. 2702 linenum: The number of the line to check.
2381 nesting_state: A _NestingState instance which maintains information about 2703 nesting_state: A NestingState instance which maintains information about
2382 the current stack of nested blocks being parsed. 2704 the current stack of nested blocks being parsed.
2383 error: The function to call with any errors found. 2705 error: The function to call with any errors found.
2384 """ 2706 """
2385 line = clean_lines.elided[linenum] # get rid of comments and strings 2707 line = clean_lines.elided[linenum] # get rid of comments and strings
2386 2708
2387 matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|' 2709 matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|'
2388 r'DISALLOW_EVIL_CONSTRUCTORS|' 2710 r'DISALLOW_EVIL_CONSTRUCTORS|'
2389 r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line) 2711 r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)
2390 if not matched: 2712 if not matched:
2391 return 2713 return
2392 if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo): 2714 if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):
2393 if nesting_state.stack[-1].access != 'private': 2715 if nesting_state.stack[-1].access != 'private':
2394 error(filename, linenum, 'readability/constructors', 3, 2716 error(filename, linenum, 'readability/constructors', 3,
2395 '%s must be in the private: section' % matched.group(1)) 2717 '%s must be in the private: section' % matched.group(1))
2396 2718
2397 else: 2719 else:
2398 # Found DISALLOW* macro outside a class declaration, or perhaps it 2720 # Found DISALLOW* macro outside a class declaration, or perhaps it
2399 # was used inside a function when it should have been part of the 2721 # was used inside a function when it should have been part of the
2400 # class declaration. We could issue a warning here, but it 2722 # class declaration. We could issue a warning here, but it
2401 # probably resulted in a compiler error already. 2723 # probably resulted in a compiler error already.
2402 pass 2724 pass
2403 2725
2404 2726
2405 def FindNextMatchingAngleBracket(clean_lines, linenum, init_suffix):
2406 """Find the corresponding > to close a template.
2407
2408 Args:
2409 clean_lines: A CleansedLines instance containing the file.
2410 linenum: Current line number.
2411 init_suffix: Remainder of the current line after the initial <.
2412
2413 Returns:
2414 True if a matching bracket exists.
2415 """
2416 line = init_suffix
2417 nesting_stack = ['<']
2418 while True:
2419 # Find the next operator that can tell us whether < is used as an
2420 # opening bracket or as a less-than operator. We only want to
2421 # warn on the latter case.
2422 #
2423 # We could also check all other operators and terminate the search
2424 # early, e.g. if we got something like this "a<b+c", the "<" is
2425 # most likely a less-than operator, but then we will get false
2426 # positives for default arguments and other template expressions.
2427 match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line)
2428 if match:
2429 # Found an operator, update nesting stack
2430 operator = match.group(1)
2431 line = match.group(2)
2432
2433 if nesting_stack[-1] == '<':
2434 # Expecting closing angle bracket
2435 if operator in ('<', '(', '['):
2436 nesting_stack.append(operator)
2437 elif operator == '>':
2438 nesting_stack.pop()
2439 if not nesting_stack:
2440 # Found matching angle bracket
2441 return True
2442 elif operator == ',':
2443 # Got a comma after a bracket, this is most likely a template
2444 # argument. We have not seen a closing angle bracket yet, but
2445 # it's probably a few lines later if we look for it, so just
2446 # return early here.
2447 return True
2448 else:
2449 # Got some other operator.
2450 return False
2451
2452 else:
2453 # Expecting closing parenthesis or closing bracket
2454 if operator in ('<', '(', '['):
2455 nesting_stack.append(operator)
2456 elif operator in (')', ']'):
2457 # We don't bother checking for matching () or []. If we got
2458 # something like (] or [), it would have been a syntax error.
2459 nesting_stack.pop()
2460
2461 else:
2462 # Scan the next line
2463 linenum += 1
2464 if linenum >= len(clean_lines.elided):
2465 break
2466 line = clean_lines.elided[linenum]
2467
2468 # Exhausted all remaining lines and still no matching angle bracket.
2469 # Most likely the input was incomplete, otherwise we should have
2470 # seen a semicolon and returned early.
2471 return True
2472
2473
2474 def FindPreviousMatchingAngleBracket(clean_lines, linenum, init_prefix):
2475 """Find the corresponding < that started a template.
2476
2477 Args:
2478 clean_lines: A CleansedLines instance containing the file.
2479 linenum: Current line number.
2480 init_prefix: Part of the current line before the initial >.
2481
2482 Returns:
2483 True if a matching bracket exists.
2484 """
2485 line = init_prefix
2486 nesting_stack = ['>']
2487 while True:
2488 # Find the previous operator
2489 match = Search(r'^(.*)([<>(),;\[\]])[^<>(),;\[\]]*$', line)
2490 if match:
2491 # Found an operator, update nesting stack
2492 operator = match.group(2)
2493 line = match.group(1)
2494
2495 if nesting_stack[-1] == '>':
2496 # Expecting opening angle bracket
2497 if operator in ('>', ')', ']'):
2498 nesting_stack.append(operator)
2499 elif operator == '<':
2500 nesting_stack.pop()
2501 if not nesting_stack:
2502 # Found matching angle bracket
2503 return True
2504 elif operator == ',':
2505 # Got a comma before a bracket, this is most likely a
2506 # template argument. The opening angle bracket is probably
2507 # there if we look for it, so just return early here.
2508 return True
2509 else:
2510 # Got some other operator.
2511 return False
2512
2513 else:
2514 # Expecting opening parenthesis or opening bracket
2515 if operator in ('>', ')', ']'):
2516 nesting_stack.append(operator)
2517 elif operator in ('(', '['):
2518 nesting_stack.pop()
2519
2520 else:
2521 # Scan the previous line
2522 linenum -= 1
2523 if linenum < 0:
2524 break
2525 line = clean_lines.elided[linenum]
2526
2527 # Exhausted all earlier lines and still no matching angle bracket.
2528 return False
2529
2530
2531 def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): 2727 def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
2532 """Checks for the correctness of various spacing issues in the code. 2728 """Checks for the correctness of various spacing issues in the code.
2533 2729
2534 Things we check for: spaces around operators, spaces after 2730 Things we check for: spaces around operators, spaces after
2535 if/for/while/switch, no spaces around parens in function calls, two 2731 if/for/while/switch, no spaces around parens in function calls, two
2536 spaces between code and comment, don't start a block with a blank 2732 spaces between code and comment, don't start a block with a blank
2537 line, don't end a function with a blank line, don't add a blank line 2733 line, don't end a function with a blank line, don't add a blank line
2538 after public/protected/private, don't have too many blank lines in a row. 2734 after public/protected/private, don't have too many blank lines in a row.
2539 2735
2540 Args: 2736 Args:
2541 filename: The name of the current file. 2737 filename: The name of the current file.
2542 clean_lines: A CleansedLines instance containing the file. 2738 clean_lines: A CleansedLines instance containing the file.
2543 linenum: The number of the line to check. 2739 linenum: The number of the line to check.
2544 nesting_state: A _NestingState instance which maintains information about 2740 nesting_state: A NestingState instance which maintains information about
2545 the current stack of nested blocks being parsed. 2741 the current stack of nested blocks being parsed.
2546 error: The function to call with any errors found. 2742 error: The function to call with any errors found.
2547 """ 2743 """
2548 2744
2549 # Don't use "elided" lines here, otherwise we can't check commented lines. 2745 # Don't use "elided" lines here, otherwise we can't check commented lines.
2550 # Don't want to use "raw" either, because we don't want to check inside C++11 2746 # Don't want to use "raw" either, because we don't want to check inside C++11
2551 # raw strings, 2747 # raw strings,
2552 raw = clean_lines.lines_without_raw_strings 2748 raw = clean_lines.lines_without_raw_strings
2553 line = raw[linenum] 2749 line = raw[linenum]
2554 2750
2555 # Before nixing comments, check if the line is blank for no good 2751 # Before nixing comments, check if the line is blank for no good
2556 # reason. This includes the first line after a block is opened, and 2752 # reason. This includes the first line after a block is opened, and
2557 # blank lines at the end of a function (ie, right before a line like '}' 2753 # blank lines at the end of a function (ie, right before a line like '}'
2558 # 2754 #
2559 # Skip all the blank line checks if we are immediately inside a 2755 # Skip all the blank line checks if we are immediately inside a
2560 # namespace body. In other words, don't issue blank line warnings 2756 # namespace body. In other words, don't issue blank line warnings
2561 # for this block: 2757 # for this block:
2562 # namespace { 2758 # namespace {
2563 # 2759 #
2564 # } 2760 # }
2565 # 2761 #
2566 # A warning about missing end of namespace comments will be issued instead. 2762 # A warning about missing end of namespace comments will be issued instead.
2567 if IsBlankLine(line) and not nesting_state.InNamespaceBody(): 2763 #
2764 # Also skip blank line checks for 'extern "C"' blocks, which are formatted
2765 # like namespaces.
2766 if (IsBlankLine(line) and
2767 not nesting_state.InNamespaceBody() and
2768 not nesting_state.InExternC()):
2568 elided = clean_lines.elided 2769 elided = clean_lines.elided
2569 prev_line = elided[linenum - 1] 2770 prev_line = elided[linenum - 1]
2570 prevbrace = prev_line.rfind('{') 2771 prevbrace = prev_line.rfind('{')
2571 # TODO(unknown): Don't complain if line before blank line, and line after, 2772 # TODO(unknown): Don't complain if line before blank line, and line after,
2572 # both start with alnums and are indented the same amount. 2773 # both start with alnums and are indented the same amount.
2573 # This ignores whitespace at the start of a namespace block 2774 # This ignores whitespace at the start of a namespace block
2574 # because those are not usually indented. 2775 # because those are not usually indented.
2575 if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: 2776 if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1:
2576 # OK, we have a blank line at the start of a code block. Before we 2777 # OK, we have a blank line at the start of a code block. Before we
2577 # complain, we check if it is an exception to the rule: The previous 2778 # complain, we check if it is an exception to the rule: The previous
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2620 and next_line.find('} else ') == -1): 2821 and next_line.find('} else ') == -1):
2621 error(filename, linenum, 'whitespace/blank_line', 3, 2822 error(filename, linenum, 'whitespace/blank_line', 3,
2622 'Redundant blank line at the end of a code block ' 2823 'Redundant blank line at the end of a code block '
2623 'should be deleted.') 2824 'should be deleted.')
2624 2825
2625 matched = Match(r'\s*(public|protected|private):', prev_line) 2826 matched = Match(r'\s*(public|protected|private):', prev_line)
2626 if matched: 2827 if matched:
2627 error(filename, linenum, 'whitespace/blank_line', 3, 2828 error(filename, linenum, 'whitespace/blank_line', 3,
2628 'Do not leave a blank line after "%s:"' % matched.group(1)) 2829 'Do not leave a blank line after "%s:"' % matched.group(1))
2629 2830
2630 # Next, we complain if there's a comment too near the text 2831 # Next, check comments
2631 commentpos = line.find('//') 2832 next_line_start = 0
2632 if commentpos != -1: 2833 if linenum + 1 < clean_lines.NumLines():
2633 # Check if the // may be in quotes. If so, ignore it 2834 next_line = raw[linenum + 1]
2634 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-c omparison 2835 next_line_start = len(next_line) - len(next_line.lstrip())
2635 if (line.count('"', 0, commentpos) - 2836 CheckComment(line, filename, linenum, next_line_start, error)
2636 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
2637 # Allow one space for new scopes, two spaces otherwise:
2638 if (not Match(r'^\s*{ //', line) and
2639 ((commentpos >= 1 and
2640 line[commentpos-1] not in string.whitespace) or
2641 (commentpos >= 2 and
2642 line[commentpos-2] not in string.whitespace))):
2643 error(filename, linenum, 'whitespace/comments', 2,
2644 'At least two spaces is best between code and comments')
2645 # There should always be a space between the // and the comment
2646 commentend = commentpos + 2
2647 if commentend < len(line) and not line[commentend] == ' ':
2648 # but some lines are exceptions -- e.g. if they're big
2649 # comment delimiters like:
2650 # //----------------------------------------------------------
2651 # or are an empty C++ style Doxygen comment, like:
2652 # ///
2653 # or C++ style Doxygen comments placed after the variable:
2654 # ///< Header comment
2655 # //!< Header comment
2656 # or they begin with multiple slashes followed by a space:
2657 # //////// Header comment
2658 match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
2659 Search(r'^/$', line[commentend:]) or
2660 Search(r'^!< ', line[commentend:]) or
2661 Search(r'^/< ', line[commentend:]) or
2662 Search(r'^/+ ', line[commentend:]))
2663 if not match:
2664 error(filename, linenum, 'whitespace/comments', 4,
2665 'Should have a space between // and comment')
2666 CheckComment(line[commentpos:], filename, linenum, error)
2667 2837
2668 line = clean_lines.elided[linenum] # get rid of comments and strings 2838 # get rid of comments and strings
2839 line = clean_lines.elided[linenum]
2669 2840
2670 # Don't try to do spacing checks for operator methods 2841 # You shouldn't have spaces before your brackets, except maybe after
2671 line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line) 2842 # 'delete []' or 'return []() {};'
2843 if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line):
2844 error(filename, linenum, 'whitespace/braces', 5,
2845 'Extra space before [')
2846
2847 # In range-based for, we wanted spaces before and after the colon, but
2848 # not around "::" tokens that might appear.
2849 if (Search(r'for *\(.*[^:]:[^: ]', line) or
2850 Search(r'for *\(.*[^: ]:[^:]', line)):
2851 error(filename, linenum, 'whitespace/forcolon', 2,
2852 'Missing space around colon in range-based for loop')
2853
2854
2855 def CheckOperatorSpacing(filename, clean_lines, linenum, error):
2856 """Checks for horizontal spacing around operators.
2857
2858 Args:
2859 filename: The name of the current file.
2860 clean_lines: A CleansedLines instance containing the file.
2861 linenum: The number of the line to check.
2862 error: The function to call with any errors found.
2863 """
2864 line = clean_lines.elided[linenum]
2865
2866 # Don't try to do spacing checks for operator methods. Do this by
2867 # replacing the troublesome characters with something else,
2868 # preserving column position for all other characters.
2869 #
2870 # The replacement is done repeatedly to avoid false positives from
2871 # operators that call operators.
2872 while True:
2873 match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line)
2874 if match:
2875 line = match.group(1) + ('_' * len(match.group(2))) + match.group(3)
2876 else:
2877 break
2672 2878
2673 # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". 2879 # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
2674 # Otherwise not. Note we only check for non-spaces on *both* sides; 2880 # Otherwise not. Note we only check for non-spaces on *both* sides;
2675 # sometimes people put non-spaces on one side when aligning ='s among 2881 # sometimes people put non-spaces on one side when aligning ='s among
2676 # many lines (not that this is behavior that I approve of...) 2882 # many lines (not that this is behavior that I approve of...)
2677 if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): 2883 if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line):
2678 error(filename, linenum, 'whitespace/operators', 4, 2884 error(filename, linenum, 'whitespace/operators', 4,
2679 'Missing spaces around =') 2885 'Missing spaces around =')
2680 2886
2681 # It's ok not to have spaces around binary operators like + - * /, but if 2887 # It's ok not to have spaces around binary operators like + - * /, but if
2682 # there's too little whitespace, we get concerned. It's hard to tell, 2888 # there's too little whitespace, we get concerned. It's hard to tell,
2683 # though, so we punt on this one for now. TODO. 2889 # though, so we punt on this one for now. TODO.
2684 2890
2685 # You should always have whitespace around binary operators. 2891 # You should always have whitespace around binary operators.
2686 # 2892 #
2687 # Check <= and >= first to avoid false positives with < and >, then 2893 # Check <= and >= first to avoid false positives with < and >, then
2688 # check non-include lines for spacing around < and >. 2894 # check non-include lines for spacing around < and >.
2689 match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line) 2895 #
2896 # If the operator is followed by a comma, assume it's be used in a
2897 # macro context and don't do any checks. This avoids false
2898 # positives.
2899 #
2900 # Note that && is not included here. Those are checked separately
2901 # in CheckRValueReference
2902 match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line)
2690 if match: 2903 if match:
2691 error(filename, linenum, 'whitespace/operators', 3, 2904 error(filename, linenum, 'whitespace/operators', 3,
2692 'Missing spaces around %s' % match.group(1)) 2905 'Missing spaces around %s' % match.group(1))
2906 elif not Match(r'#.*include', line):
2907 # Look for < that is not surrounded by spaces. This is only
2908 # triggered if both sides are missing spaces, even though
2909 # technically should should flag if at least one side is missing a
2910 # space. This is done to avoid some false positives with shifts.
2911 match = Match(r'^(.*[^\s<])<[^\s=<,]', line)
2912 if match:
2913 (_, _, end_pos) = CloseExpression(
2914 clean_lines, linenum, len(match.group(1)))
2915 if end_pos <= -1:
2916 error(filename, linenum, 'whitespace/operators', 3,
2917 'Missing spaces around <')
2918
2919 # Look for > that is not surrounded by spaces. Similar to the
2920 # above, we only trigger if both sides are missing spaces to avoid
2921 # false positives with shifts.
2922 match = Match(r'^(.*[^-\s>])>[^\s=>,]', line)
2923 if match:
2924 (_, _, start_pos) = ReverseCloseExpression(
2925 clean_lines, linenum, len(match.group(1)))
2926 if start_pos <= -1:
2927 error(filename, linenum, 'whitespace/operators', 3,
2928 'Missing spaces around >')
2929
2693 # We allow no-spaces around << when used like this: 10<<20, but 2930 # We allow no-spaces around << when used like this: 10<<20, but
2694 # not otherwise (particularly, not when used as streams) 2931 # not otherwise (particularly, not when used as streams)
2695 # Also ignore using ns::operator<<; 2932 # We also allow operators following an opening parenthesis, since
2696 match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<(\S)', line) 2933 # those tend to be macros that deal with operators.
2697 if (match and 2934 match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<([^\s,=])', line)
2935 if (match and match.group(1) != '(' and
2698 not (match.group(1).isdigit() and match.group(2).isdigit()) and 2936 not (match.group(1).isdigit() and match.group(2).isdigit()) and
2699 not (match.group(1) == 'operator' and match.group(2) == ';')): 2937 not (match.group(1) == 'operator' and match.group(2) == ';')):
2700 error(filename, linenum, 'whitespace/operators', 3, 2938 error(filename, linenum, 'whitespace/operators', 3,
2701 'Missing spaces around <<') 2939 'Missing spaces around <<')
2702 elif not Match(r'#.*include', line):
2703 # Avoid false positives on ->
2704 reduced_line = line.replace('->', '')
2705
2706 # Look for < that is not surrounded by spaces. This is only
2707 # triggered if both sides are missing spaces, even though
2708 # technically should should flag if at least one side is missing a
2709 # space. This is done to avoid some false positives with shifts.
2710 match = Search(r'[^\s<]<([^\s=<].*)', reduced_line)
2711 if (match and
2712 not FindNextMatchingAngleBracket(clean_lines, linenum, match.group(1))):
2713 error(filename, linenum, 'whitespace/operators', 3,
2714 'Missing spaces around <')
2715
2716 # Look for > that is not surrounded by spaces. Similar to the
2717 # above, we only trigger if both sides are missing spaces to avoid
2718 # false positives with shifts.
2719 match = Search(r'^(.*[^\s>])>[^\s=>]', reduced_line)
2720 if (match and
2721 not FindPreviousMatchingAngleBracket(clean_lines, linenum,
2722 match.group(1))):
2723 error(filename, linenum, 'whitespace/operators', 3,
2724 'Missing spaces around >')
2725 2940
2726 # We allow no-spaces around >> for almost anything. This is because 2941 # We allow no-spaces around >> for almost anything. This is because
2727 # C++11 allows ">>" to close nested templates, which accounts for 2942 # C++11 allows ">>" to close nested templates, which accounts for
2728 # most cases when ">>" is not followed by a space. 2943 # most cases when ">>" is not followed by a space.
2729 # 2944 #
2730 # We still warn on ">>" followed by alpha character, because that is 2945 # We still warn on ">>" followed by alpha character, because that is
2731 # likely due to ">>" being used for right shifts, e.g.: 2946 # likely due to ">>" being used for right shifts, e.g.:
2732 # value >> alpha 2947 # value >> alpha
2733 # 2948 #
2734 # When ">>" is used to close templates, the alphanumeric letter that 2949 # When ">>" is used to close templates, the alphanumeric letter that
2735 # follows would be part of an identifier, and there should still be 2950 # follows would be part of an identifier, and there should still be
2736 # a space separating the template type and the identifier. 2951 # a space separating the template type and the identifier.
2737 # type<type<type>> alpha 2952 # type<type<type>> alpha
2738 match = Search(r'>>[a-zA-Z_]', line) 2953 match = Search(r'>>[a-zA-Z_]', line)
2739 if match: 2954 if match:
2740 error(filename, linenum, 'whitespace/operators', 3, 2955 error(filename, linenum, 'whitespace/operators', 3,
2741 'Missing spaces around >>') 2956 'Missing spaces around >>')
2742 2957
2743 # There shouldn't be space around unary operators 2958 # There shouldn't be space around unary operators
2744 match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) 2959 match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
2745 if match: 2960 if match:
2746 error(filename, linenum, 'whitespace/operators', 4, 2961 error(filename, linenum, 'whitespace/operators', 4,
2747 'Extra space for operator %s' % match.group(1)) 2962 'Extra space for operator %s' % match.group(1))
2748 2963
2749 # A pet peeve of mine: no spaces after an if, while, switch, or for 2964
2965 def CheckParenthesisSpacing(filename, clean_lines, linenum, error):
2966 """Checks for horizontal spacing around parentheses.
2967
2968 Args:
2969 filename: The name of the current file.
2970 clean_lines: A CleansedLines instance containing the file.
2971 linenum: The number of the line to check.
2972 error: The function to call with any errors found.
2973 """
2974 line = clean_lines.elided[linenum]
2975
2976 # No spaces after an if, while, switch, or for
2750 match = Search(r' (if\(|for\(|while\(|switch\()', line) 2977 match = Search(r' (if\(|for\(|while\(|switch\()', line)
2751 if match: 2978 if match:
2752 error(filename, linenum, 'whitespace/parens', 5, 2979 error(filename, linenum, 'whitespace/parens', 5,
2753 'Missing space before ( in %s' % match.group(1)) 2980 'Missing space before ( in %s' % match.group(1))
2754 2981
2755 # For if/for/while/switch, the left and right parens should be 2982 # For if/for/while/switch, the left and right parens should be
2756 # consistent about how many spaces are inside the parens, and 2983 # consistent about how many spaces are inside the parens, and
2757 # there should either be zero or one spaces inside the parens. 2984 # there should either be zero or one spaces inside the parens.
2758 # We don't want: "if ( foo)" or "if ( foo )". 2985 # We don't want: "if ( foo)" or "if ( foo )".
2759 # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. 2986 # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
2760 match = Search(r'\b(if|for|while|switch)\s*' 2987 match = Search(r'\b(if|for|while|switch)\s*'
2761 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', 2988 r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
2762 line) 2989 line)
2763 if match: 2990 if match:
2764 if len(match.group(2)) != len(match.group(4)): 2991 if len(match.group(2)) != len(match.group(4)):
2765 if not (match.group(3) == ';' and 2992 if not (match.group(3) == ';' and
2766 len(match.group(2)) == 1 + len(match.group(4)) or 2993 len(match.group(2)) == 1 + len(match.group(4)) or
2767 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): 2994 not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
2768 error(filename, linenum, 'whitespace/parens', 5, 2995 error(filename, linenum, 'whitespace/parens', 5,
2769 'Mismatching spaces inside () in %s' % match.group(1)) 2996 'Mismatching spaces inside () in %s' % match.group(1))
2770 if len(match.group(2)) not in [0, 1]: 2997 if len(match.group(2)) not in [0, 1]:
2771 error(filename, linenum, 'whitespace/parens', 5, 2998 error(filename, linenum, 'whitespace/parens', 5,
2772 'Should have zero or one spaces inside ( and ) in %s' % 2999 'Should have zero or one spaces inside ( and ) in %s' %
2773 match.group(1)) 3000 match.group(1))
2774 3001
3002
3003 def CheckCommaSpacing(filename, clean_lines, linenum, error):
3004 """Checks for horizontal spacing near commas and semicolons.
3005
3006 Args:
3007 filename: The name of the current file.
3008 clean_lines: A CleansedLines instance containing the file.
3009 linenum: The number of the line to check.
3010 error: The function to call with any errors found.
3011 """
3012 raw = clean_lines.lines_without_raw_strings
3013 line = clean_lines.elided[linenum]
3014
2775 # You should always have a space after a comma (either as fn arg or operator) 3015 # You should always have a space after a comma (either as fn arg or operator)
2776 # 3016 #
2777 # This does not apply when the non-space character following the 3017 # This does not apply when the non-space character following the
2778 # comma is another comma, since the only time when that happens is 3018 # comma is another comma, since the only time when that happens is
2779 # for empty macro arguments. 3019 # for empty macro arguments.
2780 # 3020 #
2781 # We run this check in two passes: first pass on elided lines to 3021 # We run this check in two passes: first pass on elided lines to
2782 # verify that lines contain missing whitespaces, second pass on raw 3022 # verify that lines contain missing whitespaces, second pass on raw
2783 # lines to confirm that those missing whitespaces are not due to 3023 # lines to confirm that those missing whitespaces are not due to
2784 # elided comments. 3024 # elided comments.
2785 if Search(r',[^,\s]', line) and Search(r',[^,\s]', raw[linenum]): 3025 if Search(r',[^,\s]', line) and Search(r',[^,\s]', raw[linenum]):
2786 error(filename, linenum, 'whitespace/comma', 3, 3026 error(filename, linenum, 'whitespace/comma', 3,
2787 'Missing space after ,') 3027 'Missing space after ,')
2788 3028
2789 # You should always have a space after a semicolon 3029 # You should always have a space after a semicolon
2790 # except for few corner cases 3030 # except for few corner cases
2791 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more 3031 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more
2792 # space after ; 3032 # space after ;
2793 if Search(r';[^\s};\\)/]', line): 3033 if Search(r';[^\s};\\)/]', line):
2794 error(filename, linenum, 'whitespace/semicolon', 3, 3034 error(filename, linenum, 'whitespace/semicolon', 3,
2795 'Missing space after ;') 3035 'Missing space after ;')
2796 3036
2797 # Next we will look for issues with function calls. 3037
2798 CheckSpacingForFunctionCall(filename, line, linenum, error) 3038 def CheckBracesSpacing(filename, clean_lines, linenum, error):
3039 """Checks for horizontal spacing near commas.
3040
3041 Args:
3042 filename: The name of the current file.
3043 clean_lines: A CleansedLines instance containing the file.
3044 linenum: The number of the line to check.
3045 error: The function to call with any errors found.
3046 """
3047 line = clean_lines.elided[linenum]
2799 3048
2800 # Except after an opening paren, or after another opening brace (in case of 3049 # Except after an opening paren, or after another opening brace (in case of
2801 # an initializer list, for instance), you should have spaces before your 3050 # an initializer list, for instance), you should have spaces before your
2802 # braces. And since you should never have braces at the beginning of a line, 3051 # braces. And since you should never have braces at the beginning of a line,
2803 # this is an easy test. 3052 # this is an easy test.
2804 match = Match(r'^(.*[^ ({]){', line) 3053 match = Match(r'^(.*[^ ({]){', line)
2805 if match: 3054 if match:
2806 # Try a bit harder to check for brace initialization. This 3055 # Try a bit harder to check for brace initialization. This
2807 # happens in one of the following forms: 3056 # happens in one of the following forms:
2808 # Constructor() : initializer_list_{} { ... } 3057 # Constructor() : initializer_list_{} { ... }
2809 # Constructor{}.MemberFunction() 3058 # Constructor{}.MemberFunction()
2810 # Type variable{}; 3059 # Type variable{};
2811 # FunctionCall(type{}, ...); 3060 # FunctionCall(type{}, ...);
2812 # LastArgument(..., type{}); 3061 # LastArgument(..., type{});
2813 # LOG(INFO) << type{} << " ..."; 3062 # LOG(INFO) << type{} << " ...";
2814 # map_of_type[{...}] = ...; 3063 # map_of_type[{...}] = ...;
3064 # ternary = expr ? new type{} : nullptr;
3065 # OuterTemplate<InnerTemplateConstructor<Type>{}>
2815 # 3066 #
2816 # We check for the character following the closing brace, and 3067 # We check for the character following the closing brace, and
2817 # silence the warning if it's one of those listed above, i.e. 3068 # silence the warning if it's one of those listed above, i.e.
2818 # "{.;,)<]". 3069 # "{.;,)<>]:".
2819 # 3070 #
2820 # To account for nested initializer list, we allow any number of 3071 # To account for nested initializer list, we allow any number of
2821 # closing braces up to "{;,)<". We can't simply silence the 3072 # closing braces up to "{;,)<". We can't simply silence the
2822 # warning on first sight of closing brace, because that would 3073 # warning on first sight of closing brace, because that would
2823 # cause false negatives for things that are not initializer lists. 3074 # cause false negatives for things that are not initializer lists.
2824 # Silence this: But not this: 3075 # Silence this: But not this:
2825 # Outer{ if (...) { 3076 # Outer{ if (...) {
2826 # Inner{...} if (...){ // Missing space before { 3077 # Inner{...} if (...){ // Missing space before {
2827 # }; } 3078 # }; }
2828 # 3079 #
2829 # There is a false negative with this approach if people inserted 3080 # There is a false negative with this approach if people inserted
2830 # spurious semicolons, e.g. "if (cond){};", but we will catch the 3081 # spurious semicolons, e.g. "if (cond){};", but we will catch the
2831 # spurious semicolon with a separate check. 3082 # spurious semicolon with a separate check.
2832 (endline, endlinenum, endpos) = CloseExpression( 3083 (endline, endlinenum, endpos) = CloseExpression(
2833 clean_lines, linenum, len(match.group(1))) 3084 clean_lines, linenum, len(match.group(1)))
2834 trailing_text = '' 3085 trailing_text = ''
2835 if endpos > -1: 3086 if endpos > -1:
2836 trailing_text = endline[endpos:] 3087 trailing_text = endline[endpos:]
2837 for offset in xrange(endlinenum + 1, 3088 for offset in xrange(endlinenum + 1,
2838 min(endlinenum + 3, clean_lines.NumLines() - 1)): 3089 min(endlinenum + 3, clean_lines.NumLines() - 1)):
2839 trailing_text += clean_lines.elided[offset] 3090 trailing_text += clean_lines.elided[offset]
2840 if not Match(r'^[\s}]*[{.;,)<\]]', trailing_text): 3091 if not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text):
2841 error(filename, linenum, 'whitespace/braces', 5, 3092 error(filename, linenum, 'whitespace/braces', 5,
2842 'Missing space before {') 3093 'Missing space before {')
2843 3094
2844 # Make sure '} else {' has spaces. 3095 # Make sure '} else {' has spaces.
2845 if Search(r'}else', line): 3096 if Search(r'}else', line):
2846 error(filename, linenum, 'whitespace/braces', 5, 3097 error(filename, linenum, 'whitespace/braces', 5,
2847 'Missing space before else') 3098 'Missing space before else')
2848 3099
2849 # You shouldn't have spaces before your brackets, except maybe after
2850 # 'delete []' or 'new char * []'.
2851 if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
2852 error(filename, linenum, 'whitespace/braces', 5,
2853 'Extra space before [')
2854
2855 # You shouldn't have a space before a semicolon at the end of the line. 3100 # You shouldn't have a space before a semicolon at the end of the line.
2856 # There's a special case for "for" since the style guide allows space before 3101 # There's a special case for "for" since the style guide allows space before
2857 # the semicolon there. 3102 # the semicolon there.
2858 if Search(r':\s*;\s*$', line): 3103 if Search(r':\s*;\s*$', line):
2859 error(filename, linenum, 'whitespace/semicolon', 5, 3104 error(filename, linenum, 'whitespace/semicolon', 5,
2860 'Semicolon defining empty statement. Use {} instead.') 3105 'Semicolon defining empty statement. Use {} instead.')
2861 elif Search(r'^\s*;\s*$', line): 3106 elif Search(r'^\s*;\s*$', line):
2862 error(filename, linenum, 'whitespace/semicolon', 5, 3107 error(filename, linenum, 'whitespace/semicolon', 5,
2863 'Line contains only semicolon. If this should be an empty statement, ' 3108 'Line contains only semicolon. If this should be an empty statement, '
2864 'use {} instead.') 3109 'use {} instead.')
2865 elif (Search(r'\s+;\s*$', line) and 3110 elif (Search(r'\s+;\s*$', line) and
2866 not Search(r'\bfor\b', line)): 3111 not Search(r'\bfor\b', line)):
2867 error(filename, linenum, 'whitespace/semicolon', 5, 3112 error(filename, linenum, 'whitespace/semicolon', 5,
2868 'Extra space before last semicolon. If this should be an empty ' 3113 'Extra space before last semicolon. If this should be an empty '
2869 'statement, use {} instead.') 3114 'statement, use {} instead.')
2870 3115
2871 # In range-based for, we wanted spaces before and after the colon, but 3116
2872 # not around "::" tokens that might appear. 3117 def IsDecltype(clean_lines, linenum, column):
2873 if (Search('for *\(.*[^:]:[^: ]', line) or 3118 """Check if the token ending on (linenum, column) is decltype().
2874 Search('for *\(.*[^: ]:[^:]', line)): 3119
2875 error(filename, linenum, 'whitespace/forcolon', 2, 3120 Args:
2876 'Missing space around colon in range-based for loop') 3121 clean_lines: A CleansedLines instance containing the file.
3122 linenum: the number of the line to check.
3123 column: end column of the token to check.
3124 Returns:
3125 True if this token is decltype() expression, False otherwise.
3126 """
3127 (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column)
3128 if start_col < 0:
3129 return False
3130 if Search(r'\bdecltype\s*$', text[0:start_col]):
3131 return True
3132 return False
3133
3134
3135 def IsTemplateParameterList(clean_lines, linenum, column):
3136 """Check if the token ending on (linenum, column) is the end of template<>.
3137
3138 Args:
3139 clean_lines: A CleansedLines instance containing the file.
3140 linenum: the number of the line to check.
3141 column: end column of the token to check.
3142 Returns:
3143 True if this token is end of a template parameter list, False otherwise.
3144 """
3145 (_, startline, startpos) = ReverseCloseExpression(
3146 clean_lines, linenum, column)
3147 if (startpos > -1 and
3148 Search(r'\btemplate\s*$', clean_lines.elided[startline][0:startpos])):
3149 return True
3150 return False
3151
3152
3153 def IsRValueType(clean_lines, nesting_state, linenum, column):
3154 """Check if the token ending on (linenum, column) is a type.
3155
3156 Assumes that text to the right of the column is "&&" or a function
3157 name.
3158
3159 Args:
3160 clean_lines: A CleansedLines instance containing the file.
3161 nesting_state: A NestingState instance which maintains information about
3162 the current stack of nested blocks being parsed.
3163 linenum: the number of the line to check.
3164 column: end column of the token to check.
3165 Returns:
3166 True if this token is a type, False if we are not sure.
3167 """
3168 prefix = clean_lines.elided[linenum][0:column]
3169
3170 # Get one word to the left. If we failed to do so, this is most
3171 # likely not a type, since it's unlikely that the type name and "&&"
3172 # would be split across multiple lines.
3173 match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix)
3174 if not match:
3175 return False
3176
3177 # Check text following the token. If it's "&&>" or "&&," or "&&...", it's
3178 # most likely a rvalue reference used inside a template.
3179 suffix = clean_lines.elided[linenum][column:]
3180 if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix):
3181 return True
3182
3183 # Check for simple type and end of templates:
3184 # int&& variable
3185 # vector<int>&& variable
3186 #
3187 # Because this function is called recursively, we also need to
3188 # recognize pointer and reference types:
3189 # int* Function()
3190 # int& Function()
3191 if match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool',
3192 'short', 'int', 'long', 'signed', 'unsigned',
3193 'float', 'double', 'void', 'auto', '>', '*', '&']:
3194 return True
3195
3196 # If we see a close parenthesis, look for decltype on the other side.
3197 # decltype would unambiguously identify a type, anything else is
3198 # probably a parenthesized expression and not a type.
3199 if match.group(2) == ')':
3200 return IsDecltype(
3201 clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1)
3202
3203 # Check for casts and cv-qualifiers.
3204 # match.group(1) remainder
3205 # -------------- ---------
3206 # const_cast< type&&
3207 # const type&&
3208 # type const&&
3209 if Search(r'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|'
3210 r'reinterpret_cast\s*<|\w+\s)\s*$',
3211 match.group(1)):
3212 return True
3213
3214 # Look for a preceding symbol that might help differentiate the context.
3215 # These are the cases that would be ambiguous:
3216 # match.group(1) remainder
3217 # -------------- ---------
3218 # Call ( expression &&
3219 # Declaration ( type&&
3220 # sizeof ( type&&
3221 # if ( expression &&
3222 # while ( expression &&
3223 # for ( type&&
3224 # for( ; expression &&
3225 # statement ; type&&
3226 # block { type&&
3227 # constructor { expression &&
3228 start = linenum
3229 line = match.group(1)
3230 match_symbol = None
3231 while start >= 0:
3232 # We want to skip over identifiers and commas to get to a symbol.
3233 # Commas are skipped so that we can find the opening parenthesis
3234 # for function parameter lists.
3235 match_symbol = Match(r'^(.*)([^\w\s,])[\w\s,]*$', line)
3236 if match_symbol:
3237 break
3238 start -= 1
3239 line = clean_lines.elided[start]
3240
3241 if not match_symbol:
3242 # Probably the first statement in the file is an rvalue reference
3243 return True
3244
3245 if match_symbol.group(2) == '}':
3246 # Found closing brace, probably an indicate of this:
3247 # block{} type&&
3248 return True
3249
3250 if match_symbol.group(2) == ';':
3251 # Found semicolon, probably one of these:
3252 # for(; expression &&
3253 # statement; type&&
3254
3255 # Look for the previous 'for(' in the previous lines.
3256 before_text = match_symbol.group(1)
3257 for i in xrange(start - 1, max(start - 6, 0), -1):
3258 before_text = clean_lines.elided[i] + before_text
3259 if Search(r'for\s*\([^{};]*$', before_text):
3260 # This is the condition inside a for-loop
3261 return False
3262
3263 # Did not find a for-init-statement before this semicolon, so this
3264 # is probably a new statement and not a condition.
3265 return True
3266
3267 if match_symbol.group(2) == '{':
3268 # Found opening brace, probably one of these:
3269 # block{ type&& = ... ; }
3270 # constructor{ expression && expression }
3271
3272 # Look for a closing brace or a semicolon. If we see a semicolon
3273 # first, this is probably a rvalue reference.
3274 line = clean_lines.elided[start][0:len(match_symbol.group(1)) + 1]
3275 end = start
3276 depth = 1
3277 while True:
3278 for ch in line:
3279 if ch == ';':
3280 return True
3281 elif ch == '{':
3282 depth += 1
3283 elif ch == '}':
3284 depth -= 1
3285 if depth == 0:
3286 return False
3287 end += 1
3288 if end >= clean_lines.NumLines():
3289 break
3290 line = clean_lines.elided[end]
3291 # Incomplete program?
3292 return False
3293
3294 if match_symbol.group(2) == '(':
3295 # Opening parenthesis. Need to check what's to the left of the
3296 # parenthesis. Look back one extra line for additional context.
3297 before_text = match_symbol.group(1)
3298 if linenum > 1:
3299 before_text = clean_lines.elided[linenum - 1] + before_text
3300 before_text = match_symbol.group(1)
3301
3302 # Patterns that are likely to be types:
3303 # [](type&&
3304 # for (type&&
3305 # sizeof(type&&
3306 # operator=(type&&
3307 #
3308 if Search(r'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$', before_text):
3309 return True
3310
3311 # Patterns that are likely to be expressions:
3312 # if (expression &&
3313 # while (expression &&
3314 # : initializer(expression &&
3315 # , initializer(expression &&
3316 # ( FunctionCall(expression &&
3317 # + FunctionCall(expression &&
3318 # + (expression &&
3319 #
3320 # The last '+' represents operators such as '+' and '-'.
3321 if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text):
3322 return False
3323
3324 # Something else. Check that tokens to the left look like
3325 # return_type function_name
3326 match_func = Match(r'^(.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$',
3327 match_symbol.group(1))
3328 if match_func:
3329 # Check for constructors, which don't have return types.
3330 if Search(r'\bexplicit$', match_func.group(1)):
3331 return True
3332 implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix)
3333 if (implicit_constructor and
3334 implicit_constructor.group(1) == implicit_constructor.group(2)):
3335 return True
3336 return IsRValueType(clean_lines, nesting_state, linenum,
3337 len(match_func.group(1)))
3338
3339 # Nothing before the function name. If this is inside a block scope,
3340 # this is probably a function call.
3341 return not (nesting_state.previous_stack_top and
3342 nesting_state.previous_stack_top.IsBlockInfo())
3343
3344 if match_symbol.group(2) == '>':
3345 # Possibly a closing bracket, check that what's on the other side
3346 # looks like the start of a template.
3347 return IsTemplateParameterList(
3348 clean_lines, start, len(match_symbol.group(1)))
3349
3350 # Some other symbol, usually something like "a=b&&c". This is most
3351 # likely not a type.
3352 return False
3353
3354
3355 def IsRValueAllowed(clean_lines, linenum):
3356 """Check if RValue reference is allowed within some range of lines.
3357
3358 Args:
3359 clean_lines: A CleansedLines instance containing the file.
3360 linenum: The number of the line to check.
3361 Returns:
3362 True if line is within the region where RValue references are allowed.
3363 """
3364 for i in xrange(linenum, 0, -1):
3365 line = clean_lines.elided[i]
3366 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line):
3367 if not line.endswith('PUSH'):
3368 return False
3369 for j in xrange(linenum, clean_lines.NumLines(), 1):
3370 line = clean_lines.elided[j]
3371 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line):
3372 return line.endswith('POP')
3373 return False
3374
3375
3376 def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error):
3377 """Check for rvalue references.
3378
3379 Args:
3380 filename: The name of the current file.
3381 clean_lines: A CleansedLines instance containing the file.
3382 linenum: The number of the line to check.
3383 nesting_state: A NestingState instance which maintains information about
3384 the current stack of nested blocks being parsed.
3385 error: The function to call with any errors found.
3386 """
3387 # Find lines missing spaces around &&.
3388 # TODO(unknown): currently we don't check for rvalue references
3389 # with spaces surrounding the && to avoid false positives with
3390 # boolean expressions.
3391 line = clean_lines.elided[linenum]
3392 match = Match(r'^(.*\S)&&', line)
3393 if not match:
3394 match = Match(r'(.*)&&\S', line)
3395 if (not match) or '(&&)' in line or Search(r'\boperator\s*$', match.group(1)):
3396 return
3397
3398 # Either poorly formed && or an rvalue reference, check the context
3399 # to get a more accurate error message. Mostly we want to determine
3400 # if what's to the left of "&&" is a type or not.
3401 and_pos = len(match.group(1))
3402 if IsRValueType(clean_lines, nesting_state, linenum, and_pos):
3403 if not IsRValueAllowed(clean_lines, linenum):
3404 error(filename, linenum, 'build/c++11', 3,
3405 'RValue references are an unapproved C++ feature.')
3406 else:
3407 error(filename, linenum, 'whitespace/operators', 3,
3408 'Missing spaces around &&')
2877 3409
2878 3410
2879 def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): 3411 def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
2880 """Checks for additional blank line issues related to sections. 3412 """Checks for additional blank line issues related to sections.
2881 3413
2882 Currently the only thing checked here is blank line before protected/private. 3414 Currently the only thing checked here is blank line before protected/private.
2883 3415
2884 Args: 3416 Args:
2885 filename: The name of the current file. 3417 filename: The name of the current file.
2886 clean_lines: A CleansedLines instance containing the file. 3418 clean_lines: A CleansedLines instance containing the file.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2974 # perfectly: we just don't complain if the last non-whitespace character on 3506 # perfectly: we just don't complain if the last non-whitespace character on
2975 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the 3507 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the
2976 # previous line starts a preprocessor block. 3508 # previous line starts a preprocessor block.
2977 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 3509 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
2978 if (not Search(r'[,;:}{(]\s*$', prevline) and 3510 if (not Search(r'[,;:}{(]\s*$', prevline) and
2979 not Match(r'\s*#', prevline)): 3511 not Match(r'\s*#', prevline)):
2980 error(filename, linenum, 'whitespace/braces', 4, 3512 error(filename, linenum, 'whitespace/braces', 4,
2981 '{ should almost always be at the end of the previous line') 3513 '{ should almost always be at the end of the previous line')
2982 3514
2983 # An else clause should be on the same line as the preceding closing brace. 3515 # An else clause should be on the same line as the preceding closing brace.
2984 if Match(r'\s*else\s*', line): 3516 if Match(r'\s*else\b\s*(?:if\b|\{|$)', line):
2985 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] 3517 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
2986 if Match(r'\s*}\s*$', prevline): 3518 if Match(r'\s*}\s*$', prevline):
2987 error(filename, linenum, 'whitespace/newline', 4, 3519 error(filename, linenum, 'whitespace/newline', 4,
2988 'An else should appear on the same line as the preceding }') 3520 'An else should appear on the same line as the preceding }')
2989 3521
2990 # If braces come on one side of an else, they should be on both. 3522 # If braces come on one side of an else, they should be on both.
2991 # However, we have to worry about "else if" that spans multiple lines! 3523 # However, we have to worry about "else if" that spans multiple lines!
2992 if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): 3524 if Search(r'else if\s*\(', line): # could be multi-line if
2993 if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if 3525 brace_on_left = bool(Search(r'}\s*else if\s*\(', line))
2994 # find the ( after the if 3526 # find the ( after the if
2995 pos = line.find('else if') 3527 pos = line.find('else if')
2996 pos = line.find('(', pos) 3528 pos = line.find('(', pos)
2997 if pos > 0: 3529 if pos > 0:
2998 (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) 3530 (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
2999 if endline[endpos:].find('{') == -1: # must be brace after if 3531 brace_on_right = endline[endpos:].find('{') != -1
3000 error(filename, linenum, 'readability/braces', 5, 3532 if brace_on_left != brace_on_right: # must be brace after if
3001 'If an else has a brace on one side, it should have it on both') 3533 error(filename, linenum, 'readability/braces', 5,
3002 else: # common case: else not followed by a multi-line if 3534 'If an else has a brace on one side, it should have it on both')
3003 error(filename, linenum, 'readability/braces', 5, 3535 elif Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
3004 'If an else has a brace on one side, it should have it on both') 3536 error(filename, linenum, 'readability/braces', 5,
3537 'If an else has a brace on one side, it should have it on both')
3005 3538
3006 # Likewise, an else should never have the else clause on the same line 3539 # Likewise, an else should never have the else clause on the same line
3007 if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): 3540 if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
3008 error(filename, linenum, 'whitespace/newline', 4, 3541 error(filename, linenum, 'whitespace/newline', 4,
3009 'Else clause should never be on same line as else (use 2 lines)') 3542 'Else clause should never be on same line as else (use 2 lines)')
3010 3543
3011 # In the same way, a do/while should never be on one line 3544 # In the same way, a do/while should never be on one line
3012 if Match(r'\s*do [^\s{]', line): 3545 if Match(r'\s*do [^\s{]', line):
3013 error(filename, linenum, 'whitespace/newline', 4, 3546 error(filename, linenum, 'whitespace/newline', 4,
3014 'do/while clauses should not be on a single line') 3547 'do/while clauses should not be on a single line')
3015 3548
3549 # Check single-line if/else bodies. The style guide says 'curly braces are not
3550 # required for single-line statements'. We additionally allow multi-line,
3551 # single statements, but we reject anything with more than one semicolon in
3552 # it. This means that the first semicolon after the if should be at the end of
3553 # its line, and the line after that should have an indent level equal to or
3554 # lower than the if. We also check for ambiguous if/else nesting without
3555 # braces.
3556 if_else_match = Search(r'\b(if\s*\(|else\b)', line)
3557 if if_else_match and not Match(r'\s*#', line):
3558 if_indent = GetIndentLevel(line)
3559 endline, endlinenum, endpos = line, linenum, if_else_match.end()
3560 if_match = Search(r'\bif\s*\(', line)
3561 if if_match:
3562 # This could be a multiline if condition, so find the end first.
3563 pos = if_match.end() - 1
3564 (endline, endlinenum, endpos) = CloseExpression(clean_lines, linenum, pos)
3565 # Check for an opening brace, either directly after the if or on the next
3566 # line. If found, this isn't a single-statement conditional.
3567 if (not Match(r'\s*{', endline[endpos:])
3568 and not (Match(r'\s*$', endline[endpos:])
3569 and endlinenum < (len(clean_lines.elided) - 1)
3570 and Match(r'\s*{', clean_lines.elided[endlinenum + 1]))):
3571 while (endlinenum < len(clean_lines.elided)
3572 and ';' not in clean_lines.elided[endlinenum][endpos:]):
3573 endlinenum += 1
3574 endpos = 0
3575 if endlinenum < len(clean_lines.elided):
3576 endline = clean_lines.elided[endlinenum]
3577 # We allow a mix of whitespace and closing braces (e.g. for one-liner
3578 # methods) and a single \ after the semicolon (for macros)
3579 endpos = endline.find(';')
3580 if not Match(r';[\s}]*(\\?)$', endline[endpos:]):
3581 # Semicolon isn't the last character, there's something trailing
3582 error(filename, linenum, 'readability/braces', 4,
3583 'If/else bodies with multiple statements require braces')
3584 elif endlinenum < len(clean_lines.elided) - 1:
3585 # Make sure the next line is dedented
3586 next_line = clean_lines.elided[endlinenum + 1]
3587 next_indent = GetIndentLevel(next_line)
3588 # With ambiguous nested if statements, this will error out on the
3589 # if that *doesn't* match the else, regardless of whether it's the
3590 # inner one or outer one.
3591 if (if_match and Match(r'\s*else\b', next_line)
3592 and next_indent != if_indent):
3593 error(filename, linenum, 'readability/braces', 4,
3594 'Else clause should be indented at the same level as if. '
3595 'Ambiguous nested if/else chains require braces.')
3596 elif next_indent > if_indent:
3597 error(filename, linenum, 'readability/braces', 4,
3598 'If/else bodies with multiple statements require braces')
3599
3600
3601 def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
3602 """Looks for redundant trailing semicolon.
3603
3604 Args:
3605 filename: The name of the current file.
3606 clean_lines: A CleansedLines instance containing the file.
3607 linenum: The number of the line to check.
3608 error: The function to call with any errors found.
3609 """
3610
3611 line = clean_lines.elided[linenum]
3612
3016 # Block bodies should not be followed by a semicolon. Due to C++11 3613 # Block bodies should not be followed by a semicolon. Due to C++11
3017 # brace initialization, there are more places where semicolons are 3614 # brace initialization, there are more places where semicolons are
3018 # required than not, so we use a whitelist approach to check these 3615 # required than not, so we use a whitelist approach to check these
3019 # rather than a blacklist. These are the places where "};" should 3616 # rather than a blacklist. These are the places where "};" should
3020 # be replaced by just "}": 3617 # be replaced by just "}":
3021 # 1. Some flavor of block following closing parenthesis: 3618 # 1. Some flavor of block following closing parenthesis:
3022 # for (;;) {}; 3619 # for (;;) {};
3023 # while (...) {}; 3620 # while (...) {};
3024 # switch (...) {}; 3621 # switch (...) {};
3025 # Function(...) {}; 3622 # Function(...) {};
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3074 # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: 3671 # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED:
3075 # 3672 #
3076 # We implement a whitelist of safe macros instead of a blacklist of 3673 # We implement a whitelist of safe macros instead of a blacklist of
3077 # unsafe macros, even though the latter appears less frequently in 3674 # unsafe macros, even though the latter appears less frequently in
3078 # google code and would have been easier to implement. This is because 3675 # google code and would have been easier to implement. This is because
3079 # the downside for getting the whitelist wrong means some extra 3676 # the downside for getting the whitelist wrong means some extra
3080 # semicolons, while the downside for getting the blacklist wrong 3677 # semicolons, while the downside for getting the blacklist wrong
3081 # would result in compile errors. 3678 # would result in compile errors.
3082 # 3679 #
3083 # In addition to macros, we also don't want to warn on compound 3680 # In addition to macros, we also don't want to warn on compound
3084 # literals. 3681 # literals and lambdas.
3085 closing_brace_pos = match.group(1).rfind(')') 3682 closing_brace_pos = match.group(1).rfind(')')
3086 opening_parenthesis = ReverseCloseExpression( 3683 opening_parenthesis = ReverseCloseExpression(
3087 clean_lines, linenum, closing_brace_pos) 3684 clean_lines, linenum, closing_brace_pos)
3088 if opening_parenthesis[2] > -1: 3685 if opening_parenthesis[2] > -1:
3089 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] 3686 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]]
3090 macro = Search(r'\b([A-Z_]+)\s*$', line_prefix) 3687 macro = Search(r'\b([A-Z_]+)\s*$', line_prefix)
3688 func = Match(r'^(.*\])\s*$', line_prefix)
3091 if ((macro and 3689 if ((macro and
3092 macro.group(1) not in ( 3690 macro.group(1) not in (
3093 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', 3691 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',
3094 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', 3692 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',
3095 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or 3693 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or
3694 (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or
3096 Search(r'\s+=\s*$', line_prefix)): 3695 Search(r'\s+=\s*$', line_prefix)):
3097 match = None 3696 match = None
3697 if (match and
3698 opening_parenthesis[1] > 1 and
3699 Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])):
3700 # Multi-line lambda-expression
3701 match = None
3098 3702
3099 else: 3703 else:
3100 # Try matching cases 2-3. 3704 # Try matching cases 2-3.
3101 match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) 3705 match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line)
3102 if not match: 3706 if not match:
3103 # Try matching cases 4-6. These are always matched on separate lines. 3707 # Try matching cases 4-6. These are always matched on separate lines.
3104 # 3708 #
3105 # Note that we can't simply concatenate the previous line to the 3709 # Note that we can't simply concatenate the previous line to the
3106 # current line and do a single match, otherwise we may output 3710 # current line and do a single match, otherwise we may output
3107 # duplicate warnings for the blank line case: 3711 # duplicate warnings for the blank line case:
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3156 # have a separate check for semicolons preceded by whitespace. 3760 # have a separate check for semicolons preceded by whitespace.
3157 if end_pos >= 0 and Match(r';', end_line[end_pos:]): 3761 if end_pos >= 0 and Match(r';', end_line[end_pos:]):
3158 if matched.group(1) == 'if': 3762 if matched.group(1) == 'if':
3159 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, 3763 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5,
3160 'Empty conditional bodies should use {}') 3764 'Empty conditional bodies should use {}')
3161 else: 3765 else:
3162 error(filename, end_linenum, 'whitespace/empty_loop_body', 5, 3766 error(filename, end_linenum, 'whitespace/empty_loop_body', 5,
3163 'Empty loop bodies should use {} or continue') 3767 'Empty loop bodies should use {} or continue')
3164 3768
3165 3769
3770 def FindCheckMacro(line):
3771 """Find a replaceable CHECK-like macro.
3772
3773 Args:
3774 line: line to search on.
3775 Returns:
3776 (macro name, start position), or (None, -1) if no replaceable
3777 macro is found.
3778 """
3779 for macro in _CHECK_MACROS:
3780 i = line.find(macro)
3781 if i >= 0:
3782 # Find opening parenthesis. Do a regular expression match here
3783 # to make sure that we are matching the expected CHECK macro, as
3784 # opposed to some other macro that happens to contain the CHECK
3785 # substring.
3786 matched = Match(r'^(.*\b' + macro + r'\s*)\(', line)
3787 if not matched:
3788 continue
3789 return (macro, len(matched.group(1)))
3790 return (None, -1)
3791
3792
3166 def CheckCheck(filename, clean_lines, linenum, error): 3793 def CheckCheck(filename, clean_lines, linenum, error):
3167 """Checks the use of CHECK and EXPECT macros. 3794 """Checks the use of CHECK and EXPECT macros.
3168 3795
3169 Args: 3796 Args:
3170 filename: The name of the current file. 3797 filename: The name of the current file.
3171 clean_lines: A CleansedLines instance containing the file. 3798 clean_lines: A CleansedLines instance containing the file.
3172 linenum: The number of the line to check. 3799 linenum: The number of the line to check.
3173 error: The function to call with any errors found. 3800 error: The function to call with any errors found.
3174 """ 3801 """
3175 3802
3176 # Decide the set of replacement macros that should be suggested 3803 # Decide the set of replacement macros that should be suggested
3177 lines = clean_lines.elided 3804 lines = clean_lines.elided
3178 check_macro = None 3805 (check_macro, start_pos) = FindCheckMacro(lines[linenum])
3179 start_pos = -1 3806 if not check_macro:
3180 for macro in _CHECK_MACROS:
3181 i = lines[linenum].find(macro)
3182 if i >= 0:
3183 check_macro = macro
3184
3185 # Find opening parenthesis. Do a regular expression match here
3186 # to make sure that we are matching the expected CHECK macro, as
3187 # opposed to some other macro that happens to contain the CHECK
3188 # substring.
3189 matched = Match(r'^(.*\b' + check_macro + r'\s*)\(', lines[linenum])
3190 if not matched:
3191 continue
3192 start_pos = len(matched.group(1))
3193 break
3194 if not check_macro or start_pos < 0:
3195 # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
3196 return 3807 return
3197 3808
3198 # Find end of the boolean expression by matching parentheses 3809 # Find end of the boolean expression by matching parentheses
3199 (last_line, end_line, end_pos) = CloseExpression( 3810 (last_line, end_line, end_pos) = CloseExpression(
3200 clean_lines, linenum, start_pos) 3811 clean_lines, linenum, start_pos)
3201 if end_pos < 0: 3812 if end_pos < 0:
3202 return 3813 return
3203 if linenum == end_line: 3814 if linenum == end_line:
3204 expression = lines[linenum][start_pos + 1:end_pos - 1] 3815 expression = lines[linenum][start_pos + 1:end_pos - 1]
3205 else: 3816 else:
3206 expression = lines[linenum][start_pos + 1:] 3817 expression = lines[linenum][start_pos + 1:]
3207 for i in xrange(linenum + 1, end_line): 3818 for i in xrange(linenum + 1, end_line):
3208 expression += lines[i] 3819 expression += lines[i]
3209 expression += last_line[0:end_pos - 1] 3820 expression += last_line[0:end_pos - 1]
3210 3821
3211 # Parse expression so that we can take parentheses into account. 3822 # Parse expression so that we can take parentheses into account.
3212 # This avoids false positives for inputs like "CHECK((a < 4) == b)", 3823 # This avoids false positives for inputs like "CHECK((a < 4) == b)",
3213 # which is not replaceable by CHECK_LE. 3824 # which is not replaceable by CHECK_LE.
3214 lhs = '' 3825 lhs = ''
3215 rhs = '' 3826 rhs = ''
3216 operator = None 3827 operator = None
3217 while expression: 3828 while expression:
3218 matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||' 3829 matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||'
3219 r'==|!=|>=|>|<=|<|\()(.*)$', expression) 3830 r'==|!=|>=|>|<=|<|\()(.*)$', expression)
3220 if matched: 3831 if matched:
3221 token = matched.group(1) 3832 token = matched.group(1)
3222 if token == '(': 3833 if token == '(':
3223 # Parenthesized operand 3834 # Parenthesized operand
3224 expression = matched.group(2) 3835 expression = matched.group(2)
3225 (end, _) = FindEndOfExpressionInLine(expression, 0, 1, '(', ')') 3836 (end, _) = FindEndOfExpressionInLine(expression, 0, ['('])
3226 if end < 0: 3837 if end < 0:
3227 return # Unmatched parenthesis 3838 return # Unmatched parenthesis
3228 lhs += '(' + expression[0:end] 3839 lhs += '(' + expression[0:end]
3229 expression = expression[end:] 3840 expression = expression[end:]
3230 elif token in ('&&', '||'): 3841 elif token in ('&&', '||'):
3231 # Logical and/or operators. This means the expression 3842 # Logical and/or operators. This means the expression
3232 # contains more than one term, for example: 3843 # contains more than one term, for example:
3233 # CHECK(42 < a && a < b); 3844 # CHECK(42 < a && a < b);
3234 # 3845 #
3235 # These are not replaceable with CHECK_LE, so bail out early. 3846 # These are not replaceable with CHECK_LE, so bail out early.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
3350 3961
3351 Most of these rules are hard to test (naming, comment style), but we 3962 Most of these rules are hard to test (naming, comment style), but we
3352 do what we can. In particular we check for 2-space indents, line lengths, 3963 do what we can. In particular we check for 2-space indents, line lengths,
3353 tab usage, spaces inside code, etc. 3964 tab usage, spaces inside code, etc.
3354 3965
3355 Args: 3966 Args:
3356 filename: The name of the current file. 3967 filename: The name of the current file.
3357 clean_lines: A CleansedLines instance containing the file. 3968 clean_lines: A CleansedLines instance containing the file.
3358 linenum: The number of the line to check. 3969 linenum: The number of the line to check.
3359 file_extension: The extension (without the dot) of the filename. 3970 file_extension: The extension (without the dot) of the filename.
3360 nesting_state: A _NestingState instance which maintains information about 3971 nesting_state: A NestingState instance which maintains information about
3361 the current stack of nested blocks being parsed. 3972 the current stack of nested blocks being parsed.
3362 error: The function to call with any errors found. 3973 error: The function to call with any errors found.
3363 """ 3974 """
3364 3975
3365 # Don't use "elided" lines here, otherwise we can't check commented lines. 3976 # Don't use "elided" lines here, otherwise we can't check commented lines.
3366 # Don't want to use "raw" either, because we don't want to check inside C++11 3977 # Don't want to use "raw" either, because we don't want to check inside C++11
3367 # raw strings, 3978 # raw strings,
3368 raw_lines = clean_lines.lines_without_raw_strings 3979 raw_lines = clean_lines.lines_without_raw_strings
3369 line = raw_lines[linenum] 3980 line = raw_lines[linenum]
3370 3981
3371 if line.find('\t') != -1: 3982 if line.find('\t') != -1:
3372 error(filename, linenum, 'whitespace/tab', 1, 3983 error(filename, linenum, 'whitespace/tab', 1,
3373 'Tab found; better to use spaces') 3984 'Tab found; better to use spaces')
3374 3985
3375 # One or three blank spaces at the beginning of the line is weird; it's 3986 # One or three blank spaces at the beginning of the line is weird; it's
3376 # hard to reconcile that with 2-space indents. 3987 # hard to reconcile that with 2-space indents.
3377 # NOTE: here are the conditions rob pike used for his tests. Mine aren't 3988 # NOTE: here are the conditions rob pike used for his tests. Mine aren't
3378 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces 3989 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
3379 # if(RLENGTH > 20) complain = 0; 3990 # if(RLENGTH > 20) complain = 0;
3380 # if(match($0, " +(error|private|public|protected):")) complain = 0; 3991 # if(match($0, " +(error|private|public|protected):")) complain = 0;
3381 # if(match(prev, "&& *$")) complain = 0; 3992 # if(match(prev, "&& *$")) complain = 0;
3382 # if(match(prev, "\\|\\| *$")) complain = 0; 3993 # if(match(prev, "\\|\\| *$")) complain = 0;
3383 # if(match(prev, "[\",=><] *$")) complain = 0; 3994 # if(match(prev, "[\",=><] *$")) complain = 0;
3384 # if(match($0, " <<")) complain = 0; 3995 # if(match($0, " <<")) complain = 0;
3385 # if(match(prev, " +for \\(")) complain = 0; 3996 # if(match(prev, " +for \\(")) complain = 0;
3386 # if(prevodd && match(prevprev, " +for \\(")) complain = 0; 3997 # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
3998 scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$'
3999 classinfo = nesting_state.InnermostClass()
3387 initial_spaces = 0 4000 initial_spaces = 0
3388 cleansed_line = clean_lines.elided[linenum] 4001 cleansed_line = clean_lines.elided[linenum]
3389 while initial_spaces < len(line) and line[initial_spaces] == ' ': 4002 while initial_spaces < len(line) and line[initial_spaces] == ' ':
3390 initial_spaces += 1 4003 initial_spaces += 1
3391 if line and line[-1].isspace(): 4004 if line and line[-1].isspace():
3392 error(filename, linenum, 'whitespace/end_of_line', 4, 4005 error(filename, linenum, 'whitespace/end_of_line', 4,
3393 'Line ends in whitespace. Consider deleting these extra spaces.') 4006 'Line ends in whitespace. Consider deleting these extra spaces.')
3394 # There are certain situations we allow one space, notably for section labels 4007 # There are certain situations we allow one space, notably for
4008 # section labels, and also lines containing multi-line raw strings.
3395 elif ((initial_spaces == 1 or initial_spaces == 3) and 4009 elif ((initial_spaces == 1 or initial_spaces == 3) and
3396 not Match(r'\s*\w+\s*:\s*$', cleansed_line)): 4010 not Match(scope_or_label_pattern, cleansed_line) and
4011 not (clean_lines.raw_lines[linenum] != line and
4012 Match(r'^\s*""', line))):
3397 error(filename, linenum, 'whitespace/indent', 3, 4013 error(filename, linenum, 'whitespace/indent', 3,
3398 'Weird number of spaces at line-start. ' 4014 'Weird number of spaces at line-start. '
3399 'Are you using a 2-space indent?') 4015 'Are you using a 2-space indent?')
3400 4016
3401 # Check if the line is a header guard. 4017 # Check if the line is a header guard.
3402 is_header_guard = False 4018 is_header_guard = False
3403 if file_extension == 'h': 4019 if file_extension == 'h':
3404 cppvar = GetHeaderGuardCPPVariable(filename) 4020 cppvar = GetHeaderGuardCPPVariable(filename)
3405 if (line.startswith('#ifndef %s' % cppvar) or 4021 if (line.startswith('#ifndef %s' % cppvar) or
3406 line.startswith('#define %s' % cppvar) or 4022 line.startswith('#define %s' % cppvar) or
(...skipping 27 matching lines...) Expand all
3434 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and 4050 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
3435 # It's ok to have many commands in a switch case that fits in 1 line 4051 # It's ok to have many commands in a switch case that fits in 1 line
3436 not ((cleansed_line.find('case ') != -1 or 4052 not ((cleansed_line.find('case ') != -1 or
3437 cleansed_line.find('default:') != -1) and 4053 cleansed_line.find('default:') != -1) and
3438 cleansed_line.find('break;') != -1)): 4054 cleansed_line.find('break;') != -1)):
3439 error(filename, linenum, 'whitespace/newline', 0, 4055 error(filename, linenum, 'whitespace/newline', 0,
3440 'More than one command on the same line') 4056 'More than one command on the same line')
3441 4057
3442 # Some more style checks 4058 # Some more style checks
3443 CheckBraces(filename, clean_lines, linenum, error) 4059 CheckBraces(filename, clean_lines, linenum, error)
4060 CheckTrailingSemicolon(filename, clean_lines, linenum, error)
3444 CheckEmptyBlockBody(filename, clean_lines, linenum, error) 4061 CheckEmptyBlockBody(filename, clean_lines, linenum, error)
3445 CheckAccess(filename, clean_lines, linenum, nesting_state, error) 4062 CheckAccess(filename, clean_lines, linenum, nesting_state, error)
3446 CheckSpacing(filename, clean_lines, linenum, nesting_state, error) 4063 CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
4064 CheckOperatorSpacing(filename, clean_lines, linenum, error)
4065 CheckParenthesisSpacing(filename, clean_lines, linenum, error)
4066 CheckCommaSpacing(filename, clean_lines, linenum, error)
4067 CheckBracesSpacing(filename, clean_lines, linenum, error)
4068 CheckSpacingForFunctionCall(filename, clean_lines, linenum, error)
4069 CheckRValueReference(filename, clean_lines, linenum, nesting_state, error)
3447 CheckCheck(filename, clean_lines, linenum, error) 4070 CheckCheck(filename, clean_lines, linenum, error)
3448 CheckAltTokens(filename, clean_lines, linenum, error) 4071 CheckAltTokens(filename, clean_lines, linenum, error)
3449 classinfo = nesting_state.InnermostClass() 4072 classinfo = nesting_state.InnermostClass()
3450 if classinfo: 4073 if classinfo:
3451 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) 4074 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
3452 4075
3453 4076
3454 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') 4077 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
3455 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') 4078 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
3456 # Matches the first component of a filename delimited by -s and _s. That is: 4079 # Matches the first component of a filename delimited by -s and _s. That is:
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3573 applicable to #include lines in CheckLanguage must be put here. 4196 applicable to #include lines in CheckLanguage must be put here.
3574 4197
3575 Args: 4198 Args:
3576 filename: The name of the current file. 4199 filename: The name of the current file.
3577 clean_lines: A CleansedLines instance containing the file. 4200 clean_lines: A CleansedLines instance containing the file.
3578 linenum: The number of the line to check. 4201 linenum: The number of the line to check.
3579 include_state: An _IncludeState instance in which the headers are inserted. 4202 include_state: An _IncludeState instance in which the headers are inserted.
3580 error: The function to call with any errors found. 4203 error: The function to call with any errors found.
3581 """ 4204 """
3582 fileinfo = FileInfo(filename) 4205 fileinfo = FileInfo(filename)
3583
3584 line = clean_lines.lines[linenum] 4206 line = clean_lines.lines[linenum]
3585 4207
3586 # "include" should use the new style "foo/bar.h" instead of just "bar.h" 4208 # "include" should use the new style "foo/bar.h" instead of just "bar.h"
3587 if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line): 4209 if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
3588 error(filename, linenum, 'build/include', 4, 4210 error(filename, linenum, 'build/include', 4,
3589 'Include the directory when naming .h files') 4211 'Include the directory when naming .h files')
3590 4212
3591 # we shouldn't include a file more than once. actually, there are a 4213 # we shouldn't include a file more than once. actually, there are a
3592 # handful of instances where doing so is okay, but in general it's 4214 # handful of instances where doing so is okay, but in general it's
3593 # not. 4215 # not.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3626 'Include "%s" not in alphabetical order' % include) 4248 'Include "%s" not in alphabetical order' % include)
3627 include_state.SetLastHeader(canonical_include) 4249 include_state.SetLastHeader(canonical_include)
3628 4250
3629 # Look for any of the stream classes that are part of standard C++. 4251 # Look for any of the stream classes that are part of standard C++.
3630 match = _RE_PATTERN_INCLUDE.match(line) 4252 match = _RE_PATTERN_INCLUDE.match(line)
3631 if match: 4253 if match:
3632 include = match.group(2) 4254 include = match.group(2)
3633 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): 4255 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
3634 # Many unit tests use cout, so we exempt them. 4256 # Many unit tests use cout, so we exempt them.
3635 if not _IsTestFilename(filename): 4257 if not _IsTestFilename(filename):
3636 error(filename, linenum, 'readability/streams', 3, 4258 # Suggest a different header for ostream
3637 'Streams are highly discouraged.') 4259 if include == 'ostream':
4260 error(filename, linenum, 'readability/streams', 3,
4261 'For logging, include "base/logging.h" instead of <ostream>.')
4262 else:
4263 error(filename, linenum, 'readability/streams', 3,
4264 'Streams are highly discouraged.')
3638 4265
3639 4266
3640 def _GetTextInside(text, start_pattern): 4267 def _GetTextInside(text, start_pattern):
3641 r"""Retrieves all the text between matching open and close parentheses. 4268 r"""Retrieves all the text between matching open and close parentheses.
3642 4269
3643 Given a string of lines and a regular expression string, retrieve all the text 4270 Given a string of lines and a regular expression string, retrieve all the text
3644 following the expression and between opening punctuation symbols like 4271 following the expression and between opening punctuation symbols like
3645 (, [, or {, and the matching close-punctuation symbol. This properly nested 4272 (, [, or {, and the matching close-punctuation symbol. This properly nested
3646 occurrences of the punctuations, so for the text like 4273 occurrences of the punctuations, so for the text like
3647 printf(a(), b(c())); 4274 printf(a(), b(c()));
3648 a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. 4275 a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'.
3649 start_pattern must match string having an open punctuation symbol at the end. 4276 start_pattern must match string having an open punctuation symbol at the end.
3650 4277
3651 Args: 4278 Args:
3652 text: The lines to extract text. Its comments and strings must be elided. 4279 text: The lines to extract text. Its comments and strings must be elided.
3653 It can be single line and can span multiple lines. 4280 It can be single line and can span multiple lines.
3654 start_pattern: The regexp string indicating where to start extracting 4281 start_pattern: The regexp string indicating where to start extracting
3655 the text. 4282 the text.
3656 Returns: 4283 Returns:
3657 The extracted text. 4284 The extracted text.
3658 None if either the opening string or ending punctuation could not be found. 4285 None if either the opening string or ending punctuation could not be found.
3659 """ 4286 """
3660 # TODO(sugawarayu): Audit cpplint.py to see what places could be profitably 4287 # TODO(unknown): Audit cpplint.py to see what places could be profitably
3661 # rewritten to use _GetTextInside (and use inferior regexp matching today). 4288 # rewritten to use _GetTextInside (and use inferior regexp matching today).
3662 4289
3663 # Give opening punctuations to get the matching close-punctuations. 4290 # Give opening punctuations to get the matching close-punctuations.
3664 matching_punctuation = {'(': ')', '{': '}', '[': ']'} 4291 matching_punctuation = {'(': ')', '{': '}', '[': ']'}
3665 closing_punctuation = set(matching_punctuation.itervalues()) 4292 closing_punctuation = set(matching_punctuation.itervalues())
3666 4293
3667 # Find the position to start extracting text. 4294 # Find the position to start extracting text.
3668 match = re.search(start_pattern, text, re.M) 4295 match = re.search(start_pattern, text, re.M)
3669 if not match: # start_pattern not found in text. 4296 if not match: # start_pattern not found in text.
3670 return None 4297 return None
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3725 4352
3726 Some of these rules are hard to test (function overloading, using 4353 Some of these rules are hard to test (function overloading, using
3727 uint32 inappropriately), but we do the best we can. 4354 uint32 inappropriately), but we do the best we can.
3728 4355
3729 Args: 4356 Args:
3730 filename: The name of the current file. 4357 filename: The name of the current file.
3731 clean_lines: A CleansedLines instance containing the file. 4358 clean_lines: A CleansedLines instance containing the file.
3732 linenum: The number of the line to check. 4359 linenum: The number of the line to check.
3733 file_extension: The extension (without the dot) of the filename. 4360 file_extension: The extension (without the dot) of the filename.
3734 include_state: An _IncludeState instance in which the headers are inserted. 4361 include_state: An _IncludeState instance in which the headers are inserted.
3735 nesting_state: A _NestingState instance which maintains information about 4362 nesting_state: A NestingState instance which maintains information about
3736 the current stack of nested blocks being parsed. 4363 the current stack of nested blocks being parsed.
3737 error: The function to call with any errors found. 4364 error: The function to call with any errors found.
3738 """ 4365 """
3739 # If the line is empty or consists of entirely a comment, no need to 4366 # If the line is empty or consists of entirely a comment, no need to
3740 # check it. 4367 # check it.
3741 line = clean_lines.elided[linenum] 4368 line = clean_lines.elided[linenum]
3742 if not line: 4369 if not line:
3743 return 4370 return
3744 4371
3745 match = _RE_PATTERN_INCLUDE.search(line) 4372 match = _RE_PATTERN_INCLUDE.search(line)
3746 if match: 4373 if match:
3747 CheckIncludeLine(filename, clean_lines, linenum, include_state, error) 4374 CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
3748 return 4375 return
3749 4376
3750 # Reset include state across preprocessor directives. This is meant 4377 # Reset include state across preprocessor directives. This is meant
3751 # to silence warnings for conditional includes. 4378 # to silence warnings for conditional includes.
3752 if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line): 4379 if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line):
3753 include_state.ResetSection() 4380 include_state.ResetSection()
3754 4381
3755 # Make Windows paths like Unix. 4382 # Make Windows paths like Unix.
3756 fullname = os.path.abspath(filename).replace('\\', '/') 4383 fullname = os.path.abspath(filename).replace('\\', '/')
3757 4384
3758 # TODO(unknown): figure out if they're using default arguments in fn proto. 4385 # Perform other checks now that we are sure that this is not an include line
3759 4386 CheckCasts(filename, clean_lines, linenum, error)
3760 # Check to see if they're using an conversion function cast. 4387 CheckGlobalStatic(filename, clean_lines, linenum, error)
3761 # I just try to capture the most common basic types, though there are more. 4388 CheckPrintf(filename, clean_lines, linenum, error)
3762 # Parameterless conversion functions, such as bool(), are allowed as they are
3763 # probably a member operator declaration or default constructor.
3764 match = Search(
3765 r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there
3766 r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
3767 r'(\([^)].*)', line)
3768 if match:
3769 matched_new = match.group(1)
3770 matched_type = match.group(2)
3771 matched_funcptr = match.group(3)
3772
3773 # gMock methods are defined using some variant of MOCK_METHODx(name, type)
3774 # where type may be float(), int(string), etc. Without context they are
3775 # virtually indistinguishable from int(x) casts. Likewise, gMock's
3776 # MockCallback takes a template parameter of the form return_type(arg_type),
3777 # which looks much like the cast we're trying to detect.
3778 #
3779 # std::function<> wrapper has a similar problem.
3780 #
3781 # Return types for function pointers also look like casts if they
3782 # don't have an extra space.
3783 if (matched_new is None and # If new operator, then this isn't a cast
3784 not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
3785 Search(r'\bMockCallback<.*>', line) or
3786 Search(r'\bstd::function<.*>', line)) and
3787 not (matched_funcptr and
3788 Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(',
3789 matched_funcptr))):
3790 # Try a bit harder to catch gmock lines: the only place where
3791 # something looks like an old-style cast is where we declare the
3792 # return type of the mocked method, and the only time when we
3793 # are missing context is if MOCK_METHOD was split across
3794 # multiple lines. The missing MOCK_METHOD is usually one or two
3795 # lines back, so scan back one or two lines.
3796 #
3797 # It's not possible for gmock macros to appear in the first 2
3798 # lines, since the class head + section name takes up 2 lines.
3799 if (linenum < 2 or
3800 not (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
3801 clean_lines.elided[linenum - 1]) or
3802 Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
3803 clean_lines.elided[linenum - 2]))):
3804 error(filename, linenum, 'readability/casting', 4,
3805 'Using deprecated casting style. '
3806 'Use static_cast<%s>(...) instead' %
3807 matched_type)
3808
3809 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3810 'static_cast',
3811 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
3812
3813 # This doesn't catch all cases. Consider (const char * const)"hello".
3814 #
3815 # (char *) "foo" should always be a const_cast (reinterpret_cast won't
3816 # compile).
3817 if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3818 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error):
3819 pass
3820 else:
3821 # Check pointer casts for other than string constants
3822 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
3823 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
3824
3825 # In addition, we look for people taking the address of a cast. This
3826 # is dangerous -- casts can assign to temporaries, so the pointer doesn't
3827 # point where you think.
3828 match = Search(
3829 r'(?:&\(([^)]+)\)[\w(])|'
3830 r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line)
3831 if match and match.group(1) != '*':
3832 error(filename, linenum, 'runtime/casting', 4,
3833 ('Are you taking an address of a cast? '
3834 'This is dangerous: could be a temp var. '
3835 'Take the address before doing the cast, rather than after'))
3836
3837 # Create an extended_line, which is the concatenation of the current and
3838 # next lines, for more effective checking of code that may span more than one
3839 # line.
3840 if linenum + 1 < clean_lines.NumLines():
3841 extended_line = line + clean_lines.elided[linenum + 1]
3842 else:
3843 extended_line = line
3844
3845 # Check for people declaring static/global STL strings at the top level.
3846 # This is dangerous because the C++ language does not guarantee that
3847 # globals with constructors are initialized before the first access.
3848 match = Match(
3849 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
3850 line)
3851 # Make sure it's not a function.
3852 # Function template specialization looks like: "string foo<Type>(...".
3853 # Class template definitions look like: "string Foo<Type>::Method(...".
3854 #
3855 # Also ignore things that look like operators. These are matched separately
3856 # because operator names cross non-word boundaries. If we change the pattern
3857 # above, we would decrease the accuracy of matching identifiers.
3858 if (match and
3859 not Search(r'\boperator\W', line) and
3860 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3))):
3861 error(filename, linenum, 'runtime/string', 4,
3862 'For a static/global string constant, use a C style string instead: '
3863 '"%schar %s[]".' %
3864 (match.group(1), match.group(2)))
3865
3866 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
3867 error(filename, linenum, 'runtime/init', 4,
3868 'You seem to be initializing a member variable with itself.')
3869 4389
3870 if file_extension == 'h': 4390 if file_extension == 'h':
3871 # TODO(unknown): check that 1-arg constructors are explicit. 4391 # TODO(unknown): check that 1-arg constructors are explicit.
3872 # How to tell it's a constructor? 4392 # How to tell it's a constructor?
3873 # (handled in CheckForNonStandardConstructs for now) 4393 # (handled in CheckForNonStandardConstructs for now)
3874 # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS 4394 # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
3875 # (level 1 error) 4395 # (level 1 error)
3876 pass 4396 pass
3877 4397
3878 # Check if people are using the verboten C basic types. The only exception 4398 # Check if people are using the verboten C basic types. The only exception
3879 # we regularly allow is "unsigned short port" for port. 4399 # we regularly allow is "unsigned short port" for port.
3880 if Search(r'\bshort port\b', line): 4400 if Search(r'\bshort port\b', line):
3881 if not Search(r'\bunsigned short port\b', line): 4401 if not Search(r'\bunsigned short port\b', line):
3882 error(filename, linenum, 'runtime/int', 4, 4402 error(filename, linenum, 'runtime/int', 4,
3883 'Use "unsigned short" for ports, not "short"') 4403 'Use "unsigned short" for ports, not "short"')
3884 else: 4404 else:
3885 match = Search(r'\b(short|long(?! +double)|long long)\b', line) 4405 match = Search(r'\b(short|long(?! +double)|long long)\b', line)
3886 if match: 4406 if match:
3887 error(filename, linenum, 'runtime/int', 4, 4407 error(filename, linenum, 'runtime/int', 4,
3888 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) 4408 'Use int16/int64/etc, rather than the C type %s' % match.group(1))
3889 4409
3890 # When snprintf is used, the second argument shouldn't be a literal.
3891 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
3892 if match and match.group(2) != '0':
3893 # If 2nd arg is zero, snprintf is used to calculate size.
3894 error(filename, linenum, 'runtime/printf', 3,
3895 'If you can, use sizeof(%s) instead of %s as the 2nd arg '
3896 'to snprintf.' % (match.group(1), match.group(2)))
3897
3898 # Check if some verboten C functions are being used.
3899 if Search(r'\bsprintf\b', line):
3900 error(filename, linenum, 'runtime/printf', 5,
3901 'Never use sprintf. Use snprintf instead.')
3902 match = Search(r'\b(strcpy|strcat)\b', line)
3903 if match:
3904 error(filename, linenum, 'runtime/printf', 4,
3905 'Almost always, snprintf is better than %s' % match.group(1))
3906
3907 # Check if some verboten operator overloading is going on 4410 # Check if some verboten operator overloading is going on
3908 # TODO(unknown): catch out-of-line unary operator&: 4411 # TODO(unknown): catch out-of-line unary operator&:
3909 # class X {}; 4412 # class X {};
3910 # int operator&(const X& x) { return 42; } // unary operator& 4413 # int operator&(const X& x) { return 42; } // unary operator&
3911 # The trick is it's hard to tell apart from binary operator&: 4414 # The trick is it's hard to tell apart from binary operator&:
3912 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& 4415 # class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
3913 if Search(r'\boperator\s*&\s*\(\s*\)', line): 4416 if Search(r'\boperator\s*&\s*\(\s*\)', line):
3914 error(filename, linenum, 'runtime/operator', 4, 4417 error(filename, linenum, 'runtime/operator', 4,
3915 'Unary operator& is dangerous. Do not use it.') 4418 'Unary operator& is dangerous. Do not use it.')
3916 4419
3917 # Check for suspicious usage of "if" like 4420 # Check for suspicious usage of "if" like
3918 # } if (a == b) { 4421 # } if (a == b) {
3919 if Search(r'\}\s*if\s*\(', line): 4422 if Search(r'\}\s*if\s*\(', line):
3920 error(filename, linenum, 'readability/braces', 4, 4423 error(filename, linenum, 'readability/braces', 4,
3921 'Did you mean "else if"? If not, start a new line for "if".') 4424 'Did you mean "else if"? If not, start a new line for "if".')
3922 4425
3923 # Check for potential format string bugs like printf(foo). 4426 # Check for potential format string bugs like printf(foo).
3924 # We constrain the pattern not to pick things like DocidForPrintf(foo). 4427 # We constrain the pattern not to pick things like DocidForPrintf(foo).
3925 # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) 4428 # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
3926 # TODO(sugawarayu): Catch the following case. Need to change the calling 4429 # TODO(unknown): Catch the following case. Need to change the calling
3927 # convention of the whole function to process multiple line to handle it. 4430 # convention of the whole function to process multiple line to handle it.
3928 # printf( 4431 # printf(
3929 # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line); 4432 # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line);
3930 printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(') 4433 printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(')
3931 if printf_args: 4434 if printf_args:
3932 match = Match(r'([\w.\->()]+)$', printf_args) 4435 match = Match(r'([\w.\->()]+)$', printf_args)
3933 if match and match.group(1) != '__VA_ARGS__': 4436 if match and match.group(1) != '__VA_ARGS__':
3934 function_name = re.search(r'\b((?:string)?printf)\s*\(', 4437 function_name = re.search(r'\b((?:string)?printf)\s*\(',
3935 line, re.I).group(1) 4438 line, re.I).group(1)
3936 error(filename, linenum, 'runtime/printf', 4, 4439 error(filename, linenum, 'runtime/printf', 4,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
4012 # macros are typically OK, so we allow use of "namespace {" on lines 4515 # macros are typically OK, so we allow use of "namespace {" on lines
4013 # that end with backslashes. 4516 # that end with backslashes.
4014 if (file_extension == 'h' 4517 if (file_extension == 'h'
4015 and Search(r'\bnamespace\s*{', line) 4518 and Search(r'\bnamespace\s*{', line)
4016 and line[-1] != '\\'): 4519 and line[-1] != '\\'):
4017 error(filename, linenum, 'build/namespaces', 4, 4520 error(filename, linenum, 'build/namespaces', 4,
4018 'Do not use unnamed namespaces in header files. See ' 4521 'Do not use unnamed namespaces in header files. See '
4019 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp aces' 4522 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp aces'
4020 ' for more information.') 4523 ' for more information.')
4021 4524
4525
4526 def CheckGlobalStatic(filename, clean_lines, linenum, error):
4527 """Check for unsafe global or static objects.
4528
4529 Args:
4530 filename: The name of the current file.
4531 clean_lines: A CleansedLines instance containing the file.
4532 linenum: The number of the line to check.
4533 error: The function to call with any errors found.
4534 """
4535 line = clean_lines.elided[linenum]
4536
4537 # Check for people declaring static/global STL strings at the top level.
4538 # This is dangerous because the C++ language does not guarantee that
4539 # globals with constructors are initialized before the first access.
4540 match = Match(
4541 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
4542 line)
4543 # Remove false positives:
4544 # - String pointers (as opposed to values).
4545 # string *pointer
4546 # const string *pointer
4547 # string const *pointer
4548 # string *const pointer
4549 #
4550 # - Functions and template specializations.
4551 # string Function<Type>(...
4552 # string Class<Type>::Method(...
4553 #
4554 # - Operators. These are matched separately because operator names
4555 # cross non-word boundaries, and trying to match both operators
4556 # and functions at the same time would decrease accuracy of
4557 # matching identifiers.
4558 # string Class::operator*()
4559 if (match and
4560 not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and
4561 not Search(r'\boperator\W', line) and
4562 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3))):
4563 error(filename, linenum, 'runtime/string', 4,
4564 'For a static/global string constant, use a C style string instead: '
4565 '"%schar %s[]".' %
4566 (match.group(1), match.group(2)))
4567
4568 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
4569 error(filename, linenum, 'runtime/init', 4,
4570 'You seem to be initializing a member variable with itself.')
4571
4572
4573 def CheckPrintf(filename, clean_lines, linenum, error):
4574 """Check for printf related issues.
4575
4576 Args:
4577 filename: The name of the current file.
4578 clean_lines: A CleansedLines instance containing the file.
4579 linenum: The number of the line to check.
4580 error: The function to call with any errors found.
4581 """
4582 line = clean_lines.elided[linenum]
4583
4584 # When snprintf is used, the second argument shouldn't be a literal.
4585 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
4586 if match and match.group(2) != '0':
4587 # If 2nd arg is zero, snprintf is used to calculate size.
4588 error(filename, linenum, 'runtime/printf', 3,
4589 'If you can, use sizeof(%s) instead of %s as the 2nd arg '
4590 'to snprintf.' % (match.group(1), match.group(2)))
4591
4592 # Check if some verboten C functions are being used.
4593 if Search(r'\bsprintf\b', line):
4594 error(filename, linenum, 'runtime/printf', 5,
4595 'Never use sprintf. Use snprintf instead.')
4596 match = Search(r'\b(strcpy|strcat)\b', line)
4597 if match:
4598 error(filename, linenum, 'runtime/printf', 4,
4599 'Almost always, snprintf is better than %s' % match.group(1))
4600
4601
4602 def IsDerivedFunction(clean_lines, linenum):
4603 """Check if current line contains an inherited function.
4604
4605 Args:
4606 clean_lines: A CleansedLines instance containing the file.
4607 linenum: The number of the line to check.
4608 Returns:
4609 True if current line contains a function with "override"
4610 virt-specifier.
4611 """
4612 # Look for leftmost opening parenthesis on current line
4613 opening_paren = clean_lines.elided[linenum].find('(')
4614 if opening_paren < 0: return False
4615
4616 # Look for "override" after the matching closing parenthesis
4617 line, _, closing_paren = CloseExpression(clean_lines, linenum, opening_paren)
4618 return closing_paren >= 0 and Search(r'\boverride\b', line[closing_paren:])
4619
4620
4621 def IsInitializerList(clean_lines, linenum):
4622 """Check if current line is inside constructor initializer list.
4623
4624 Args:
4625 clean_lines: A CleansedLines instance containing the file.
4626 linenum: The number of the line to check.
4627 Returns:
4628 True if current line appears to be inside constructor initializer
4629 list, False otherwise.
4630 """
4631 for i in xrange(linenum, 1, -1):
4632 line = clean_lines.elided[i]
4633 if i == linenum:
4634 remove_function_body = Match(r'^(.*)\{\s*$', line)
4635 if remove_function_body:
4636 line = remove_function_body.group(1)
4637
4638 if Search(r'\s:\s*\w+[({]', line):
4639 # A lone colon tend to indicate the start of a constructor
4640 # initializer list. It could also be a ternary operator, which
4641 # also tend to appear in constructor initializer lists as
4642 # opposed to parameter lists.
4643 return True
4644 if Search(r'\}\s*,\s*$', line):
4645 # A closing brace followed by a comma is probably the end of a
4646 # brace-initialized member in constructor initializer list.
4647 return True
4648 if Search(r'[{};]\s*$', line):
4649 # Found one of the following:
4650 # - A closing brace or semicolon, probably the end of the previous
4651 # function.
4652 # - An opening brace, probably the start of current class or namespace.
4653 #
4654 # Current line is probably not inside an initializer list since
4655 # we saw one of those things without seeing the starting colon.
4656 return False
4657
4658 # Got to the beginning of the file without seeing the start of
4659 # constructor initializer list.
4660 return False
4661
4662
4022 def CheckForNonConstReference(filename, clean_lines, linenum, 4663 def CheckForNonConstReference(filename, clean_lines, linenum,
4023 nesting_state, error): 4664 nesting_state, error):
4024 """Check for non-const references. 4665 """Check for non-const references.
4025 4666
4026 Separate from CheckLanguage since it scans backwards from current 4667 Separate from CheckLanguage since it scans backwards from current
4027 line, instead of scanning forward. 4668 line, instead of scanning forward.
4028 4669
4029 Args: 4670 Args:
4030 filename: The name of the current file. 4671 filename: The name of the current file.
4031 clean_lines: A CleansedLines instance containing the file. 4672 clean_lines: A CleansedLines instance containing the file.
4032 linenum: The number of the line to check. 4673 linenum: The number of the line to check.
4033 nesting_state: A _NestingState instance which maintains information about 4674 nesting_state: A NestingState instance which maintains information about
4034 the current stack of nested blocks being parsed. 4675 the current stack of nested blocks being parsed.
4035 error: The function to call with any errors found. 4676 error: The function to call with any errors found.
4036 """ 4677 """
4037 # Do nothing if there is no '&' on current line. 4678 # Do nothing if there is no '&' on current line.
4038 line = clean_lines.elided[linenum] 4679 line = clean_lines.elided[linenum]
4039 if '&' not in line: 4680 if '&' not in line:
4040 return 4681 return
4041 4682
4683 # If a function is inherited, current function doesn't have much of
4684 # a choice, so any non-const references should not be blamed on
4685 # derived function.
4686 if IsDerivedFunction(clean_lines, linenum):
4687 return
4688
4042 # Long type names may be broken across multiple lines, usually in one 4689 # Long type names may be broken across multiple lines, usually in one
4043 # of these forms: 4690 # of these forms:
4044 # LongType 4691 # LongType
4045 # ::LongTypeContinued &identifier 4692 # ::LongTypeContinued &identifier
4046 # LongType:: 4693 # LongType::
4047 # LongTypeContinued &identifier 4694 # LongTypeContinued &identifier
4048 # LongType< 4695 # LongType<
4049 # ...>::LongTypeContinued &identifier 4696 # ...>::LongTypeContinued &identifier
4050 # 4697 #
4051 # If we detected a type split across two lines, join the previous 4698 # If we detected a type split across two lines, join the previous
(...skipping 28 matching lines...) Expand all
4080 for i in xrange(startline, linenum + 1): 4727 for i in xrange(startline, linenum + 1):
4081 line += clean_lines.elided[i].strip() 4728 line += clean_lines.elided[i].strip()
4082 4729
4083 # Check for non-const references in function parameters. A single '&' may 4730 # Check for non-const references in function parameters. A single '&' may
4084 # found in the following places: 4731 # found in the following places:
4085 # inside expression: binary & for bitwise AND 4732 # inside expression: binary & for bitwise AND
4086 # inside expression: unary & for taking the address of something 4733 # inside expression: unary & for taking the address of something
4087 # inside declarators: reference parameter 4734 # inside declarators: reference parameter
4088 # We will exclude the first two cases by checking that we are not inside a 4735 # We will exclude the first two cases by checking that we are not inside a
4089 # function body, including one that was just introduced by a trailing '{'. 4736 # function body, including one that was just introduced by a trailing '{'.
4090 # TODO(unknwon): Doesn't account for preprocessor directives.
4091 # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. 4737 # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare].
4092 check_params = False 4738 if (nesting_state.previous_stack_top and
4093 if not nesting_state.stack: 4739 not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or
4094 check_params = True # top level 4740 isinstance(nesting_state.previous_stack_top, _NamespaceInfo))):
4095 elif (isinstance(nesting_state.stack[-1], _ClassInfo) or 4741 # Not at toplevel, not within a class, and not within a namespace
4096 isinstance(nesting_state.stack[-1], _NamespaceInfo)): 4742 return
4097 check_params = True # within class or namespace 4743
4098 elif Match(r'.*{\s*$', line): 4744 # Avoid preprocessors
4099 if (len(nesting_state.stack) == 1 or 4745 if Search(r'\\\s*$', line):
4100 isinstance(nesting_state.stack[-2], _ClassInfo) or 4746 return
4101 isinstance(nesting_state.stack[-2], _NamespaceInfo)): 4747
4102 check_params = True # just opened global/class/namespace block 4748 # Avoid constructor initializer lists
4749 if IsInitializerList(clean_lines, linenum):
4750 return
4751
4103 # We allow non-const references in a few standard places, like functions 4752 # We allow non-const references in a few standard places, like functions
4104 # called "swap()" or iostream operators like "<<" or ">>". Do not check 4753 # called "swap()" or iostream operators like "<<" or ">>". Do not check
4105 # those function parameters. 4754 # those function parameters.
4106 # 4755 #
4107 # We also accept & in static_assert, which looks like a function but 4756 # We also accept & in static_assert, which looks like a function but
4108 # it's actually a declaration expression. 4757 # it's actually a declaration expression.
4109 whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|' 4758 whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|'
4110 r'operator\s*[<>][<>]|' 4759 r'operator\s*[<>][<>]|'
4111 r'static_assert|COMPILE_ASSERT' 4760 r'static_assert|COMPILE_ASSERT'
4112 r')\s*\(') 4761 r')\s*\(')
4113 if Search(whitelisted_functions, line): 4762 if Search(whitelisted_functions, line):
4114 check_params = False 4763 return
4115 elif not Search(r'\S+\([^)]*$', line): 4764 elif not Search(r'\S+\([^)]*$', line):
4116 # Don't see a whitelisted function on this line. Actually we 4765 # Don't see a whitelisted function on this line. Actually we
4117 # didn't see any function name on this line, so this is likely a 4766 # didn't see any function name on this line, so this is likely a
4118 # multi-line parameter list. Try a bit harder to catch this case. 4767 # multi-line parameter list. Try a bit harder to catch this case.
4119 for i in xrange(2): 4768 for i in xrange(2):
4120 if (linenum > i and 4769 if (linenum > i and
4121 Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): 4770 Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])):
4122 check_params = False 4771 return
4123 break
4124 4772
4125 if check_params: 4773 decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body
4126 decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body 4774 for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls):
4127 for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): 4775 if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter):
4128 if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter): 4776 error(filename, linenum, 'runtime/references', 2,
4129 error(filename, linenum, 'runtime/references', 2, 4777 'Is this a non-const reference? '
4130 'Is this a non-const reference? ' 4778 'If so, make const or use a pointer: ' +
4131 'If so, make const or use a pointer: ' + 4779 ReplaceAll(' *<', '<', parameter))
4132 ReplaceAll(' *<', '<', parameter)) 4780
4781
4782 def CheckCasts(filename, clean_lines, linenum, error):
4783 """Various cast related checks.
4784
4785 Args:
4786 filename: The name of the current file.
4787 clean_lines: A CleansedLines instance containing the file.
4788 linenum: The number of the line to check.
4789 error: The function to call with any errors found.
4790 """
4791 line = clean_lines.elided[linenum]
4792
4793 # Check to see if they're using an conversion function cast.
4794 # I just try to capture the most common basic types, though there are more.
4795 # Parameterless conversion functions, such as bool(), are allowed as they are
4796 # probably a member operator declaration or default constructor.
4797 match = Search(
4798 r'(\bnew\s+|\S<\s*(?:const\s+)?)?\b'
4799 r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
4800 r'(\([^)].*)', line)
4801 expecting_function = ExpectingFunctionArgs(clean_lines, linenum)
4802 if match and not expecting_function:
4803 matched_type = match.group(2)
4804
4805 # matched_new_or_template is used to silence two false positives:
4806 # - New operators
4807 # - Template arguments with function types
4808 #
4809 # For template arguments, we match on types immediately following
4810 # an opening bracket without any spaces. This is a fast way to
4811 # silence the common case where the function type is the first
4812 # template argument. False negative with less-than comparison is
4813 # avoided because those operators are usually followed by a space.
4814 #
4815 # function<double(double)> // bracket + no space = false positive
4816 # value < double(42) // bracket + space = true positive
4817 matched_new_or_template = match.group(1)
4818
4819 # Other things to ignore:
4820 # - Function pointers
4821 # - Casts to pointer types
4822 # - Placement new
4823 # - Alias declarations
4824 matched_funcptr = match.group(3)
4825 if (matched_new_or_template is None and
4826 not (matched_funcptr and
4827 (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(',
4828 matched_funcptr) or
4829 matched_funcptr.startswith('(*)'))) and
4830 not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and
4831 not Search(r'new\(\S+\)\s*' + matched_type, line)):
4832 error(filename, linenum, 'readability/casting', 4,
4833 'Using deprecated casting style. '
4834 'Use static_cast<%s>(...) instead' %
4835 matched_type)
4836
4837 if not expecting_function:
4838 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
4839 'static_cast',
4840 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
4841
4842 # This doesn't catch all cases. Consider (const char * const)"hello".
4843 #
4844 # (char *) "foo" should always be a const_cast (reinterpret_cast won't
4845 # compile).
4846 if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
4847 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error):
4848 pass
4849 else:
4850 # Check pointer casts for other than string constants
4851 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
4852 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
4853
4854 # In addition, we look for people taking the address of a cast. This
4855 # is dangerous -- casts can assign to temporaries, so the pointer doesn't
4856 # point where you think.
4857 match = Search(
4858 r'(?:&\(([^)]+)\)[\w(])|'
4859 r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line)
4860 if match and match.group(1) != '*':
4861 # Try a better error message when the & is bound to something
4862 # dereferenced by the casted pointer, as opposed to the casted
4863 # pointer itself.
4864 parenthesis_error = False
4865 match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line)
4866 if match:
4867 _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1)))
4868 if x1 >= 0 and clean_lines.elided[y1][x1] == '(':
4869 _, y2, x2 = CloseExpression(clean_lines, y1, x1)
4870 if x2 >= 0:
4871 extended_line = clean_lines.elided[y2][x2:]
4872 if y2 < clean_lines.NumLines() - 1:
4873 extended_line += clean_lines.elided[y2 + 1]
4874 if Match(r'\s*(?:->|\[)', extended_line):
4875 parenthesis_error = True
4876
4877 if parenthesis_error:
4878 error(filename, linenum, 'readability/casting', 4,
4879 ('Are you taking an address of something dereferenced '
4880 'from a cast? Wrapping the dereferenced expression in '
4881 'parentheses will make the binding more obvious'))
4882 else:
4883 error(filename, linenum, 'runtime/casting', 4,
4884 ('Are you taking an address of a cast? '
4885 'This is dangerous: could be a temp var. '
4886 'Take the address before doing the cast, rather than after'))
4133 4887
4134 4888
4135 def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, 4889 def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
4136 error): 4890 error):
4137 """Checks for a C-style cast by looking for the pattern. 4891 """Checks for a C-style cast by looking for the pattern.
4138 4892
4139 Args: 4893 Args:
4140 filename: The name of the current file. 4894 filename: The name of the current file.
4141 linenum: The number of the line to check. 4895 linenum: The number of the line to check.
4142 line: The line of code to check. 4896 line: The line of code to check.
4143 raw_line: The raw line of code to check, with comments. 4897 raw_line: The raw line of code to check, with comments.
4144 cast_type: The string for the C++ cast to recommend. This is either 4898 cast_type: The string for the C++ cast to recommend. This is either
4145 reinterpret_cast, static_cast, or const_cast, depending. 4899 reinterpret_cast, static_cast, or const_cast, depending.
4146 pattern: The regular expression used to find C-style casts. 4900 pattern: The regular expression used to find C-style casts.
4147 error: The function to call with any errors found. 4901 error: The function to call with any errors found.
4148 4902
4149 Returns: 4903 Returns:
4150 True if an error was emitted. 4904 True if an error was emitted.
4151 False otherwise. 4905 False otherwise.
4152 """ 4906 """
4153 match = Search(pattern, line) 4907 match = Search(pattern, line)
4154 if not match: 4908 if not match:
4155 return False 4909 return False
4156 4910
4157 # Exclude lines with sizeof, since sizeof looks like a cast. 4911 # Exclude lines with keywords that tend to look like casts, and also
4158 sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1]) 4912 # macros which are generally troublesome.
4159 if sizeof_match: 4913 if Match(r'.*\b(?:sizeof|alignof|alignas|[A-Z_]+)\s*$',
4914 line[0:match.start(1) - 1]):
4160 return False 4915 return False
4161 4916
4162 # operator++(int) and operator--(int) 4917 # operator++(int) and operator--(int)
4163 if (line[0:match.start(1) - 1].endswith(' operator++') or 4918 if (line[0:match.start(1) - 1].endswith(' operator++') or
4164 line[0:match.start(1) - 1].endswith(' operator--')): 4919 line[0:match.start(1) - 1].endswith(' operator--')):
4165 return False 4920 return False
4166 4921
4167 # A single unnamed argument for a function tends to look like old 4922 # A single unnamed argument for a function tends to look like old
4168 # style cast. If we see those, don't issue warnings for deprecated 4923 # style cast. If we see those, don't issue warnings for deprecated
4169 # casts, instead issue warnings for unnamed arguments where 4924 # casts, instead issue warnings for unnamed arguments where
(...skipping 11 matching lines...) Expand all
4181 # 4936 #
4182 # These are functions of some sort, where the compiler would be fine 4937 # These are functions of some sort, where the compiler would be fine
4183 # if they had named parameters, but people often omit those 4938 # if they had named parameters, but people often omit those
4184 # identifiers to reduce clutter: 4939 # identifiers to reduce clutter:
4185 # (FunctionPointer)(int); 4940 # (FunctionPointer)(int);
4186 # (FunctionPointer)(int) = value; 4941 # (FunctionPointer)(int) = value;
4187 # Function((function_pointer_arg)(int)) 4942 # Function((function_pointer_arg)(int))
4188 # <TemplateArgument(int)>; 4943 # <TemplateArgument(int)>;
4189 # <(FunctionPointerTemplateArgument)(int)>; 4944 # <(FunctionPointerTemplateArgument)(int)>;
4190 remainder = line[match.end(0):] 4945 remainder = line[match.end(0):]
4191 if Match(r'^\s*(?:;|const\b|throw\b|=|>|\{|\))', remainder): 4946 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|=|>|\{|\))',
4947 remainder):
4192 # Looks like an unnamed parameter. 4948 # Looks like an unnamed parameter.
4193 4949
4194 # Don't warn on any kind of template arguments. 4950 # Don't warn on any kind of template arguments.
4195 if Match(r'^\s*>', remainder): 4951 if Match(r'^\s*>', remainder):
4196 return False 4952 return False
4197 4953
4198 # Don't warn on assignments to function pointers, but keep warnings for 4954 # Don't warn on assignments to function pointers, but keep warnings for
4199 # unnamed parameters to pure virtual functions. Note that this pattern 4955 # unnamed parameters to pure virtual functions. Note that this pattern
4200 # will also pass on assignments of "0" to function pointers, but the 4956 # will also pass on assignments of "0" to function pointers, but the
4201 # preferred values for those would be "nullptr" or "NULL". 4957 # preferred values for those would be "nullptr" or "NULL".
(...skipping 17 matching lines...) Expand all
4219 return True 4975 return True
4220 4976
4221 # At this point, all that should be left is actual casts. 4977 # At this point, all that should be left is actual casts.
4222 error(filename, linenum, 'readability/casting', 4, 4978 error(filename, linenum, 'readability/casting', 4,
4223 'Using C-style cast. Use %s<%s>(...) instead' % 4979 'Using C-style cast. Use %s<%s>(...) instead' %
4224 (cast_type, match.group(1))) 4980 (cast_type, match.group(1)))
4225 4981
4226 return True 4982 return True
4227 4983
4228 4984
4985 def ExpectingFunctionArgs(clean_lines, linenum):
4986 """Checks whether where function type arguments are expected.
4987
4988 Args:
4989 clean_lines: A CleansedLines instance containing the file.
4990 linenum: The number of the line to check.
4991
4992 Returns:
4993 True if the line at 'linenum' is inside something that expects arguments
4994 of function types.
4995 """
4996 line = clean_lines.elided[linenum]
4997 return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
4998 (linenum >= 2 and
4999 (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
5000 clean_lines.elided[linenum - 1]) or
5001 Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
5002 clean_lines.elided[linenum - 2]) or
5003 Search(r'\bstd::m?function\s*\<\s*$',
5004 clean_lines.elided[linenum - 1]))))
5005
5006
4229 _HEADERS_CONTAINING_TEMPLATES = ( 5007 _HEADERS_CONTAINING_TEMPLATES = (
4230 ('<deque>', ('deque',)), 5008 ('<deque>', ('deque',)),
4231 ('<functional>', ('unary_function', 'binary_function', 5009 ('<functional>', ('unary_function', 'binary_function',
4232 'plus', 'minus', 'multiplies', 'divides', 'modulus', 5010 'plus', 'minus', 'multiplies', 'divides', 'modulus',
4233 'negate', 5011 'negate',
4234 'equal_to', 'not_equal_to', 'greater', 'less', 5012 'equal_to', 'not_equal_to', 'greater', 'less',
4235 'greater_equal', 'less_equal', 5013 'greater_equal', 'less_equal',
4236 'logical_and', 'logical_or', 'logical_not', 5014 'logical_and', 'logical_or', 'logical_not',
4237 'unary_negate', 'not1', 'binary_negate', 'not2', 5015 'unary_negate', 'not1', 'binary_negate', 'not2',
4238 'bind1st', 'bind2nd', 5016 'bind1st', 'bind2nd',
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
4460 'build/include_what_you_use', 4, 5238 'build/include_what_you_use', 4,
4461 'Add #include ' + required_header_unstripped + ' for ' + template) 5239 'Add #include ' + required_header_unstripped + ' for ' + template)
4462 5240
4463 5241
4464 _RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') 5242 _RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<')
4465 5243
4466 5244
4467 def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): 5245 def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
4468 """Check that make_pair's template arguments are deduced. 5246 """Check that make_pair's template arguments are deduced.
4469 5247
4470 G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are 5248 G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are
4471 specified explicitly, and such use isn't intended in any case. 5249 specified explicitly, and such use isn't intended in any case.
4472 5250
4473 Args: 5251 Args:
4474 filename: The name of the current file. 5252 filename: The name of the current file.
4475 clean_lines: A CleansedLines instance containing the file. 5253 clean_lines: A CleansedLines instance containing the file.
4476 linenum: The number of the line to check. 5254 linenum: The number of the line to check.
4477 error: The function to call with any errors found. 5255 error: The function to call with any errors found.
4478 """ 5256 """
4479 line = clean_lines.elided[linenum] 5257 line = clean_lines.elided[linenum]
4480 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) 5258 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)
4481 if match: 5259 if match:
4482 error(filename, linenum, 'build/explicit_make_pair', 5260 error(filename, linenum, 'build/explicit_make_pair',
4483 4, # 4 = high confidence 5261 4, # 4 = high confidence
4484 'For C++11-compatibility, omit template arguments from make_pair' 5262 'For C++11-compatibility, omit template arguments from make_pair'
4485 ' OR use pair directly OR if appropriate, construct a pair directly') 5263 ' OR use pair directly OR if appropriate, construct a pair directly')
5264 def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error):
5265 """Check that default lambda captures are not used.
5266
5267 Args:
5268 filename: The name of the current file.
5269 clean_lines: A CleansedLines instance containing the file.
5270 linenum: The number of the line to check.
5271 error: The function to call with any errors found.
5272 """
5273 line = clean_lines.elided[linenum]
5274
5275 # A lambda introducer specifies a default capture if it starts with "[="
5276 # or if it starts with "[&" _not_ followed by an identifier.
5277 match = Match(r'^(.*)\[\s*(?:=|&[^\w])', line)
5278 if match:
5279 # Found a potential error, check what comes after the lambda-introducer.
5280 # If it's not open parenthesis (for lambda-declarator) or open brace
5281 # (for compound-statement), it's not a lambda.
5282 line, _, pos = CloseExpression(clean_lines, linenum, len(match.group(1)))
5283 if pos >= 0 and Match(r'^\s*[{(]', line[pos:]):
5284 error(filename, linenum, 'build/c++11',
5285 4, # 4 = high confidence
5286 'Default lambda captures are an unapproved C++ feature.')
5287
5288
4486 5289
4487 5290
4488 def ProcessLine(filename, file_extension, clean_lines, line, 5291 def ProcessLine(filename, file_extension, clean_lines, line,
4489 include_state, function_state, nesting_state, error, 5292 include_state, function_state, nesting_state, error,
4490 extra_check_functions=[]): 5293 extra_check_functions=[]):
4491 """Processes a single line in the file. 5294 """Processes a single line in the file.
4492 5295
4493 Args: 5296 Args:
4494 filename: Filename of the file that is being processed. 5297 filename: Filename of the file that is being processed.
4495 file_extension: The extension (dot not included) of the file. 5298 file_extension: The extension (dot not included) of the file.
4496 clean_lines: An array of strings, each representing a line of the file, 5299 clean_lines: An array of strings, each representing a line of the file,
4497 with comments stripped. 5300 with comments stripped.
4498 line: Number of line being processed. 5301 line: Number of line being processed.
4499 include_state: An _IncludeState instance in which the headers are inserted. 5302 include_state: An _IncludeState instance in which the headers are inserted.
4500 function_state: A _FunctionState instance which counts function lines, etc. 5303 function_state: A _FunctionState instance which counts function lines, etc.
4501 nesting_state: A _NestingState instance which maintains information about 5304 nesting_state: A NestingState instance which maintains information about
4502 the current stack of nested blocks being parsed. 5305 the current stack of nested blocks being parsed.
4503 error: A callable to which errors are reported, which takes 4 arguments: 5306 error: A callable to which errors are reported, which takes 4 arguments:
4504 filename, line number, error level, and message 5307 filename, line number, error level, and message
4505 extra_check_functions: An array of additional check functions that will be 5308 extra_check_functions: An array of additional check functions that will be
4506 run on each source line. Each function takes 4 5309 run on each source line. Each function takes 4
4507 arguments: filename, clean_lines, line, error 5310 arguments: filename, clean_lines, line, error
4508 """ 5311 """
4509 raw_lines = clean_lines.raw_lines 5312 raw_lines = clean_lines.raw_lines
4510 ParseNolintSuppressions(filename, raw_lines[line], line, error) 5313 ParseNolintSuppressions(filename, raw_lines[line], line, error)
4511 nesting_state.Update(filename, clean_lines, line, error) 5314 nesting_state.Update(filename, clean_lines, line, error)
4512 if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM: 5315 if nesting_state.InAsmBlock(): return
4513 return
4514 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) 5316 CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
4515 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) 5317 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
4516 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) 5318 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)
4517 CheckLanguage(filename, clean_lines, line, file_extension, include_state, 5319 CheckLanguage(filename, clean_lines, line, file_extension, include_state,
4518 nesting_state, error) 5320 nesting_state, error)
4519 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) 5321 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error)
4520 CheckForNonStandardConstructs(filename, clean_lines, line, 5322 CheckForNonStandardConstructs(filename, clean_lines, line,
4521 nesting_state, error) 5323 nesting_state, error)
4522 CheckVlogArguments(filename, clean_lines, line, error) 5324 CheckVlogArguments(filename, clean_lines, line, error)
4523 CheckPosixThreading(filename, clean_lines, line, error) 5325 CheckPosixThreading(filename, clean_lines, line, error)
4524 CheckInvalidIncrement(filename, clean_lines, line, error) 5326 CheckInvalidIncrement(filename, clean_lines, line, error)
4525 CheckMakePairUsesDeduction(filename, clean_lines, line, error) 5327 CheckMakePairUsesDeduction(filename, clean_lines, line, error)
5328 CheckDefaultLambdaCaptures(filename, clean_lines, line, error)
4526 for check_fn in extra_check_functions: 5329 for check_fn in extra_check_functions:
4527 check_fn(filename, clean_lines, line, error) 5330 check_fn(filename, clean_lines, line, error)
5331
5332 def FlagCxx11Features(filename, clean_lines, linenum, error):
5333 """Flag those c++11 features that we only allow in certain places.
5334
5335 Args:
5336 filename: The name of the current file.
5337 clean_lines: A CleansedLines instance containing the file.
5338 linenum: The number of the line to check.
5339 error: The function to call with any errors found.
5340 """
5341 line = clean_lines.elided[linenum]
5342
5343 # Flag unapproved C++11 headers.
5344 include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line)
5345 if include and include.group(1) in ('cfenv',
5346 'condition_variable',
5347 'fenv.h',
5348 'future',
5349 'mutex',
5350 'thread',
5351 'chrono',
5352 'ratio',
5353 'regex',
5354 'system_error',
5355 ):
5356 error(filename, linenum, 'build/c++11', 5,
5357 ('<%s> is an unapproved C++11 header.') % include.group(1))
5358
5359 # The only place where we need to worry about C++11 keywords and library
5360 # features in preprocessor directives is in macro definitions.
5361 if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return
5362
5363 # These are classes and free functions. The classes are always
5364 # mentioned as std::*, but we only catch the free functions if
5365 # they're not found by ADL. They're alphabetical by header.
5366 for top_name in (
5367 # type_traits
5368 'alignment_of',
5369 'aligned_union',
5370
5371 # utility
5372 'forward',
5373 ):
5374 if Search(r'\bstd::%s\b' % top_name, line):
5375 error(filename, linenum, 'build/c++11', 5,
5376 ('std::%s is an unapproved C++11 class or function. Send c-style '
5377 'an example of where it would make your code more readable, and '
5378 'they may let you use it.') % top_name)
5379
4528 5380
4529 def ProcessFileData(filename, file_extension, lines, error, 5381 def ProcessFileData(filename, file_extension, lines, error,
4530 extra_check_functions=[]): 5382 extra_check_functions=[]):
4531 """Performs lint checks and reports any errors to the given error function. 5383 """Performs lint checks and reports any errors to the given error function.
4532 5384
4533 Args: 5385 Args:
4534 filename: Filename of the file that is being processed. 5386 filename: Filename of the file that is being processed.
4535 file_extension: The extension (dot not included) of the file. 5387 file_extension: The extension (dot not included) of the file.
4536 lines: An array of strings, each representing a line of the file, with the 5388 lines: An array of strings, each representing a line of the file, with the
4537 last element being empty if the file is terminated with a newline. 5389 last element being empty if the file is terminated with a newline.
4538 error: A callable to which errors are reported, which takes 4 arguments: 5390 error: A callable to which errors are reported, which takes 4 arguments:
4539 filename, line number, error level, and message 5391 filename, line number, error level, and message
4540 extra_check_functions: An array of additional check functions that will be 5392 extra_check_functions: An array of additional check functions that will be
4541 run on each source line. Each function takes 4 5393 run on each source line. Each function takes 4
4542 arguments: filename, clean_lines, line, error 5394 arguments: filename, clean_lines, line, error
4543 """ 5395 """
4544 lines = (['// marker so line numbers and indices both start at 1'] + lines + 5396 lines = (['// marker so line numbers and indices both start at 1'] + lines +
4545 ['// marker so line numbers end in a known way']) 5397 ['// marker so line numbers end in a known way'])
4546 5398
4547 include_state = _IncludeState() 5399 include_state = _IncludeState()
4548 function_state = _FunctionState() 5400 function_state = _FunctionState()
4549 nesting_state = _NestingState() 5401 nesting_state = NestingState()
4550 5402
4551 ResetNolintSuppressions() 5403 ResetNolintSuppressions()
4552 5404
4553 CheckForCopyright(filename, lines, error) 5405 CheckForCopyright(filename, lines, error)
4554 5406
4555 if file_extension == 'h': 5407 if file_extension == 'h':
4556 CheckForHeaderGuard(filename, lines, error) 5408 CheckForHeaderGuard(filename, lines, error)
4557 5409
4558 RemoveMultiLineComments(filename, lines, error) 5410 RemoveMultiLineComments(filename, lines, error)
4559 clean_lines = CleansedLines(lines) 5411 clean_lines = CleansedLines(lines)
4560 for line in xrange(clean_lines.NumLines()): 5412 for line in xrange(clean_lines.NumLines()):
4561 ProcessLine(filename, file_extension, clean_lines, line, 5413 ProcessLine(filename, file_extension, clean_lines, line,
4562 include_state, function_state, nesting_state, error, 5414 include_state, function_state, nesting_state, error,
4563 extra_check_functions) 5415 extra_check_functions)
5416 FlagCxx11Features(filename, clean_lines, line, error)
4564 nesting_state.CheckCompletedBlocks(filename, error) 5417 nesting_state.CheckCompletedBlocks(filename, error)
4565 5418
4566 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) 5419 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
4567 5420
4568 # We check here rather than inside ProcessLine so that we see raw 5421 # We check here rather than inside ProcessLine so that we see raw
4569 # lines rather than "cleaned" lines. 5422 # lines rather than "cleaned" lines.
4570 CheckForBadCharacters(filename, lines, error) 5423 CheckForBadCharacters(filename, lines, error)
4571 5424
4572 CheckForNewlineAtEOF(filename, lines, error) 5425 CheckForNewlineAtEOF(filename, lines, error)
4573 5426
5427
4574 def ProcessFile(filename, vlevel, extra_check_functions=[]): 5428 def ProcessFile(filename, vlevel, extra_check_functions=[]):
4575 """Does google-lint on a single file. 5429 """Does google-lint on a single file.
4576 5430
4577 Args: 5431 Args:
4578 filename: The name of the file to parse. 5432 filename: The name of the file to parse.
4579 5433
4580 vlevel: The level of errors to report. Every error of confidence 5434 vlevel: The level of errors to report. Every error of confidence
4581 >= verbose_level will be reported. 0 is a good default. 5435 >= verbose_level will be reported. 0 is a good default.
4582 5436
4583 extra_check_functions: An array of additional check functions that will be 5437 extra_check_functions: An array of additional check functions that will be
4584 run on each source line. Each function takes 4 5438 run on each source line. Each function takes 4
4585 arguments: filename, clean_lines, line, error 5439 arguments: filename, clean_lines, line, error
4586 """ 5440 """
4587 5441
4588 _SetVerboseLevel(vlevel) 5442 _SetVerboseLevel(vlevel)
4589 5443
5444 lf_lines = []
5445 crlf_lines = []
4590 try: 5446 try:
4591 # Support the UNIX convention of using "-" for stdin. Note that 5447 # Support the UNIX convention of using "-" for stdin. Note that
4592 # we are not opening the file with universal newline support 5448 # we are not opening the file with universal newline support
4593 # (which codecs doesn't support anyway), so the resulting lines do 5449 # (which codecs doesn't support anyway), so the resulting lines do
4594 # contain trailing '\r' characters if we are reading a file that 5450 # contain trailing '\r' characters if we are reading a file that
4595 # has CRLF endings. 5451 # has CRLF endings.
4596 # If after the split a trailing '\r' is present, it is removed 5452 # If after the split a trailing '\r' is present, it is removed
4597 # below. If it is not expected to be present (i.e. os.linesep != 5453 # below.
4598 # '\r\n' as in Windows), a warning is issued below if this file
4599 # is processed.
4600
4601 if filename == '-': 5454 if filename == '-':
4602 lines = codecs.StreamReaderWriter(sys.stdin, 5455 lines = codecs.StreamReaderWriter(sys.stdin,
4603 codecs.getreader('utf8'), 5456 codecs.getreader('utf8'),
4604 codecs.getwriter('utf8'), 5457 codecs.getwriter('utf8'),
4605 'replace').read().split('\n') 5458 'replace').read().split('\n')
4606 else: 5459 else:
4607 lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') 5460 lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
4608 5461
4609 carriage_return_found = False
4610 # Remove trailing '\r'. 5462 # Remove trailing '\r'.
4611 for linenum in range(len(lines)): 5463 # The -1 accounts for the extra trailing blank line we get from split()
5464 for linenum in range(len(lines) - 1):
4612 if lines[linenum].endswith('\r'): 5465 if lines[linenum].endswith('\r'):
4613 lines[linenum] = lines[linenum].rstrip('\r') 5466 lines[linenum] = lines[linenum].rstrip('\r')
4614 carriage_return_found = True 5467 crlf_lines.append(linenum + 1)
5468 else:
5469 lf_lines.append(linenum + 1)
4615 5470
4616 except IOError: 5471 except IOError:
4617 sys.stderr.write( 5472 sys.stderr.write(
4618 "Skipping input '%s': Can't open for reading\n" % filename) 5473 "Skipping input '%s': Can't open for reading\n" % filename)
4619 return 5474 return
4620 5475
4621 # Note, if no dot is found, this will give the entire filename as the ext. 5476 # Note, if no dot is found, this will give the entire filename as the ext.
4622 file_extension = filename[filename.rfind('.') + 1:] 5477 file_extension = filename[filename.rfind('.') + 1:]
4623 5478
4624 # When reading from stdin, the extension is unknown, so no cpplint tests 5479 # When reading from stdin, the extension is unknown, so no cpplint tests
4625 # should rely on the extension. 5480 # should rely on the extension.
4626 if filename != '-' and file_extension not in _valid_extensions: 5481 if filename != '-' and file_extension not in _valid_extensions:
4627 sys.stderr.write('Ignoring %s; not a valid file name ' 5482 sys.stderr.write('Ignoring %s; not a valid file name '
4628 '(%s)\n' % (filename, ', '.join(_valid_extensions))) 5483 '(%s)\n' % (filename, ', '.join(_valid_extensions)))
4629 else: 5484 else:
4630 ProcessFileData(filename, file_extension, lines, Error, 5485 ProcessFileData(filename, file_extension, lines, Error,
4631 extra_check_functions) 5486 extra_check_functions)
4632 if carriage_return_found and os.linesep != '\r\n': 5487
4633 # Use 0 for linenum since outputting only one error for potentially 5488 # If end-of-line sequences are a mix of LF and CR-LF, issue
4634 # several lines. 5489 # warnings on the lines with CR.
4635 Error(filename, 0, 'whitespace/newline', 1, 5490 #
4636 'One or more unexpected \\r (^M) found;' 5491 # Don't issue any warnings if all lines are uniformly LF or CR-LF,
4637 'better to use only a \\n') 5492 # since critique can handle these just fine, and the style guide
5493 # doesn't dictate a particular end of line sequence.
5494 #
5495 # We can't depend on os.linesep to determine what the desired
5496 # end-of-line sequence should be, since that will return the
5497 # server-side end-of-line sequence.
5498 if lf_lines and crlf_lines:
5499 # Warn on every line with CR. An alternative approach might be to
5500 # check whether the file is mostly CRLF or just LF, and warn on the
5501 # minority, we bias toward LF here since most tools prefer LF.
5502 for linenum in crlf_lines:
5503 Error(filename, linenum, 'whitespace/newline', 1,
5504 'Unexpected \\r (^M) found; better to use only \\n')
4638 5505
4639 sys.stderr.write('Done processing %s\n' % filename) 5506 sys.stderr.write('Done processing %s\n' % filename)
4640 5507
4641 5508
4642 def PrintUsage(message): 5509 def PrintUsage(message):
4643 """Prints a brief usage string and exits, optionally with an error message. 5510 """Prints a brief usage string and exits, optionally with an error message.
4644 5511
4645 Args: 5512 Args:
4646 message: The optional error message. 5513 message: The optional error message.
4647 """ 5514 """
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
4744 _cpplint_state.ResetErrorCounts() 5611 _cpplint_state.ResetErrorCounts()
4745 for filename in filenames: 5612 for filename in filenames:
4746 ProcessFile(filename, _cpplint_state.verbose_level) 5613 ProcessFile(filename, _cpplint_state.verbose_level)
4747 _cpplint_state.PrintErrorCounts() 5614 _cpplint_state.PrintErrorCounts()
4748 5615
4749 sys.exit(_cpplint_state.error_count > 0) 5616 sys.exit(_cpplint_state.error_count > 0)
4750 5617
4751 5618
4752 if __name__ == '__main__': 5619 if __name__ == '__main__':
4753 main() 5620 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698