scripts: maps: Cleaned up comments and junk

This took a bit of a messy route, but these scripts should be good to go
now.
This commit is contained in:
Christopher Haster
2025-04-11 02:58:00 -05:00
parent 50f652d44f
commit 5e817be9cc
3 changed files with 0 additions and 1557 deletions
-617
View File
@@ -3851,8 +3851,6 @@ def punescape(s, attrs=None):
return re.sub(pattern, unescape, s)
# TODO sync these
# naive space filling curve (the default)
def naive_curve(width, height):
for y in range(height):
@@ -4065,580 +4063,6 @@ class BmapBlock:
}
# a mergable range set type
class RangeSet:
def __init__(self, ranges=None):
self._ranges = []
if ranges is not None:
# using add here makes sure all ranges are merged/sorted
# correctly
for r in ranges:
self.add(r)
def __repr__(self):
return 'RangeSet(%r)' % self._ranges
def __contains__(self, k):
i = bisect.bisect(self._ranges, k,
key=lambda r: r.start) - 1
if i > -1:
return k in self._ranges[i]
else:
return False
def __bool__(self):
return bool(self._ranges)
def ranges(self):
yield from self._ranges
def __iter__(self):
for r in self._ranges:
yield from r
def add(self, r):
assert isinstance(r, range)
# trivial range?
if not r:
return
# find earliest possible merge point
ranges = self._ranges
i = bisect.bisect_left(ranges, r.start,
key=lambda r: r.stop)
# copy ranges < merge
merged = ranges[:i]
# merge ranges and append
while i < len(ranges) and ranges[i].start <= r.stop:
r = range(
min(ranges[i].start, r.start),
max(ranges[i].stop, r.stop))
i += 1
merged.append(r)
# copy ranges > merge
merged.extend(ranges[i:])
self._ranges = merged
def remove(self, r):
assert isinstance(r, range)
# trivial range?
if not r:
return
# find earliest possible carve point
ranges = self._ranges
i = bisect.bisect_left(ranges, r.start,
key=lambda r: r.stop)
# copy ranges < carve
carved = ranges[:i]
# carve overlapping ranges, note this can split ranges
while i < len(ranges) and ranges[i].start <= r.stop:
if ranges[i].start < r.start:
carved.append(range(ranges[i].start, r.start))
if ranges[i].stop > r.stop:
carved.append(range(r.stop, ranges[i].stop))
i += 1
# copy ranges > carve
carved.extend(ranges[i:])
self._ranges = carved
@property
def start(self):
if not self._ranges:
return 0
else:
return self._ranges[0].start
@property
def stop(self):
if not self._ranges:
return 0
else:
return self._ranges[-1].stop
def __len__(self):
return self.stop
def copy(self):
# create a shallow copy
ranges = RangeSet()
ranges._ranges = self._ranges.copy()
return ranges
def __getitem__(self, slice_):
assert isinstance(slice_, slice)
# create a copy
ranges = self.copy()
# just use remove to do the carving, it's good enough probably
if slice_.stop is not None:
ranges.remove(range(slice_.stop, len(self)))
if slice_.start is not None:
ranges.remove(range(0, slice_.start))
ranges._ranges = [range(
r.start - slice_.start,
r.stop - slice_.start)
for r in ranges._ranges]
return ranges
def __ior__(self, other):
for r in other.ranges():
self.add(r)
return self
def __or__(self, other):
ranges = self.copy()
ranges |= other
return ranges
# a mergable range dict type
class RangeDict:
def __init__(self, ranges=None):
self._ranges = []
if ranges is not None:
# using __setitem__ here makes sure all ranges are
# merged/sorted correctly
for r, v in ranges:
self[r] = v
def __repr__(self):
return 'RangeDict(%r)' % self._ranges
def _get(self, k):
i = bisect.bisect(self._ranges, k,
key=lambda rv: rv[0].start) - 1
if i > -1:
return self._ranges[i][1]
else:
raise KeyError(k)
def get(self, k, d=None):
try:
return self._get(k)
except KeyError:
return d
def __getitem__(self, k):
# special case for slicing
if isinstance(k, slice):
return self._slice(k)
else:
return self._get(k)
def __contains__(self, k):
try:
self._get(k)
return True
except KeyError:
return False
def __bool__(self):
return bool(self._ranges)
def ranges(self):
yield from self._ranges
def __iter__(self):
for r, v in self._ranges:
for k in r:
yield k, v
# apply a function to a range
def map(self, r, f):
assert isinstance(r, range)
# trivial range?
if not r:
return
# find earliest possible merge point
ranges = self._ranges
i = bisect.bisect_left(ranges, r.start,
key=lambda rv: rv[0].stop)
# copy ranges < merge
merged = ranges[:i]
# map, merge/carve ranges
while i < len(ranges) and ranges[i][0].start <= r.stop:
# carve prefix
if ranges[i][0].start < r.start:
merged.append((
range(ranges[i][0].start, r.start),
ranges[i][1]))
# need fill?
if ranges[i][0].start > r.start:
v = f(None)
# merge?
if (merged
and merged[-1][0].stop >= r.start
and merged[-1][1] == v):
merged[-1] = (
range(
merged[-1][0].start,
ranges[i][0].start),
merged[-1][1])
else:
merged.append((
range(r.start, ranges[i][0].start),
f(None)))
# apply f
v = f(ranges[i][1])
# merge?
if (merged
and merged[-1][0].stop >= r.start
and merged[-1][1] == v):
merged[-1] = (
range(
merged[-1][0].start,
min(ranges[i][0].stop, r.stop)),
merged[-1][1])
else:
merged.append((
range(
r.start,
min(ranges[i][0].stop, r.stop)),
v))
r = range(
min(ranges[i][0].stop, r.stop),
r.stop)
# carve suffix
if ranges[i][0].stop > r.stop:
# merge?
if ranges[i][1] == v:
merged[-1] = (
range(
merged[-1][0].start,
ranges[i][0].stop),
merged[-1][1])
else:
merged.append((
range(r.stop, ranges[i][0].stop),
ranges[i][1]))
i += 1
# need fill?
if not merged or merged[-1][0].stop < r.stop:
v = f(None)
# merge?
if (merged
and merged[-1][0].stop >= r.start
and merged[-1][1] == v):
merged[-1] = (
range(merged[-1][0].start, r.stop),
merged[-1][1])
else:
merged.append((r, v))
# copy ranges > merge
merged.extend(ranges[i:])
self._ranges = merged
def __setitem__(self, r, v):
# we can define __setitem__ using map
assert isinstance(r, range)
self.map(r, lambda _: v)
def __delitem__(self, r):
# __delitem__ is a bit more complicated
assert isinstance(r, range)
# trivial range?
if not r:
return
# find earliest possible carve point
ranges = self._ranges
i = bisect.bisect_left(ranges, r.start,
key=lambda rv: rv[0].stop)
# copy ranges < carve
carved = ranges[:i]
# carve overlapping ranges, note this can split ranges
while i < len(ranges) and ranges[i][0].start <= r.stop:
if ranges[i][0].start < r.start:
carved.append((
range(ranges[i][0].start, r.start),
ranges[i][1]))
if ranges[i][0].stop > r.stop:
carved.append((
range(r.stop, ranges[i][0].stop),
ranges[i][1]))
i += 1
# copy ranges > carve
carved.extend(ranges[i:])
self._ranges = carved
@property
def start(self):
if not self._ranges:
return 0
else:
return self._ranges[0][0].start
@property
def stop(self):
if not self._ranges:
return 0
else:
return self._ranges[-1][0].stop
def __len__(self):
return self.stop
def copy(self):
# create a shallow copy
ranges = RangeDict()
ranges._ranges = self._ranges.copy()
return ranges
def _slice(self, slice_):
assert isinstance(slice_, slice)
# create a copy
ranges = RangeDict()
ranges._ranges = self._ranges
# just use __delitem__ to do the carving, it's good enough probably
if slice_.stop is not None:
del ranges[range(slice_.stop, len(self))]
if slice_.start is not None:
del ranges[range(0, slice_.start)]
ranges._ranges = [(
range(
r.start - slice_.start,
r.stop - slice_.start),
v)
for r, v in ranges._ranges]
return ranges
def __ior__(self, other):
for r, v in other.ranges():
self[r] = v
return self
def __or__(self, other):
ranges = self.copy()
ranges |= other
return ranges
## a representation of a range of blocks/offs to show
#class BmapSlice:
# def __init__(self, blocks=None, off=None, size=None):
# self.orig_blocks = blocks
# self.orig_off = off
# self.orig_size = size
#
# # flatten blocks, default to all blocks
# blocks = ([blocks] if isinstance(blocks, slice)
# else list(it.chain.from_iterable(
# [blocks_] if isinstance(blocks_, slice) else blocks_
# for blocks_ in blocks))
# if blocks is not None
# else [slice(None)])
#
# # 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 size.start if isinstance(size, slice)
# else block[1] if isinstance(block, tuple)
# else None
# for block in blocks],
# (size.stop - (size.start or 0)
# if size.stop is not None
# else None) if isinstance(size, slice)
# else size if size is not None
# else ((off.stop - (off.start or 0))
# if off.stop is not None
# else None) if isinstance(off, slice)
# else None)
#
# self.blocks = blocks
# self.offs = offs
# self.size = size
#
# @property
# def off(self):
# if not self.offs:
# return None
# else:
# return self.offs[-1]
#
# def __repr__(self):
# return 'BmapSlice(%r, %r, %r)' % (
# self.orig_blocks,
# self.orig_off,
# self.orig_size)
#
# def slices(self, block_size, block_count):
# for block, off in zip(self.blocks, self.offs):
# # figure out off range, bound to block_size
# off = off if off is not None else 0
# size = self.size if self.size is not None else block_size - off
# if off >= block_size:
# continue
# size = min(off + size, block_size) - off
#
# # flatten/filter blocks
# if isinstance(block, slice):
# start = block.start if block.start is not None else 0
# stop = block.stop if block.stop is not None else block_count
# for block_ in range(start, min(stop, block_count)):
# yield block_, off, size
# else:
# block = block if block is not None else 0
# if block < block_count:
# yield block, off, size
#
# def blocks(self, block_count):
# for block in self.blocks:
# # flatten/filter blocks
# if isinstance(block, slice):
# start = block.start if block.start is not None else 0
# stop = block.stop if block.stop is not None else block_count
# for block_ in range(start, min(stop, block_count)):
# yield block_
# else:
# block = block if block is not None else 0
# if block < block_count:
# yield block
#
# def sorted_slices(self, block_size, block_count):
# # merge block ranges
# blocks = RangeDict()
# for block in self.blocks:
# # figure out off range, bound to block_size
# off = off if off is not None else 0
# size = self.size if self.size is not None else block_size - off
# if off >= block_size:
# continue
# size = min(off + size, block_size) - off
#
# # flatten/filter blocks
# if isinstance(block, slice):
# start = block.start if block.start is not None else 0
# stop = block.stop if block.stop is not None else block_count
# blocks.map(range(start, min(stop, block_count)),
# lambda r: (r if r is not None else RangeSet())
# | RangeSet([range(off, off+size)]))
# else:
# block = block if block is not None else 0
# if block < block_count:
# blocks.map(range(block, block+1),
# lambda r: (r if r is not None else RangeSet())
# | RangeSet([range(off, off+size)]))
#
# for block, r in blocks:
# for off, stop in r:
# yield off, stop-off
#
# def sorted_blocks(self, block_count):
# # merge block ranges
# blocks = RangeSet()
# for block in self.blocks:
# # flatten/filter blocks
# if isinstance(block, slice):
# start = block.start if block.start is not None else 0
# stop = block.stop if block.stop is not None else block_count
# blocks.add(range(start, min(stop, block_count)))
# else:
# block = block if block is not None else 0
# if block < block_count:
# blocks.add(range(block, block+1))
#
# yield from blocks
#
#
#
## # merge block ranges
## merged = []
## for blocks, offs in zip(self.blocks, self.offs):
## # simplify blocks first
## if not isinstance(blocks, slice):
## blocks = slice(blocks, blocks+1)
## blocks = slice(
## blocks.start if blocks.start is not None else 0,
## blocks.start if blocks.start is not None else block_count)
##
## # copy ranges before merge
## i = 0
## merged_ = []
## blocks_ = blocks
## while i < len(merged) and merged[i].stop < blocks_.start:
## merged_.append(merged[i])
##
## # merge ranges and append
## while i < len(merged) and merged[i].start <= blocks_.stop:
## blocks_ = slice(
## min(merged[i].start, blocks_.start),
## max(merged[i].stop, blocks_.stop))
## merged_.append(blocks_)
##
## # and copy the rest
## merged_.extend(merged[i:])
##
##
##
##
##
## for blocks_ in merged:
## # merge ranges?
## if blocks_
## else
#
#
# def __contains__(self, block):
# if isinstance(block, tuple):
# block, off = block
# else:
# block, off = block, None
#
# for block_, off_ in zip(self.blocks, self.offs):
# # in off range?
# if off is not None:
# off_ = off_ if off_ is not None else 0
# size_ = self.size
# if not (off >= off_
# and (size_ is None or off < off_ + size_)):
# continue
#
# # in block range?
# if isinstance(block_, slice):
# if ((block_.start is None or block >= block_.start)
# and (block_.stop is None or block < block_.stop)):
# return True
# else:
# if block_ is None or block == block_:
# return True
#
# return False
def main(disk, output, mroots=None, *,
trunk=None,
@@ -5799,47 +5223,6 @@ if __name__ == "__main__":
'--block-count',
type=lambda x: int(x, 0),
help="Block count in blocks.")
# # subparser for block arguments
# blocks_parser = argparse.ArgumentParser(
# prog="%s -@/--blocks" % parser.prog,
# allow_abbrev=False)
# blocks_parser.add_argument(
# 'blocks',
# nargs='*',
# type=lambda x: (
# 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.")
# blocks_parser.add_argument(
# '--off',
# type=lambda x: (
# slice(*(int(x, 0) if x.strip() else None
# for x in x.split(',', 1)))
# if ',' in x
# else int(x, 0)),
# help="Show a specific offset, may be a range.")
# blocks_parser.add_argument(
# '-n', '--size',
# type=lambda x: (
# slice(*(int(x, 0) if x.strip() else None
# for x in x.split(',', 1)))
# if ',' in x
# else int(x, 0)),
# help="Show this many bytes, may be a range.")
#
# parser.add_argument(
# '-@', '--blocks',
# type=lambda blocks: BmapSlice(**{k: v
# for k, v in vars(blocks_parser.parse_intermixed_args(
# shlex.split(blocks))).items()
# if v is not None}),
# help="Optional blocks to show, may be a range. Can also include "
# "--off and -n/--size flags to indicate a range inside the "
# "block, both which may also be ranges.")
parser.add_argument(
'-@', '--blocks',
type=lambda x: (