mirror of https://github.com/openXC7/prjxray.git
156 lines
3.9 KiB
Python
Executable File
156 lines
3.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright (C) 2017-2020 The Project X-Ray Authors.
|
|
#
|
|
# Use of this source code is governed by a ISC-style
|
|
# license that can be found in the LICENSE file or at
|
|
# https://opensource.org/licenses/ISC
|
|
#
|
|
# SPDX-License-Identifier: ISC
|
|
"""
|
|
This tool allows to view segbits using a 2D frame vs. bit plot. It can read
|
|
either mask.db files or segbits.db files. Multiple files can be read at once
|
|
allowing to identify where a bit comes from.
|
|
|
|
When a single file is read, a bit is marked as "O". When multiple files are
|
|
read, a bit is denoted with a letter "A", "B" and so on depending on index
|
|
of file that it belongs to.
|
|
|
|
Duplicate bits (present in more than one files) are marked with "#"
|
|
"""
|
|
|
|
import sys
|
|
import argparse
|
|
import re
|
|
|
|
from prjxray.util import OpenSafeFile
|
|
|
|
# =============================================================================
|
|
|
|
|
|
def load_just_bits(file_name):
|
|
"""
|
|
Read bits from a .db or .rdb file. Ignores tags and bit values.
|
|
"""
|
|
|
|
with OpenSafeFile(file_name, "r") as fp:
|
|
lines = fp.readlines()
|
|
|
|
bits = set()
|
|
for line in lines:
|
|
for word in line.split(" "):
|
|
match = re.match("^(!?)([0-9]+)_([0-9]+)$", word)
|
|
if match is not None:
|
|
frm = int(match.group(2))
|
|
bit = int(match.group(3))
|
|
|
|
bits.add((
|
|
frm,
|
|
bit,
|
|
))
|
|
|
|
return bits
|
|
|
|
|
|
# =============================================================================
|
|
|
|
|
|
def main():
|
|
|
|
# Colors for TTY
|
|
if sys.stdout.isatty():
|
|
|
|
bit_colors = [
|
|
"\033[39m",
|
|
"\033[91m",
|
|
"\033[92m",
|
|
"\033[93m",
|
|
"\033[94m",
|
|
"\033[95m",
|
|
"\033[96m",
|
|
"\033[31m",
|
|
"\033[32m",
|
|
"\033[33m",
|
|
"\033[34m",
|
|
"\033[35m",
|
|
"\033[36m",
|
|
]
|
|
|
|
colors = {
|
|
"NONE": "\033[0m",
|
|
"DUPLICATE": "\033[101;97m",
|
|
}
|
|
|
|
# Colors for pipe
|
|
else:
|
|
|
|
bit_colors = [""]
|
|
|
|
colors = {
|
|
"NONE": "",
|
|
"DUPLICATE": "",
|
|
}
|
|
|
|
# .........................................................................
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
|
|
parser.add_argument("files", nargs="*", type=str, help="Input files")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Load bits
|
|
all_bits = []
|
|
for i, f in enumerate(args.files):
|
|
bits = load_just_bits(f)
|
|
all_bits.append(bits)
|
|
|
|
cstr = bit_colors[i % len(bit_colors)]
|
|
bstr = "O" if len(args.files) == 1 else chr(65 + i)
|
|
print(cstr + bstr + colors["NONE"] + ": %s #%d" % (f, len(bits)))
|
|
|
|
print("")
|
|
|
|
max_frames = max([bit[0] for bits in all_bits for bit in bits]) + 1
|
|
max_bits = max([bit[1] for bits in all_bits for bit in bits]) + 1
|
|
|
|
# Header
|
|
for r in range(3):
|
|
line = " " * 3
|
|
for c in range(max_bits):
|
|
bstr = "%03d" % c
|
|
line += bstr[r]
|
|
print(line)
|
|
|
|
print("")
|
|
|
|
# Display bits
|
|
for r in range(max_frames):
|
|
line = "%2d " % r
|
|
for c in range(max_bits):
|
|
got_bit = False
|
|
bit_str = colors["NONE"] + "-"
|
|
for i, bits in enumerate(all_bits):
|
|
cstr = bit_colors[i % len(bit_colors)]
|
|
bstr = "O" if len(args.files) == 1 else chr(65 + i)
|
|
if (r, c) in bits:
|
|
if not got_bit:
|
|
bit_str = cstr + bstr
|
|
else:
|
|
bit_str = colors["DUPLICATE"] + "#" + colors["NONE"]
|
|
got_bit = True
|
|
|
|
line += bit_str
|
|
|
|
line += colors["NONE"]
|
|
print(line)
|
|
|
|
|
|
# =============================================================================
|
|
|
|
if __name__ == "__main__":
|
|
main()
|