| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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() | 
| OLD | NEW | 
|---|