EricWF updated this revision to Diff 91145.
EricWF added a comment.

This still isn't working in python3 due to more bytes vs str issues, but this 
is my progress so far.


https://reviews.llvm.org/D30773

Files:
  tools/clang-format/git-clang-format

Index: tools/clang-format/git-clang-format
===================================================================
--- tools/clang-format/git-clang-format
+++ tools/clang-format/git-clang-format
@@ -23,6 +23,7 @@
 Requires Python 2.7                                                              
 """               
 
+from __future__ import print_function
 import argparse
 import collections
 import contextlib
@@ -138,15 +139,15 @@
   if opts.verbose >= 1:
     ignored_files.difference_update(changed_lines)
     if ignored_files:
-      print 'Ignoring changes in the following files (wrong extension):'
+      print('Ignoring changes in the following files (wrong extension):')
       for filename in ignored_files:
-        print '   ', filename
+        print('    %s' % filename)
     if changed_lines:
-      print 'Running clang-format on the following files:'
+      print('Running clang-format on the following files:')
       for filename in changed_lines:
-        print '   ', filename
+        print('    %s' % filename)
   if not changed_lines:
-    print 'no modified files to format'
+    print('no modified files to format')
     return
   # The computed diff outputs absolute paths, so we must cd before accessing
   # those files.
@@ -163,20 +164,20 @@
                                                  binary=opts.binary,
                                                  style=opts.style)
   if opts.verbose >= 1:
-    print 'old tree:', old_tree
-    print 'new tree:', new_tree
+    print('old tree:', old_tree)
+    print('new tree:', new_tree)
   if old_tree == new_tree:
     if opts.verbose >= 0:
-      print 'clang-format did not modify any files'
+      print('clang-format did not modify any files')
   elif opts.diff:
     print_diff(old_tree, new_tree)
   else:
     changed_files = apply_changes(old_tree, new_tree, force=opts.force,
                                   patch_mode=opts.patch)
     if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1:
-      print 'changed files:'
+      print('changed files:')
       for filename in changed_files:
-        print '   ', filename
+        print('    %s' % filename)
 
 
 def load_git_config(non_string_options=None):
@@ -188,9 +189,9 @@
   if non_string_options is None:
     non_string_options = {}
   out = {}
-  for entry in run('git', 'config', '--list', '--null').split('\0'):
+  for entry in run('git', 'config', '--list', '--null').split(b'\0'):
     if entry:
-      name, value = entry.split('\n', 1)
+      name, value = entry.split(b'\n', 1)
       if name in non_string_options:
         value = run('git', 'config', non_string_options[name], name)
       out[name] = value
@@ -289,6 +290,25 @@
   return p
 
 
+def to_bytes(str):
+    # Encode to UTF-8 to get binary data.
+    if isinstance(str, bytes):
+        return str
+    return str.encode('utf-8')
+
+def to_string(bytes):
+    if isinstance(bytes, str):
+        return bytes
+    return to_bytes(bytes)
+
+def convert_string(bytes):
+    try:
+        return to_string(bytes.decode('utf-8'))
+    except AttributeError: # 'str' object has no attribute 'decode'.
+        return str(bytes)
+    except UnicodeError:
+        return str(bytes)
+
 def extract_lines(patch_file):
   """Extract the changed lines in `patch_file`.
 
@@ -300,10 +320,10 @@
   list of line `Range`s."""
   matches = {}
   for line in patch_file:
-    match = re.search(r'^\+\+\+\ [^/]+/(.*)', line)
+    match = re.search(to_bytes(r'^\+\+\+\ [^/]+/(.*)'), line)
     if match:
-      filename = match.group(1).rstrip('\r\n')
-    match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line)
+      filename = match.group(1).rstrip(b'\r\n')
+    match = re.search(to_bytes(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?'), line)
     if match:
       start_line = int(match.group(1))
       line_count = 1
@@ -320,10 +340,14 @@
   `allowed_extensions` must be a collection of lowercase file extensions,
   excluding the period."""
   allowed_extensions = frozenset(allowed_extensions)
