Refactor __main__.main into smaller functions

This commit is contained in:
dgelessus 2019-09-13 12:36:37 +02:00
parent 194c886472
commit 51ae7c6a09

View File

@ -214,7 +214,7 @@ def _describe_resource(res: api.Resource, *, include_type: bool, decompress: boo
desc = f"'{restype}' {desc}" desc = f"'{restype}' {desc}"
return desc return desc
def main(): def _parse_args() -> argparse.Namespace:
ap = argparse.ArgumentParser( ap = argparse.ArgumentParser(
add_help=False, add_help=False,
fromfile_prefix_chars="@", fromfile_prefix_chars="@",
@ -249,82 +249,62 @@ def main():
ap.add_argument("filter", nargs="*", help="One or more filters to select which resources to display, or omit to show an overview of all resources") ap.add_argument("filter", nargs="*", help="One or more filters to select which resources to display, or omit to show an overview of all resources")
ns = ap.parse_args() ns = ap.parse_args()
return ns
if ns.file == "-": def _show_header_data(data: bytes, *, format: str) -> None:
if ns.fork is not None: if format == "dump":
print("Cannot specify an explicit fork when reading from stdin", file=sys.stderr)
sys.exit(1)
rf = api.ResourceFile(sys.stdin.buffer)
else:
rf = api.ResourceFile.open(ns.file, fork=ns.fork)
with rf:
if ns.header_system or ns.header_application:
if ns.header_system:
data = rf.header_system_data
else:
data = rf.header_application_data
if ns.format == "dump":
_hexdump(data) _hexdump(data)
elif ns.format == "hex": elif format == "hex":
_raw_hexdump(data) _raw_hexdump(data)
elif ns.format == "raw": elif format == "raw":
sys.stdout.buffer.write(data) sys.stdout.buffer.write(data)
elif ns.format == "derez": elif format == "derez":
print("Cannot output file header data in derez format", file=sys.stderr) print("Cannot output file header data in derez format", file=sys.stderr)
sys.exit(1) sys.exit(1)
else: else:
raise ValueError(f"Unhandled output format: {ns.format}") raise ValueError(f"Unhandled output format: {format}")
elif ns.filter or ns.all:
if ns.filter:
resources = _filter_resources(rf, ns.filter)
else:
resources = []
for reses in rf.values():
resources.extend(reses.values())
def _show_filtered_resources(resources: typing.Sequence[api.Resource], format: str, decompress: bool) -> None:
if not resources: if not resources:
if ns.format == "dump": if format == "dump":
print("No resources matched the filter") print("No resources matched the filter")
elif ns.format in ("hex", "raw"): elif format in ("hex", "raw"):
print("No resources matched the filter", file=sys.stderr) print("No resources matched the filter", file=sys.stderr)
sys.exit(1) sys.exit(1)
elif ns.format == "derez": elif format == "derez":
print("/* No resources matched the filter */") print("/* No resources matched the filter */")
else: else:
raise AssertionError(f"Unhandled output format: {ns.format}") raise AssertionError(f"Unhandled output format: {format}")
elif ns.format in ("hex", "raw") and len(resources) != 1: elif format in ("hex", "raw") and len(resources) != 1:
print(f"Format {ns.format} can only output a single resource, but the filter matched {len(resources)} resources", file=sys.stderr) print(f"Format {format} can only output a single resource, but the filter matched {len(resources)} resources", file=sys.stderr)
sys.exit(1) sys.exit(1)
for res in resources: for res in resources:
if ns.decompress: if decompress:
data = res.data data = res.data
else: else:
data = res.data_raw data = res.data_raw
if ns.format == "dump": if format == "dump":
# Human-readable info and hex dump # Human-readable info and hex dump
desc = _describe_resource(res, include_type=True, decompress=ns.decompress) desc = _describe_resource(res, include_type=True, decompress=decompress)
print(f"Resource {desc}:") print(f"Resource {desc}:")
_hexdump(data) _hexdump(data)
print() print()
elif ns.format == "hex": elif format == "hex":
# Data only as hex # Data only as hex
_raw_hexdump(data) _raw_hexdump(data)
elif ns.format == "raw": elif format == "raw":
# Data only as raw bytes # Data only as raw bytes
sys.stdout.buffer.write(data) sys.stdout.buffer.write(data)
elif ns.format == "derez": elif format == "derez":
# Like DeRez with no resource definitions # Like DeRez with no resource definitions
attrs = list(_decompose_flags(res.attributes)) attrs = list(_decompose_flags(res.attributes))
if ns.decompress and api.ResourceAttrs.resCompressed in attrs: if decompress and api.ResourceAttrs.resCompressed in attrs:
attrs.remove(api.ResourceAttrs.resCompressed) attrs.remove(api.ResourceAttrs.resCompressed)
attrs_comment = " /* was compressed */" attrs_comment = " /* was compressed */"
else: else:
@ -363,8 +343,9 @@ def main():
print("};") print("};")
print() print()
else: else:
raise ValueError(f"Unhandled output format: {ns.format}") raise ValueError(f"Unhandled output format: {format}")
else:
def _list_resource_file(rf: api.ResourceFile, *, decompress: bool) -> None:
if rf.header_system_data != bytes(len(rf.header_system_data)): if rf.header_system_data != bytes(len(rf.header_system_data)):
print("Header system data:") print("Header system data:")
_hexdump(rf.header_system_data) _hexdump(rf.header_system_data)
@ -383,11 +364,43 @@ def main():
restype = _bytes_escape(typecode, quote="'") restype = _bytes_escape(typecode, quote="'")
print(f"'{restype}': {len(resources)} resources:") print(f"'{restype}': {len(resources)} resources:")
for resid, res in rf[typecode].items(): for resid, res in rf[typecode].items():
print(_describe_resource(res, include_type=False, decompress=ns.decompress)) print(_describe_resource(res, include_type=False, decompress=decompress))
print() print()
else: else:
print("No resource types (empty resource file)") print("No resource types (empty resource file)")
def main():
ns = _parse_args()
if ns.file == "-":
if ns.fork is not None:
print("Cannot specify an explicit fork when reading from stdin", file=sys.stderr)
sys.exit(1)
rf = api.ResourceFile(sys.stdin.buffer)
else:
rf = api.ResourceFile.open(ns.file, fork=ns.fork)
with rf:
if ns.header_system or ns.header_application:
if ns.header_system:
data = rf.header_system_data
else:
data = rf.header_application_data
_show_header_data(data, format=ns.format)
elif ns.filter or ns.all:
if ns.filter:
resources = _filter_resources(rf, ns.filter)
else:
resources = []
for reses in rf.values():
resources.extend(reses.values())
_show_filtered_resources(resources, format=ns.format, decompress=ns.decompress)
else:
_list_resource_file(rf, decompress=ns.decompress)
sys.exit(0) sys.exit(0)
if __name__ == "__main__": if __name__ == "__main__":