Make script portable across Python versions

Support both Python 2 and 3.
This commit is contained in:
Steven Myint
2014-03-07 09:12:10 -08:00
committed by Thiago de Arruda
parent f479abddd7
commit 1fb6612dc0

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python
# #
# Copyright (c) 2009 Google Inc. All rights reserved. # Copyright (c) 2009 Google Inc. All rights reserved.
# #
@@ -41,6 +41,11 @@ We do a small hack, which is to ignore //'s with "'s after them on the
same line, but it is far from perfect (in either direction). same line, but it is far from perfect (in either direction).
""" """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import codecs import codecs
import copy import copy
import getopt import getopt
@@ -763,7 +768,7 @@ class _CppLintState(object):
def PrintErrorCounts(self): def PrintErrorCounts(self):
"""Print a summary of errors by category, and the total.""" """Print a summary of errors by category, and the total."""
for category, count in self.errors_by_category.iteritems(): for category, count in self.errors_by_category.items():
sys.stderr.write('Category \'%s\' errors found: %d\n' % sys.stderr.write('Category \'%s\' errors found: %d\n' %
(category, count)) (category, count))
sys.stderr.write('Total errors found: %d\n' % self.error_count) sys.stderr.write('Total errors found: %d\n' % self.error_count)
@@ -1248,7 +1253,7 @@ def FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar):
On finding matching endchar: (index just after matching endchar, 0) On finding matching endchar: (index just after matching endchar, 0)
Otherwise: (-1, new depth at end of this line) Otherwise: (-1, new depth at end of this line)
""" """
for i in xrange(startpos, len(line)): for i in range(startpos, len(line)):
if line[i] == startchar: if line[i] == startchar:
depth += 1 depth += 1
elif line[i] == endchar: elif line[i] == endchar:
@@ -1321,7 +1326,7 @@ def FindStartOfExpressionInLine(line, endpos, depth, startchar, endchar):
On finding matching startchar: (index at matching startchar, 0) On finding matching startchar: (index at matching startchar, 0)
Otherwise: (-1, new depth at beginning of this line) Otherwise: (-1, new depth at beginning of this line)
""" """
for i in xrange(endpos, -1, -1): for i in range(endpos, -1, -1):
if line[i] == endchar: if line[i] == endchar:
depth += 1 depth += 1
elif line[i] == startchar: elif line[i] == startchar:
@@ -1381,7 +1386,7 @@ def CheckForCopyright(filename, lines, error):
# We'll say it should occur by line 10. Don't forget there's a # We'll say it should occur by line 10. Don't forget there's a
# dummy line at the front. # dummy line at the front.
for line in xrange(1, min(len(lines), 11)): for line in range(1, min(len(lines), 11)):
if re.search(r'Copyright', lines[line], re.I): break if re.search(r'Copyright', lines[line], re.I): break
else: # means no copyright line was found else: # means no copyright line was found
error(filename, 0, 'legal/copyright', 5, error(filename, 0, 'legal/copyright', 5,
@@ -2313,8 +2318,6 @@ def CheckForFunctionLengths(filename, clean_lines, linenum,
""" """
lines = clean_lines.lines lines = clean_lines.lines
line = lines[linenum] line = lines[linenum]
raw = clean_lines.raw_lines
raw_line = raw[linenum]
joined_line = '' joined_line = ''
starting_func = False starting_func = False
@@ -2330,7 +2333,7 @@ def CheckForFunctionLengths(filename, clean_lines, linenum,
if starting_func: if starting_func:
body_found = False body_found = False
for start_linenum in xrange(linenum, clean_lines.NumLines()): for start_linenum in range(linenum, clean_lines.NumLines()):
start_line = lines[start_linenum] start_line = lines[start_linenum]
joined_line += ' ' + start_line.lstrip() joined_line += ' ' + start_line.lstrip()
if Search(r'(;|})', start_line): # Declarations and trivial functions if Search(r'(;|})', start_line): # Declarations and trivial functions
@@ -2853,7 +2856,7 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
trailing_text = '' trailing_text = ''
if endpos > -1: if endpos > -1:
trailing_text = endline[endpos:] trailing_text = endline[endpos:]
for offset in xrange(endlinenum + 1, for offset in range(endlinenum + 1,
min(endlinenum + 3, clean_lines.NumLines() - 1)): min(endlinenum + 3, clean_lines.NumLines() - 1)):
trailing_text += clean_lines.elided[offset] trailing_text += clean_lines.elided[offset]
if not Match(r'^[\s}]*[{.;,)<\]]', trailing_text): if not Match(r'^[\s}]*[{.;,)<\]]', trailing_text):
@@ -3224,7 +3227,7 @@ def CheckCheck(filename, clean_lines, linenum, error):
expression = lines[linenum][start_pos + 1:end_pos - 1] expression = lines[linenum][start_pos + 1:end_pos - 1]
else: else:
expression = lines[linenum][start_pos + 1:] expression = lines[linenum][start_pos + 1:]
for i in xrange(linenum + 1, end_line): for i in range(linenum + 1, end_line):
expression += lines[i] expression += lines[i]
expression += last_line[0:end_pos - 1] expression += last_line[0:end_pos - 1]
@@ -3352,7 +3355,7 @@ def GetLineWidth(line):
The width of the line in column positions, accounting for Unicode The width of the line in column positions, accounting for Unicode
combining characters and wide characters. combining characters and wide characters.
""" """
if isinstance(line, unicode): if isinstance(line, str):
width = 0 width = 0
for uc in unicodedata.normalize('NFC', line): for uc in unicodedata.normalize('NFC', line):
if unicodedata.east_asian_width(uc) in ('W', 'F'): if unicodedata.east_asian_width(uc) in ('W', 'F'):
@@ -3683,7 +3686,7 @@ def _GetTextInside(text, start_pattern):
# Give opening punctuations to get the matching close-punctuations. # Give opening punctuations to get the matching close-punctuations.
matching_punctuation = {'(': ')', '{': '}', '[': ']'} matching_punctuation = {'(': ')', '{': '}', '[': ']'}
closing_punctuation = set(matching_punctuation.itervalues()) closing_punctuation = set(matching_punctuation.values())
# Find the position to start extracting text. # Find the position to start extracting text.
match = re.search(start_pattern, text, re.M) match = re.search(start_pattern, text, re.M)
@@ -3773,9 +3776,6 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line): if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line):
include_state.ResetSection() include_state.ResetSection()
# Make Windows paths like Unix.
fullname = os.path.abspath(filename).replace('\\', '/')
# TODO(unknown): figure out if they're using default arguments in fn proto. # TODO(unknown): figure out if they're using default arguments in fn proto.
# Check to see if they're using an conversion function cast. # Check to see if they're using an conversion function cast.
@@ -3856,14 +3856,6 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
'This is dangerous: could be a temp var. ' 'This is dangerous: could be a temp var. '
'Take the address before doing the cast, rather than after')) 'Take the address before doing the cast, rather than after'))
# Create an extended_line, which is the concatenation of the current and
# next lines, for more effective checking of code that may span more than one
# line.
if linenum + 1 < clean_lines.NumLines():
extended_line = line + clean_lines.elided[linenum + 1]
else:
extended_line = line
# Check for people declaring static/global STL strings at the top level. # Check for people declaring static/global STL strings at the top level.
# This is dangerous because the C++ language does not guarantee that # This is dangerous because the C++ language does not guarantee that
# globals with constructors are initialized before the first access. # globals with constructors are initialized before the first access.
@@ -4100,7 +4092,7 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
# Found the matching < on an earlier line, collect all # Found the matching < on an earlier line, collect all
# pieces up to current line. # pieces up to current line.
line = '' line = ''
for i in xrange(startline, linenum + 1): for i in range(startline, linenum + 1):
line += clean_lines.elided[i].strip() line += clean_lines.elided[i].strip()
# Check for non-const references in function parameters. A single '&' may # Check for non-const references in function parameters. A single '&' may
@@ -4139,7 +4131,7 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
# Don't see a whitelisted function on this line. Actually we # Don't see a whitelisted function on this line. Actually we
# didn't see any function name on this line, so this is likely a # didn't see any function name on this line, so this is likely a
# multi-line parameter list. Try a bit harder to catch this case. # multi-line parameter list. Try a bit harder to catch this case.
for i in xrange(2): for i in range(2):
if (linenum > i and if (linenum > i and
Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])):
check_params = False check_params = False
@@ -4412,7 +4404,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
required = {} # A map of header name to linenumber and the template entity. required = {} # A map of header name to linenumber and the template entity.
# Example of required: { '<functional>': (1219, 'less<>') } # Example of required: { '<functional>': (1219, 'less<>') }
for linenum in xrange(clean_lines.NumLines()): for linenum in range(clean_lines.NumLines()):
line = clean_lines.elided[linenum] line = clean_lines.elided[linenum]
if not line or line[0] == '#': if not line or line[0] == '#':
continue continue
@@ -4460,7 +4452,7 @@ def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
# include_state is modified during iteration, so we iterate over a copy of # include_state is modified during iteration, so we iterate over a copy of
# the keys. # the keys.
header_keys = include_state.keys() header_keys = list(include_state.keys())
for header in header_keys: for header in header_keys:
(same_module, common_path) = FilesBelongToSameModule(abs_filename, header) (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
fullpath = common_path + header fullpath = common_path + header
@@ -4580,7 +4572,7 @@ def ProcessFileData(filename, file_extension, lines, error,
RemoveMultiLineComments(filename, lines, error) RemoveMultiLineComments(filename, lines, error)
clean_lines = CleansedLines(lines) clean_lines = CleansedLines(lines)
for line in xrange(clean_lines.NumLines()): for line in range(clean_lines.NumLines()):
ProcessLine(filename, file_extension, clean_lines, line, ProcessLine(filename, file_extension, clean_lines, line,
include_state, function_state, nesting_state, error, include_state, function_state, nesting_state, error,
extra_check_functions) extra_check_functions)
@@ -4757,13 +4749,6 @@ def ParseArguments(args):
def main(): def main():
filenames = ParseArguments(sys.argv[1:]) filenames = ParseArguments(sys.argv[1:])
# Change stderr to write with replacement characters so we don't die
# if we try to print something containing non-ASCII characters.
sys.stderr = codecs.StreamReaderWriter(sys.stderr,
codecs.getreader('utf8'),
codecs.getwriter('utf8'),
'replace')
_cpplint_state.ResetErrorCounts() _cpplint_state.ResetErrorCounts()
for filename in filenames: for filename in filenames:
ProcessFile(filename, _cpplint_state.verbose_level) ProcessFile(filename, _cpplint_state.verbose_level)