-  for filename in dictionary.keys():
-    base_ext = filename.rsplit('.', 1)
+  keys_to_delete = []
+  for filename in list(dictionary.keys()):
+    filename_cp = convert_string(bytes(filename))
+    base_ext = filename_cp.rsplit('.', 1)
     if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions:
-      del dictionary[filename]
+      keys_to_delete += [filename]
+  for key in keys_to_delete:
+    del dictionary[key]
 
 
 def cd_to_toplevel():
@@ -345,7 +369,7 @@
 
   Returns the object ID (SHA-1) of the created tree."""
   def index_info_generator():
-    for filename, line_ranges in changed_lines.iteritems():
+    for filename, line_ranges in changed_lines.items():
       if revision:
         git_metadata_cmd = ['git', 'ls-tree',
                             '%s:%s' % (revision, os.path.dirname(filename)),
@@ -376,7 +400,8 @@
   with temporary_index_file():
     p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
     for line in input_lines:
-      p.stdin.write('%s\0' % line)
+      # FIXME: This is really really broken in python3
+      p.stdin.write(b'%s\0' % to_bytes(line))
     p.stdin.close()
     if p.wait() != 0:
       die('`%s` failed' % ' '.join(cmd))
@@ -420,7 +445,7 @@
     else:
       raise
   clang_format_stdin.close()
-  hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin']
+  hash_object_cmd = ['git', 'hash-object', '-w', '--path='+convert_string(filename), '--stdin']
   hash_object = subprocess.Popen(hash_object_cmd, stdin=clang_format.stdout,
                                  stdout=subprocess.PIPE)
   clang_format.stdout.close()
@@ -431,7 +456,7 @@
     die('`%s` failed' % ' '.join(clang_format_cmd))
   if git_show and git_show.wait() != 0:
     die('`%s` failed' % ' '.join(git_show_cmd))
-  return stdout.rstrip('\r\n')
+  return stdout.rstrip(b'\r\n')
 
 
 @contextlib.contextmanager
@@ -457,6 +482,7 @@
   If `tree` is not None, use that as the tree to read in.  Otherwise, an
   empty index is created."""
   gitdir = run('git', 'rev-parse', '--git-dir')
+  gitdir = convert_string(gitdir)
   path = os.path.join(gitdir, temp_index_basename)
   if tree is None:
     tree = '--empty'
@@ -488,10 +514,10 @@
   if not force:
     unstaged_files = run('git', 'diff-files', '--name-status', *changed_files)
     if unstaged_files:
-      print >>sys.stderr, ('The following files would be modified but '
-                           'have unstaged changes:')
-      print >>sys.stderr, unstaged_files
-      print >>sys.stderr, 'Please commit, stage, or stash them first.'
+      print('The following files would be modified but have unstaged changes:',
+            file=sys.stderr)
+      print(unstaged_files, file=sys.stderr)
+      print('Please commit, stage, or stash them first.', file=sys.stderr)
       sys.exit(2)
   if patch_mode:
     # In patch mode, we could just as well create an index from the new tree
@@ -521,20 +547,20 @@
   if p.returncode == 0:
     if stderr:
       if verbose:
-        print >>sys.stderr, '`%s` printed to stderr:' % ' '.join(args)
-      print >>sys.stderr, stderr.rstrip()
+        print('`%s` printed to stderr:' % ' '.join(args), file=sys.stderr)
+      print(stderr.rstrip(), file=sys.stderr)
     if strip:
-      stdout = stdout.rstrip('\r\n')
+      stdout = stdout.rstrip(b'\r\n')
     return stdout
   if verbose:
-    print >>sys.stderr, '`%s` returned %s' % (' '.join(args), p.returncode)
+    print('`%s` returned %s' % (' '.join(args), p.returncode), file=sys.stderr)
   if stderr:
-    print >>sys.stderr, stderr.rstrip()
+    print(stderr.rstrip(), file=sys.stderr)
   sys.exit(2)
 
 
 def die(message):
-  print >>sys.stderr, 'error:', message
+  print('error:', message, file=sys.stderr)
   sys.exit(2)
 
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to