scripts: dbgblock.py: Allow multiple blocks, matching dbgcat.py

I mean, why not. dbgblock.py is already a bit special compared to the
other dbg scripts:

  $ ./scripts/dbgblock.py disk -b4096 0 1 -n16
  block 0x0, size 16, cksum a90f45b6
  00000000: 68 69 21 0e 00 03 00 08 6c 69 74 74 6c 65 66 73  hi!.....littlefs
  block 0x1, size 16, cksum 01e5f5e4
  00000000: 68 69 21 0c 80 03 00 08 6c 69 74 74 6c 65 66 73  hi!.....littlefs

This matches dbgcat.py, which is useful when switching between the two
for debugging pipelines, etc.

We want dbgblock.py/dbgcat.py to be as identical as possible, and if you
removed the multiple blocks from dbgcat.py you'd have to really start
asking why it's named dbgCAT.py.
This commit is contained in:
Christopher Haster
2025-03-16 01:32:20 -05:00
parent c028735741
commit cb9d14cc15
+34 -12
View File
@@ -4,6 +4,7 @@
if __name__ == "__main__": if __name__ == "__main__":
__import__('sys').path.pop(0) __import__('sys').path.pop(0)
import itertools as it
import os import os
@@ -85,7 +86,7 @@ def crc32c(data, crc=0):
crc = (crc >> 1) ^ ((crc & 1) * 0x82f63b78) crc = (crc >> 1) ^ ((crc & 1) * 0x82f63b78)
return 0xffffffff ^ crc return 0xffffffff ^ crc
def main(disk, block=None, *, def main(disk, blocks=None, *,
block_size=None, block_size=None,
block_count=None, block_count=None,
off=None, off=None,
@@ -103,15 +104,31 @@ def main(disk, block=None, *,
f.seek(0, os.SEEK_END) f.seek(0, os.SEEK_END)
block_size = f.tell() block_size = f.tell()
# block may also encode an offset # if block_count is omitted, derive the block_count from our file size
block, off, size = ( if block_count is None:
block[0] if isinstance(block, tuple) f.seek(0, os.SEEK_END)
else block, block_count = f.tell() // block_size
off.start if isinstance(off, slice)
# flatten blocks, default to block 0
blocks = (list(it.chain.from_iterable(
range(block.start or 0, block.stop or block_count)
if isinstance(block, slice)
else block
for block in blocks))
if blocks
else [0])
# blocks may also encode offsets
blocks, offs, size = (
[block[0] if isinstance(block, tuple)
else block
for block in blocks],
[off.start if isinstance(off, slice)
else off if off is not None else off if off is not None
else size.start if isinstance(size, slice) else size.start if isinstance(size, slice)
else block[1] if isinstance(block, tuple) else block[1] if isinstance(block, tuple)
else None, else None
for block in blocks],
(size.stop - (size.start or 0) (size.stop - (size.start or 0)
if size.stop is not None if size.stop is not None
else None) if isinstance(size, slice) else None) if isinstance(size, slice)
@@ -121,7 +138,8 @@ def main(disk, block=None, *,
else None) if isinstance(off, slice) else None) if isinstance(off, slice)
else None) else None)
# bound to block_size # hexdump the blocks
for block, off in zip(blocks, offs):
block_ = block if block is not None else 0 block_ = block if block is not None else 0
off_ = off if off is not None else 0 off_ = off if off is not None else 0
size_ = size if size is not None else block_size - off_ size_ = size if size is not None else block_size - off_
@@ -156,10 +174,14 @@ if __name__ == "__main__":
'disk', 'disk',
help="File containing the block device.") help="File containing the block device.")
parser.add_argument( parser.add_argument(
'block', 'blocks',
nargs='?', nargs='*',
type=lambda x: (lambda x: x)(*rbydaddr(x)), type=lambda x: (
help="Block address.") slice(*(int(x, 0) if x.strip() else None
for x in x.split(',', 1)))
if ',' in x and '{' not in x
else rbydaddr(x)),
help="Block addresses, may be a range.")
parser.add_argument( parser.add_argument(
'-b', '--block-size', '-b', '--block-size',
type=bdgeom, type=bdgeom,