Tobias Hieta dd3c26a045
[NFC][Py Reformat] Reformat python files in clang and clang-tools-extra
This is an ongoing series of commits that are reformatting our
Python code.

Reformatting is done with `black`.

If you end up having problems merging this commit because you
have made changes to a python file, the best way to handle that
is to run git checkout --ours <yourfile> and then reformat it
with black.

If you run into any problems, post to discourse about it and
we will try to help.

RFC Thread below:

https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style

Reviewed By: MatzeB

Differential Revision: https://reviews.llvm.org/D150761
2023-05-23 08:29:52 +02:00

117 lines
3.4 KiB
Python
Executable File

#!/usr/bin/env python
from __future__ import absolute_import, division, print_function
import argparse
import difflib
import filecmp
import os
import subprocess
import sys
disassembler = "objdump"
def keep_line(line):
"""Returns true for lines that should be compared in the disassembly
output."""
return "file format" not in line
def disassemble(objfile):
"""Disassemble object to a file."""
p = subprocess.Popen(
[disassembler, "-d", objfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
(out, err) = p.communicate()
if p.returncode or err:
print("Disassemble failed: {}".format(objfile))
sys.exit(1)
return [line for line in out.split(os.linesep) if keep_line(line)]
def dump_debug(objfile):
"""Dump all of the debug info from a file."""
p = subprocess.Popen(
[disassembler, "-WliaprmfsoRt", objfile],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
(out, err) = p.communicate()
if p.returncode or err:
print("Dump debug failed: {}".format(objfile))
sys.exit(1)
return [line for line in out.split(os.linesep) if keep_line(line)]
def first_diff(a, b, fromfile, tofile):
"""Returns the first few lines of a difference, if there is one. Python
diff can be very slow with large objects and the most interesting changes
are the first ones. Truncate data before sending to difflib. Returns None
is there is no difference."""
# Find first diff
first_diff_idx = None
for idx, val in enumerate(a):
if val != b[idx]:
first_diff_idx = idx
break
if first_diff_idx == None:
# No difference
return None
# Diff to first line of diff plus some lines
context = 3
diff = difflib.unified_diff(
a[: first_diff_idx + context], b[: first_diff_idx + context], fromfile, tofile
)
difference = "\n".join(diff)
if first_diff_idx + context < len(a):
difference += "\n*** Diff truncated ***"
return difference
def compare_object_files(objfilea, objfileb):
"""Compare disassembly of two different files.
Allowing unavoidable differences, such as filenames.
Return the first difference if the disassembly differs, or None.
"""
disa = disassemble(objfilea)
disb = disassemble(objfileb)
return first_diff(disa, disb, objfilea, objfileb)
def compare_debug_info(objfilea, objfileb):
"""Compare debug info of two different files.
Allowing unavoidable differences, such as filenames.
Return the first difference if the debug info differs, or None.
If there are differences in the code, there will almost certainly be differences in the debug info too.
"""
dbga = dump_debug(objfilea)
dbgb = dump_debug(objfileb)
return first_diff(dbga, dbgb, objfilea, objfileb)
def compare_exact(objfilea, objfileb):
"""Byte for byte comparison between object files.
Returns True if equal, False otherwise.
"""
return filecmp.cmp(objfilea, objfileb)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("objfilea", nargs=1)
parser.add_argument("objfileb", nargs=1)
parser.add_argument("-v", "--verbose", action="store_true")
args = parser.parse_args()
diff = compare_object_files(args.objfilea[0], args.objfileb[0])
if diff:
print("Difference detected")
if args.verbose:
print(diff)
sys.exit(1)
else:
print("The same")