#!/usr/bin/env python3 import sys, re, traceback from argparse import ArgumentParser def convert(s): if s.lower().startswith('0x'): return int(s, 16) elif s.lower().startswith('0b'): return int(s, 2) else: return int(s) class Table: def __init__(self, value, numbers): self.value = value self.numbers = numbers def print(self): self.print_border() self.print_numbers() self.print_border() self.print_bits() self.print_border() def print_border(self): total_w = 4 * len(self.numbers) + 2 for i in range(total_w): c = '+' if i == 0 or i == total_w-1 else '-' print(c, end='') print() def print_numbers(self): print('|', end='') for n in reversed(self.numbers): print(' %s ' % (str(n).rjust(2)), end='') print('|') def print_bits(self): print('|', end='') for n in reversed(self.numbers): b = (self.value >> n) & 1 print(' %s ' % (str(b).rjust(2)), end='') print('|') def main(): parser = ArgumentParser(description='inspect values by bits') parser.add_argument('-s', '--size', type=int, default=32, choices=(4, 8, 16, 32, 64), help='size') parser.add_argument('-r', '--range', help='range (e.g. 31:28), numbers are inclusive') parser.add_argument('value') args = parser.parse_args() value = convert(args.value) if value.bit_length() > args.size: raise Exception('bit length of %s is %d which is larger than specified size %d' % (args.value, value.bit_length(), args.size)) if args.range: r = re.search('^(\d+):(\d+)$', args.range) if not r: raise Exception('invalid range specified') r_to = int(r.group(2)) r_from = int(r.group(1)) if r_to < 0 or r_from < 0 or r_to >= args.size or r_from >= args.size: raise Exception('specified range is out of bounds') else: r_to = 0 r_from = args.size - 1 numbers = range(r_to, r_from + 1) table = Table(value, numbers) table.print() print() print(' Input: %s' % args.value) print(' Binary: %s' % bin(value)[2:]) print('Decimal: %d' % value) print(' Hex: %s' % hex(value)[2:]) print() if args.range: new_value = value >> r_to mask = (2 ** (r_from - r_to + 1) - 1) new_value &= mask print(' [%d:%d]' % (r_from, r_to)) print(' Binary: %s' % bin(new_value)[2:]) print('Decimal: %d' % new_value) print(' Hex: %s' % hex(new_value)[2:]) if __name__ == '__main__': try: main() except Exception as e: print("error: %s" % str(e)) traceback.print_tb(e.__traceback__)